00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2.1 of the GNU Lesser General Public License 00007 as published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this program; if not, write the Free Software 00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 00023 USA. 00024 00025 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00026 Mountain View, CA 94043, or: 00027 00028 http://www.sgi.com 00029 00030 For further information regarding this notice, see: 00031 00032 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00033 00034 */ 00035 00036 00037 #pragma ident "@(#) libf/pxf/pxfexecv.c 92.1 06/29/99 11:36:06" 00038 00039 #include <errno.h> 00040 #include <liberrno.h> 00041 #include <fortran.h> 00042 #include <string.h> 00043 #include <malloc.h> 00044 #include <unistd.h> 00045 00046 extern char *_fc_acopy(_fcd f); 00047 00048 /* 00049 * PXFEXECV -- execute a new process image file 00050 * (section 3.1.2 of Posix 1003.9-1992) 00051 * 00052 * Synopsis: 00053 * SUBROUTINE PXFEXECV (PATH,LENPATH,ARGV,LENARGV,IARGC,IERROR) 00054 * INTEGER IARGC, LENPATH,LENARGV(0:IARGC-1),IERROR 00055 * CHARACTER*(*) PATH,ARGV(0:IARGC-1) 00056 * 00057 * Function description: 00058 * The routine PXFEXECV uses the execv(2) system call to replace the 00059 * current process image with a new process image. 00060 * 00061 * Description of arguments: 00062 * PATH is an input character variable or array element containing 00063 * the pathname of the new process image file. 00064 * 00065 * LENPATH is an input integer variable for the length of PATH. If 00066 * LENPATH is zero, trailing blanks are removed. 00067 * 00068 * ARGV is an input array of character strings. ARGV contains the 00069 * arguments to be passed to the new process image. 00070 * 00071 * LENARGV is an input array of intergers. Each element in LENARGV 00072 * contains the length of the corresponding character 00073 * string in ARGV. If an element in LENARGV is zero, the 00074 * corresponding element in ARGV will have all trailing 00075 * blanks stripped. 00076 * 00077 * IARGC is an input integer variable. IARGC contains the number of 00078 * arguments to pass to the new process image. 00079 * 00080 * IERROR is an output integer variable that will contain 00081 * the status: 00082 * 00083 * zero - PXFEXECV was unsuccessful. 00084 * 00085 * nonzero - PXFEXECV was not successful. 00086 * 00087 * PXFEXECV may return any of the following error 00088 * values: 00089 * 00090 * EACCES If the new process file is not a regular file, 00091 * the new process image file mode denies execution 00092 * permission, or search permission is denied for 00093 * a directory listed in the new process image 00094 * file's path prefix. 00095 * 00096 * ENOENT If one or more components of the new process 00097 * image file's path name do not exist. 00098 * 00099 * ENOEXEC If the new process image file has the 00100 * appropriate access permission but an invalid 00101 * magic number in its header. 00102 * 00103 * ENOMEM If the memory needed to create structures used 00104 * by PXFEXECV could not be allocated. 00105 * 00106 * EINVAL If LENPATH < 0 or LENPATH > LEN(PATH) or any 00107 * element of LENARGV is less than zero or greater 00108 * than the length of the corresponding element in 00109 * ARGV. 00110 * 00111 * UNICOS 9 only errors: 00112 * 00113 * E2BIG If the number of bytes in ARGV is greater than 00114 * the system-imposed limit of ARG_MAX found in 00115 * <limits.h>. 00116 * 00117 * EDMOFF If the process image file is offline, and 00118 * the data migration facility is not configured 00119 * in the system. 00120 * 00121 * EFAULT If the new process image file is not as long as 00122 * indicated by the size values in it header. 00123 * 00124 * ENOMEM If the new process requires more memory than is 00125 * allowed by the system-imposed maximum MAXMEM. 00126 * 00127 * EOFFLIN If the process image file is offline, and 00128 * automatic file retrieval is disabled. 00129 * 00130 * EOFLNDD If the file is offline, and the data management 00131 * daemon is not currently executing. 00132 * 00133 * EOFLNNR If the file is offline, and it is currently 00134 * unretrievable. 00135 * 00136 * IRIX 6.2 only errors: 00137 * 00138 * E2BIG If the number of bytes in the new process's argument 00139 * list is greater than the system-imposed limit 00140 * {ARG_MAX} [see sysconf(2), intro(2), and limits.h]. 00141 * The argument list limit is the sum of the size of 00142 * the argument list plus the size of the environment's 00143 * exported shell variables. 00144 * 00145 * E2BIG If the number of bytes in the first line of an 00146 * interpreter file is greater than 256 bytes. 00147 * 00148 * EAGAIN If there is not enough memory. 00149 * 00150 * ELIBACC If the required shared library does not have 00151 * execute permission. 00152 * 00153 * ELIBEXEC If PATH points to a shared library. 00154 * 00155 * ELIBMAX If the required number of shared libraries 00156 * exceeds the system imposed maximum {SHLIB_MAX) 00157 * [see intro(2)]. 00158 * 00159 * ELOOP If too many symbolic links were encountered in 00160 * translating PATH. 00161 * 00162 * ENAMETOOLONG If the length of PATH exceeds PATH_MAX found 00163 * in <limits.h>, or the length of a path 00164 * component exceeds NAME_MAX found in <limits.h> 00165 * while POSIX_NO_TRUNC is in effect. 00166 * 00167 * ENOEXEC If the executable process image file has badly 00168 * formed header information or the requested 00169 * virtual addresses are not available. 00170 * 00171 * ENOMEM If the new process image requires more virtual 00172 * space than is allowed either by the 00173 * system-imposed maximum or the process imposed 00174 * maximum PROCSIZE_MAX [see getrlimit(2) and 00175 * intro(2)]. 00176 * 00177 * EPERM If a non-superuser tries to execute a setuid 00178 * file which belongs to some other user and the 00179 * file system in which then file resides has 00180 * been mounted with the nosuid option [see 00181 * fstab(4)], or if a non-superuser attempts to 00182 * execute a setuid or setgid shell script with 00183 * a uid or gid which is different than the user's 00184 * effective uid/gid, and the configured value for 00185 * nosuidshells is non-zero (the default) [see 00186 * intro(2) and lboot(1M)]. 00187 * 00188 */ 00189 00190 #ifdef _UNICOS 00191 void 00192 PXFEXECV( 00193 #else 00194 void 00195 _PXFEXECV( 00196 #endif 00197 _fcd PATH, 00198 _f_int *LENPATH, 00199 _fcd ARGV, /* packed array of fortran strings */ 00200 _f_int *LENARGV, 00201 _f_int *IARGC, 00202 _f_int *IERROR 00203 ) 00204 { 00205 char **arg, /* vector of argument strings for execv */ 00206 *cpath, /* file path for executable */ 00207 *cstring_ARGV; /* the C-style string for the ARGV fortran character 00208 * descriptor */ 00209 int clenpath, /* equal to *LENPATH, the user defined length of PATH */ 00210 i, /* loop counter */ 00211 position, /* current position in the string cstring_ARGV */ 00212 ciargc, /* equal to *IARGC, the number of arguments for execv */ 00213 cstring_lenargv, /* the length of the FCD ARGV. Note: This is the length of 00214 an individual FCD in the array ARGV. */ 00215 len; /* length of string to copy from cstring_ARGV to a string 00216 in the arg vector of strings. */ 00217 00218 clenpath = *LENPATH; 00219 cstring_lenargv = _fcdlen(ARGV); 00220 ciargc = *IARGC; 00221 00222 /* check for valid path length passed in by user */ 00223 if (clenpath < 0 || clenpath > _fcdlen(PATH)) { 00224 *IERROR = EINVAL; 00225 return; 00226 } else { 00227 if (clenpath == 0) { 00228 /* 00229 * If length is zero, user wants trailing blanks stripped. 00230 * Otherwise, malloc memory and copy the string adding a 00231 * NULL terminator. 00232 */ 00233 cpath = _fc_acopy(PATH); 00234 00235 } else { 00236 00237 cpath = (char *)malloc(clenpath + 1); 00238 if (cpath != NULL) { 00239 memcpy(cpath, _fcdtocp(PATH), clenpath); 00240 cpath[clenpath] = '\0'; 00241 } else { 00242 *IERROR = ENOMEM; 00243 return; 00244 } 00245 00246 } 00247 } 00248 00249 /* attempt to copy all argument strings from ARGV */ 00250 00251 /* check the LENARGV array for proper values before copying ARGV strings */ 00252 i = 0; 00253 while (i < ciargc) { 00254 len = LENARGV[i]; 00255 if (len < 0 || len > cstring_lenargv) { 00256 *IERROR = EINVAL; 00257 free(cpath); 00258 return; 00259 } 00260 i++; 00261 } 00262 00263 arg = (char **)calloc(ciargc + 1,sizeof(char *)); 00264 if (arg == NULL) { 00265 *IERROR = ENOMEM; 00266 free(cpath); 00267 return; 00268 } 00269 00270 cstring_ARGV = _fcdtocp(ARGV); 00271 00272 /* malloc the memory for all the strings copy each Fortran string 00273 * into a C-style string */ 00274 for (i = 0, position = 0; i < ciargc; position += cstring_lenargv, i++) { 00275 len = LENARGV[i]; 00276 /* strip off trailing blanks */ 00277 if (len == 0) { 00278 len = cstring_lenargv - 1; 00279 while ((len > 0) && 00280 cstring_ARGV[(i * cstring_lenargv) + len] == ' ') { 00281 len--; 00282 } 00283 len++; 00284 } 00285 if ((arg[i] = (char *)malloc((len+1)*sizeof(char))) == NULL) { 00286 for (; i >= 0; i--) { 00287 free(arg[i]); 00288 } 00289 free(arg); 00290 free(cpath); 00291 *IERROR = ENOMEM; 00292 return; 00293 } 00294 00295 strncpy(arg[i], &cstring_ARGV[position], len); 00296 arg[i][len] = '\0'; 00297 } 00298 if (execv(cpath, arg) == -1) { 00299 for (i--; i >= 0; i--) { 00300 free(arg[i]); 00301 } 00302 free(arg); 00303 free(cpath); 00304 *IERROR = errno; 00305 return; 00306 } 00307 00308 *IERROR = 0; 00309 } 00310 00311 #ifndef _UNICOS 00312 void 00313 pxfexecv_( 00314 char *PATH, 00315 _f_int *LENPATH, 00316 char *ARGV, 00317 _f_int *LENARGV, 00318 _f_int *IARGC, 00319 _f_int *IERROR, 00320 _f_int pathlen, 00321 _f_int argvlen 00322 ) 00323 { 00324 _PXFEXECV( _cptofcd(PATH,pathlen), LENPATH, _cptofcd(ARGV,argvlen), 00325 LENARGV, IARGC, IERROR); 00326 } 00327 #endif 00328 00329 00330 00331 00332
1.5.6