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;
125 New(401,PL_Argv, sp - mark + 1, char*);
130 *a++ = SvPVx(*mark, n_a);
134 inherit.flags = SPAWN_SETGROUP;
135 inherit.pgroup = SPAWN_NEWPGROUP;
136 fdMap[STDIN_FILENO] = Perl_stdin_fd;
137 fdMap[STDOUT_FILENO] = Perl_stdout_fd;
138 fdMap[STDERR_FILENO] = STDERR_FILENO;
141 /*-----------------------------------------------------*/
142 /* Will execvp() use PATH? */
143 /*-----------------------------------------------------*/
144 if (*PL_Argv[0] != '/')
146 if (really && *(tmps = SvPV(really, n_a)))
147 pid = spawnp(tmps, nFd, fdMap, &inherit,
148 (const char **) PL_Argv,
149 (const char **) environ);
151 pid = spawnp(PL_Argv[0], nFd, fdMap, &inherit,
152 (const char **) PL_Argv,
153 (const char **) environ);
157 if (ckWARN(WARN_EXEC))
158 warner(WARN_EXEC,"Can't exec \"%s\": %s",
164 /*------------------------------------------------*/
165 /* If the file descriptors have been remapped then*/
166 /* we've been called following a my_popen request */
167 /* therefore we don't want to wait for spawnned */
168 /* program to complete. We need to set the fdpid */
169 /* value to the value of the spawnned process' pid*/
170 /*------------------------------------------------*/
172 if (Perl_stdin_fd != STDIN_FILENO)
175 if (Perl_stdout_fd != STDOUT_FILENO)
179 /*---------------------------------------------*/
180 /* Get the fd of the other end of the pipe, */
181 /* use this to reference the fdpid which will */
182 /* be used by my_pclose */
183 /*---------------------------------------------*/
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 (void) SvUPGRADE(sv, SVt_IV);
195 wait4pid(pid, &status, 0);
202 /*===================== End of do_aspawn ===================*/
204 /************************************************************/
206 /* D O _ S P A W N */
207 /* --------------- */
209 /************************************************************/
212 do_spawn(char *cmd, int execf)
220 struct inheritance inherit;
223 while (*cmd && isSPACE(*cmd))
226 /*------------------------------------------------------*/
227 /* See if there are shell metacharacters in it */
228 /*------------------------------------------------------*/
230 if (*cmd == '.' && isSPACE(cmd[1]))
231 return (spawnit(cmd));
234 if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
235 return (spawnit(cmd));
238 /*------------------------------------------------*/
239 /* Catch VAR=val gizmo */
240 /*------------------------------------------------*/
241 for (s = cmd; *s && isALPHA(*s); s++);
244 for (s = cmd; *s; s++)
248 strchr("$&*(){}[]'\";\\|?<>~`\n",*s))
250 if (*s == '\n' && !s[1])
255 return(spawnit(cmd));
262 New(402,PL_Argv, (s - cmd) / 2 + 2, char*);
263 PL_Cmd = savepvn(cmd, s-cmd);
265 for (s = PL_Cmd; *s;)
267 while (*s && isSPACE(*s)) s++;
270 while (*s && !isSPACE(*s)) s++;
275 fdMap[STDIN_FILENO] = Perl_stdin_fd;
276 fdMap[STDOUT_FILENO] = Perl_stdout_fd;
277 fdMap[STDERR_FILENO] = STDERR_FILENO;
282 pid = spawnp(PL_Argv[0], nFd, fdMap, &inherit,
283 (const char **) PL_Argv,
284 (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 pid = spawn_cmd(cmd, Perl_stdin_fd, Perl_stdout_fd);
414 sv = *av_fetch(PL_fdpid,pFd[this],TRUE);
415 (void) SvUPGRADE(sv, SVt_IV);
417 fd = PerlIO_fdopen(pFd[this], mode);
425 sv = *av_fetch(PL_fdpid,pFd[that],TRUE);
426 (void) SvUPGRADE(sv, SVt_IV);
427 SvIVX(sv) = pFd[this];
428 fd = PerlIO_fdopen(pFd[this], mode);
436 /*===================== End of my_popen ====================*/
438 /************************************************************/
440 /* Name - my_pclose. */
442 /* Function - Use pclose to terminate a piped command */
445 /* On Entry - fd - FILE pointer. */
447 /* On Exit - Status returned. */
449 /************************************************************/
462 sv = av_fetch(PL_fdpid,PerlIO_fileno(fp),TRUE);
463 pid = (int) SvIVX(*sv);
466 rc = PerlIO_close(fp);
470 wRc = waitpid(pid, &status, 0);
471 } while ((wRc == -1) && (errno == EINTR));
472 Perl_stdin_fd = STDIN_FILENO;
473 Perl_stdout_fd = STDOUT_FILENO;
476 SETERRNO(errno, garbage);
481 /************************************************************/
485 /* Function - Load a DLL. */
489 /************************************************************/
492 dlopen(const char *path)
496 fprintf(stderr,"Loading %s\n",path);
497 handle = dllload(path);
499 fprintf(stderr,"Handle %08X %s\n",handle,strerror(errno));
500 return ((void *) handle);
503 /*===================== End of dlopen ======================*/
505 /************************************************************/
509 /* Function - Locate a DLL symbol. */
513 /************************************************************/
516 dlsym(void *handle, const char *symbol)
520 fprintf(stderr,"Finding %s\n",symbol);
521 symLoc = dllqueryvar((dllhandle *) handle, (char *) symbol);
523 symLoc = (void *) dllqueryfn((dllhandle *) handle,
529 /*===================== End of dlsym =======================*/
531 /************************************************************/
533 /* Name - dlerror. */
535 /* Function - Return the last errno pertaining to a DLL */
540 /************************************************************/
547 dlEmsg = strerror(dl_retcode);
552 /*===================== End of dlerror =====================*/
554 /************************************************************/
556 /* Name - TRUNCATE. */
558 /* Function - Truncate a file identified by 'path' to */
559 /* a given length. */
561 /* On Entry - path - Path of file to be truncated. */
562 /* length - length of truncated file. */
564 /* On Exit - retC - return code. */
566 /************************************************************/
569 truncate(const unsigned char *path, off_t length)
574 fd = open((const char *) path, O_RDWR);
577 retC = ftruncate(fd, length);
585 /*===================== End of trunc =======================*/