1 /************************************************************/
3 /* Module ID - vmesa.c */
5 /* Function - Provide operating system dependent process- */
6 /* ing for perl under VM/ESA. */
8 /* Parameters - See individual entry points. */
10 /* Called By - N/A - see individual entry points. */
12 /* Calling To - N/A - see individual entry points. */
14 /* Notes - (1) ....................................... */
16 /* (2) ....................................... */
18 /* Name - Neale Ferguson. */
20 /* Date - August, 1998. */
23 /* Associated - (1) Refer To ........................... */
25 /* (2) Refer To ........................... */
27 /************************************************************/
28 /************************************************************/
30 /* MODULE MAINTENANCE HISTORY */
31 /* -------------------------- */
33 static char REQ_REL_WHO [13] =
34 /*-------------- -------------------------------------*/
35 "9999_99 NAF "; /* Original module */
37 /*============ End of Module Maintenance History ===========*/
39 /************************************************************/
44 /************************************************************/
48 /*=============== END OF DEFINES ===========================*/
50 /************************************************************/
52 /* INCLUDE STATEMENTS */
53 /* ------------------ */
55 /************************************************************/
66 #pragma map(truncate, "@@TRUNC")
68 /*================== End of Include Statements =============*/
70 /************************************************************/
72 /* Global Variables */
73 /* ---------------- */
75 /************************************************************/
77 static int Perl_stdin_fd = STDIN_FILENO,
78 Perl_stdout_fd = STDOUT_FILENO;
80 static long dl_retcode = 0;
82 /*================== End of Global Variables ===============*/
84 /************************************************************/
86 /* FUNCTION PROTOTYPES */
87 /* ------------------- */
89 /************************************************************/
91 int do_aspawn(SV *, SV **, SV **);
92 int do_spawn(char *, int);
93 static int spawnit(char *);
94 static pid_t spawn_cmd(char *, int, int);
95 struct perl_thread * getTHR(void);
97 /*================== End of Prototypes =====================*/
99 /************************************************************/
101 /* D O _ A S P A W N */
102 /* ----------------- */
104 /************************************************************/
107 do_aspawn(SV* really, SV **mark, SV **sp)
111 struct inheritance inherit;
124 New(401,PL_Argv, sp - mark + 1, char*);
129 *a++ = SvPVx(*mark, n_a);
133 inherit.flags = SPAWN_SETGROUP;
134 inherit.pgroup = SPAWN_NEWPGROUP;
135 fdMap[STDIN_FILENO] = Perl_stdin_fd;
136 fdMap[STDOUT_FILENO] = Perl_stdout_fd;
137 fdMap[STDERR_FILENO] = STDERR_FILENO;
140 /*-----------------------------------------------------*/
141 /* Will execvp() use PATH? */
142 /*-----------------------------------------------------*/
143 if (*PL_Argv[0] != '/')
145 if (really && *(tmps = SvPV(really, n_a)))
146 pid = spawnp(tmps, nFd, fdMap, &inherit,
147 (const char **) PL_Argv,
148 (const char **) environ);
150 pid = spawnp(PL_Argv[0], nFd, fdMap, &inherit,
151 (const char **) PL_Argv,
152 (const char **) environ);
156 if (ckWARN(WARN_EXEC))
157 warner(WARN_EXEC,"Can't exec \"%s\": %s",
163 /*------------------------------------------------*/
164 /* If the file descriptors have been remapped then*/
165 /* we've been called following a my_popen request */
166 /* therefore we don't want to wait for spawnned */
167 /* program to complete. We need to set the fdpid */
168 /* value to the value of the spawnned process' pid*/
169 /*------------------------------------------------*/
171 if (Perl_stdin_fd != STDIN_FILENO)
174 if (Perl_stdout_fd != STDOUT_FILENO)
178 /*---------------------------------------------*/
179 /* Get the fd of the other end of the pipe, */
180 /* use this to reference the fdpid which will */
181 /* be used by my_pclose */
182 /*---------------------------------------------*/
184 MUTEX_LOCK(&PL_fdpid_mutex);
185 p_sv = av_fetch(PL_fdpid,fd,TRUE);
186 fd = (int) SvIVX(*p_sv);
188 *p_sv = &PL_sv_undef;
189 sv = *av_fetch(PL_fdpid,fd,TRUE);
190 MUTEX_UNLOCK(&PL_fdpid_mutex);
191 (void) SvUPGRADE(sv, SVt_IV);
196 wait4pid(pid, &status, 0);
203 /*===================== End of do_aspawn ===================*/
205 /************************************************************/
207 /* D O _ S P A W N */
208 /* --------------- */
210 /************************************************************/
213 do_spawn(char *cmd, int execf)
221 struct inheritance inherit;
224 while (*cmd && isSPACE(*cmd))
227 /*------------------------------------------------------*/
228 /* See if there are shell metacharacters in it */
229 /*------------------------------------------------------*/
231 if (*cmd == '.' && isSPACE(cmd[1]))
232 return (spawnit(cmd));
235 if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
236 return (spawnit(cmd));
239 /*------------------------------------------------*/
240 /* Catch VAR=val gizmo */
241 /*------------------------------------------------*/
242 for (s = cmd; *s && isALPHA(*s); s++);
245 for (s = cmd; *s; s++)
249 strchr("$&*(){}[]'\";\\|?<>~`\n",*s))
251 if (*s == '\n' && !s[1])
256 return(spawnit(cmd));
263 New(402,PL_Argv, (s - cmd) / 2 + 2, char*);
264 PL_Cmd = savepvn(cmd, s-cmd);
266 for (s = PL_Cmd; *s;)
268 while (*s && isSPACE(*s)) s++;
271 while (*s && !isSPACE(*s)) s++;
276 fdMap[STDIN_FILENO] = Perl_stdin_fd;
277 fdMap[STDOUT_FILENO] = Perl_stdout_fd;
278 fdMap[STDERR_FILENO] = STDERR_FILENO;
283 pid = spawnp(PL_Argv[0], nFd, fdMap, &inherit,
284 (const char **) PL_Argv,
285 (const char **) environ);
289 if (ckWARN(WARN_EXEC))
290 warner(WARN_EXEC,"Can't exec \"%s\": %s",
295 wait4pid(pid, &status, 0);
301 /*===================== End of do_spawn ====================*/
303 /************************************************************/
305 /* Name - spawnit. */
307 /* Function - Spawn command and return status. */
309 /* On Entry - cmd - command to be spawned. */
311 /* On Exit - status returned. */
313 /************************************************************/
321 pid = spawn_cmd(cmd, STDIN_FILENO, STDOUT_FILENO);
325 wait4pid(pid, &status, 0);
330 /*===================== End of spawnit =====================*/
332 /************************************************************/
334 /* Name - spawn_cmd. */
336 /* Function - Spawn command and return pid. */
338 /* On Entry - cmd - command to be spawned. */
340 /* On Exit - pid returned. */
342 /************************************************************/
345 spawn_cmd(char *cmd, int inFd, int outFd)
347 struct inheritance inherit;
349 const char *argV[4] = {"/bin/sh","-c",NULL,NULL};
354 fdMap[STDIN_FILENO] = inFd;
355 fdMap[STDOUT_FILENO] = outFd;
356 fdMap[STDERR_FILENO] = STDERR_FILENO;
358 inherit.flags = SPAWN_SETGROUP;
359 inherit.pgroup = SPAWN_NEWPGROUP;
360 pid = spawn(argV[0], nFd, fdMap, &inherit,
361 argV, (const char **) environ);
365 /*===================== End of spawnit =====================*/
367 /************************************************************/
369 /* Name - my_popen. */
371 /* Function - Use popen to execute a command return a */
372 /* file descriptor. */
374 /* On Entry - cmd - command to be executed. */
376 /* On Exit - FILE * returned. */
378 /************************************************************/
382 my_popen(char *cmd, char *mode)
391 if (PerlProc_pipe(pFd) >= 0)
393 this = (*mode == 'w');
395 /*-------------------------------------------------*/
396 /* If this is a read mode pipe */
397 /* - map the write end of the pipe to STDOUT */
398 /* - return the *FILE for the read end of the pipe */
399 /*-------------------------------------------------*/
401 Perl_stdout_fd = pFd[that];
402 /*-------------------------------------------------*/
404 /* - map the read end of the pipe to STDIN */
405 /* - return the *FILE for the write end of the pipe*/
406 /*-------------------------------------------------*/
408 Perl_stdin_fd = pFd[that];
411 PERL_FLUSHALL_FOR_CHILD;
412 pid = spawn_cmd(cmd, Perl_stdin_fd, Perl_stdout_fd);
415 MUTEX_LOCK(&PL_fdpid_mutex);
416 sv = *av_fetch(PL_fdpid,pFd[this],TRUE);
417 MUTEX_UNLOCK(&PL_fdpid_mutex);
418 (void) SvUPGRADE(sv, SVt_IV);
420 fd = PerlIO_fdopen(pFd[this], mode);
428 MUTEX_LOCK(&PL_fdpid_mutex);
429 sv = *av_fetch(PL_fdpid,pFd[that],TRUE);
430 MUTEX_UNLOCK(&PL_fdpid_mutex);
431 (void) SvUPGRADE(sv, SVt_IV);
432 SvIVX(sv) = pFd[this];
433 fd = PerlIO_fdopen(pFd[this], mode);
441 /*===================== End of my_popen ====================*/
443 /************************************************************/
445 /* Name - my_pclose. */
447 /* Function - Use pclose to terminate a piped command */
450 /* On Entry - fd - FILE pointer. */
452 /* On Exit - Status returned. */
454 /************************************************************/
467 MUTEX_LOCK(&PL_fdpid_mutex);
468 sv = av_fetch(PL_fdpid,PerlIO_fileno(fp),TRUE);
469 MUTEX_UNLOCK(&PL_fdpid_mutex);
470 pid = (int) SvIVX(*sv);
473 rc = PerlIO_close(fp);
477 wRc = waitpid(pid, &status, 0);
478 } while ((wRc == -1) && (errno == EINTR));
479 Perl_stdin_fd = STDIN_FILENO;
480 Perl_stdout_fd = STDOUT_FILENO;
483 SETERRNO(errno, garbage);
488 /************************************************************/
492 /* Function - Load a DLL. */
496 /************************************************************/
499 dlopen(const char *path)
503 fprintf(stderr,"Loading %s\n",path);
504 handle = dllload(path);
506 fprintf(stderr,"Handle %08X %s\n",handle,strerror(errno));
507 return ((void *) handle);
510 /*===================== End of dlopen ======================*/
512 /************************************************************/
516 /* Function - Locate a DLL symbol. */
520 /************************************************************/
523 dlsym(void *handle, const char *symbol)
527 fprintf(stderr,"Finding %s\n",symbol);
528 symLoc = dllqueryvar((dllhandle *) handle, (char *) symbol);
530 symLoc = (void *) dllqueryfn((dllhandle *) handle,
536 /*===================== End of dlsym =======================*/
538 /************************************************************/
540 /* Name - dlerror. */
542 /* Function - Return the last errno pertaining to a DLL */
547 /************************************************************/
554 dlEmsg = strerror(dl_retcode);
559 /*===================== End of dlerror =====================*/
561 /************************************************************/
563 /* Name - TRUNCATE. */
565 /* Function - Truncate a file identified by 'path' to */
566 /* a given length. */
568 /* On Entry - path - Path of file to be truncated. */
569 /* length - length of truncated file. */
571 /* On Exit - retC - return code. */
573 /************************************************************/
576 truncate(const unsigned char *path, off_t length)
581 fd = open((const char *) path, O_RDWR);
584 retC = ftruncate(fd, length);
592 /*===================== End of trunc =======================*/