scripts/wrapper.c
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Fri Dec 31 00:16:19 2010 +0100 (2010-12-31)
changeset 2251 1bd55a223113
parent 1964 f02cfced8f55
permissions -rw-r--r--
samples: update i686-nptl-linux-gnu

Enable Java and Fortran frontends.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
yann@1492
     1
#include <limits.h>
yann@1492
     2
#include <stdlib.h>
yann@1492
     3
#include <stdio.h>
yann@1492
     4
#include <string.h>
yann@1492
     5
#include <sys/types.h>
yann@1492
     6
#include <sys/stat.h>
yann@1492
     7
#include <unistd.h>
yann@1492
     8
#include <errno.h>
yann@1492
     9
titus@1964
    10
#ifdef	__APPLE__
titus@1964
    11
#define LDLP "DYLD_LIBRARY_PATH"
titus@1964
    12
#else
titus@1964
    13
#define LDLP "LD_LIBRARY_PATH"
titus@1964
    14
#endif
yann@1492
    15
yann@1492
    16
/* Needed for execve */
yann@1492
    17
extern char **environ;
yann@1492
    18
yann@1492
    19
int main( int argc,
yann@1492
    20
          char** argv )
yann@1492
    21
{
yann@1492
    22
  char *fullname;   /* 'fullname' is used to store the absolute path to the
yann@1492
    23
                       tool being executed; it serves as a base to compute
yann@1492
    24
                       the realname of that tool, and the directory holding
yann@1492
    25
                       our runtime libraries */
yann@1492
    26
  char *realname;   /* 'realname' is the real name of the tool, that is what
yann@1492
    27
                       the wrapper is currently impersonating */
yann@1492
    28
  char *basedir;    /* 'libdir' contains our runtime libraries */
yann@1492
    29
yann@1492
    30
  char *lastslash;  /* Temporary variables now */
yann@1492
    31
  char *ldlibpath;
yann@1492
    32
  size_t len;
yann@1492
    33
  int execve_ret;
yann@1492
    34
yann@1504
    35
  /* Avoid the warning-treated-as-error: "error: unused parameter 'argc'" */
yann@1504
    36
  len = argc;
yann@1504
    37
yann@1492
    38
  /* In case we have a relative or absolute pathname (ie. contains a slash),
yann@1492
    39
   * then realpath wll work. But if the tool was found in the PATH, realpath
yann@1492
    40
   * won't work, and we'll have to search ourselves.
yann@1492
    41
   * This if{}else{} block allocates memory for fullname. */
yann@1492
    42
  if( strchr( argv[0], '/' ) ) {
yann@1492
    43
    fullname = (char*) malloc( PATH_MAX * sizeof(char) );
yann@1492
    44
    if( ! realpath( argv[0], fullname ) ) {
yann@1492
    45
      perror( "tool wrapper" );
yann@1492
    46
      exit( 1 );
yann@1492
    47
    }
yann@1492
    48
  } else {
yann@1492
    49
    char *path;
yann@1492
    50
    char *mypath;
yann@1492
    51
    char *colon;
yann@1492
    52
    char *testname;
yann@1492
    53
    struct stat st;
yann@1492
    54
yann@1492
    55
    fullname = NULL;
yann@1492
    56
    colon = mypath = path = strdup( getenv( "PATH" ) );
yann@1492
    57
    while( colon ) {
yann@1492
    58
      colon = strchr( mypath, ':' );
yann@1492
    59
      if( colon ) {
yann@1492
    60
        *colon = '\0';
yann@1492
    61
      }
yann@1492
    62
      testname = strdup( mypath );
yann@1492
    63
      testname = (char*) realloc( testname,   strlen( testname )
yann@1492
    64
                                            + strlen( argv[0] )
yann@1492
    65
                                            + 2 * sizeof(char) );
yann@1492
    66
      memset( testname + strlen( testname ),
yann@1492
    67
              0,
yann@1492
    68
              strlen( argv[0] ) + 2 * sizeof(char) );
yann@1492
    69
      strcat( testname, "/" );
yann@1492
    70
      strcat( testname, argv[0] );
yann@1492
    71
      if( stat( testname, &st ) == 0 ) {
yann@1492
    72
        /* OK, exists. Is it a regular file, or a
yann@1492
    73
         * symlink, which the current user may execute? */
yann@1992
    74
        if( S_ISREG( st.st_mode ) && ! access( testname, X_OK | R_OK ) ) {
yann@1492
    75
          fullname = strdup( testname );
yann@1492
    76
          break;
yann@1492
    77
        }
yann@1492
    78
      }
yann@1492
    79
      free( testname );
yann@1492
    80
      mypath = colon + 1;
yann@1492
    81
    }
yann@1492
    82
    free( path );
yann@1492
    83
    if( ! fullname ) {
yann@1492
    84
      fprintf( stderr, "tool wrapper: %s: command not found\n", argv[0] );
yann@1492
    85
      exit( 1 );
yann@1492
    86
    }
yann@1492
    87
  }
yann@1492
    88
yann@1492
    89
  /* Duplicate my own name to add the 'dot' to tool name */
yann@1492
    90
  realname = strdup( fullname );
yann@1492
    91
  realname = (char*) realloc( realname, strlen( realname) + 2 * sizeof(char) );
yann@1492
    92
  realname[ strlen( realname ) + 1 ] = '\0';
yann@1492
    93
yann@1492
    94
  /* Add the dot after the last '/' */
yann@1492
    95
  lastslash = strrchr( realname, '/' );
yann@1492
    96
  memmove( lastslash + 1, lastslash, strlen( lastslash ) );
yann@1492
    97
  *( lastslash + 1 ) = '.';
yann@1492
    98
yann@1492
    99
  /* Compute the basedir of the tool */
yann@1492
   100
  basedir = strdup( fullname );
yann@1492
   101
  lastslash = strrchr( basedir, '/' );
yann@1492
   102
  *lastslash = '\0';
yann@1492
   103
  lastslash = strrchr( basedir, '/' );
yann@1492
   104
  *lastslash = '\0';
yann@1492
   105
yann@1492
   106
  /* Append '/lib' */
yann@1492
   107
  len = strlen( basedir );
yann@1492
   108
  basedir = (char*) realloc( basedir, len + 5 );
yann@1492
   109
  *( basedir + len ) = '\0';
yann@1492
   110
  strcat( basedir, "/lib" );
yann@1492
   111
yann@1492
   112
  /* Now add the directory with our runtime libraries to the
yann@1492
   113
     front of the library search path, LD_LIBRARY_PATH */
titus@1964
   114
  ldlibpath = getenv(LDLP);
yann@1492
   115
  if( ldlibpath ) {
yann@1492
   116
    basedir = (char*) realloc( basedir,   strlen( basedir )
yann@1492
   117
                                        + strlen( ldlibpath )
yann@1492
   118
                                        + 2 * sizeof(char) );
yann@1492
   119
    strcat( basedir, ":" );
yann@1492
   120
    strcat( basedir, ldlibpath );
yann@1492
   121
  }
yann@1492
   122
titus@1964
   123
  if( setenv( LDLP, basedir, 1 ) ) {
yann@1492
   124
    errno = ENOMEM;
yann@1492
   125
    perror( "tool wrapper" );
yann@1492
   126
    exit( 1 );
yann@1492
   127
  }
yann@1492
   128
yann@1492
   129
  /* Execute the real tool, now */
yann@1492
   130
  execve_ret = execve( realname, argv, environ );
yann@1492
   131
yann@1492
   132
  /* In case something went wrong above, print a
yann@1492
   133
     diagnostic message, and exit with error code 1 */
yann@1492
   134
  perror( "tool wrapper" );
yann@1492
   135
  return 1;
yann@1492
   136
}