219
212
childEnvp = newEnvp;
224
** Since vfork/exec is implemented VERY differently on OpenVMS, we have to
225
** handle the setting up of the standard streams very differently. And since
226
** none of this code can ever execute in the context of the child, we have
227
** to perform the chdir in the parent so the child is born into the correct
228
** directory (and then switch the parent back again).
231
int decc$set_child_standard_streams(int,int,int);
232
int n, fd_stdin=0, fd_stdout=1, fd_stderr=2;
234
/* Set up any standard streams we are given, assuming defaults */
237
fd_stdin = attr->stdinFd->secret->md.osfd;
239
fd_stdout = attr->stdoutFd->secret->md.osfd;
241
fd_stderr = attr->stderrFd->secret->md.osfd;
245
** Put a lock around anything that isn't going to be thread-safe.
247
PR_Lock(_pr_vms_fork_lock);
250
** Prepare the child's streams. We always do this in case a previous fork
251
** has left the stream assignments in some non-standard way.
253
n = decc$set_child_standard_streams(fd_stdin,fd_stdout,fd_stderr);
255
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, errno);
260
PR_Unlock(_pr_vms_fork_lock);
264
/* Switch directory if we have to */
266
if (attr->currentDirectory) {
267
if ( (getcwd(VMScurdir,sizeof(VMScurdir)) == NULL) ||
268
(chdir(attr->currentDirectory) < 0) ) {
269
PR_SetError(PR_DIRECTORY_OPEN_ERROR, errno);
274
PR_Unlock(_pr_vms_fork_lock);
283
216
process->md.pid = (*pr_wp.forkptr)();
217
#elif defined(NTO) || defined(SYMBIAN)
286
219
* fork() & exec() does not work in a multithreaded process.
287
220
* Use spawn() instead.
312
245
PR_ASSERT(attr->currentDirectory == NULL); /* not implemented */
249
/* In Symbian OS, we use posix_spawn instead of fork() and exec() */
250
posix_spawn(&(process->md.pid), path, NULL, NULL, argv, childEnvp);
315
252
process->md.pid = spawn(path, 3, fd_map, NULL, argv, childEnvp);
317
255
if (fd_map[0] != 0)
318
256
close(fd_map[0]);
339
277
* the parent process's standard I/O data structures.
344
/* OpenVMS has already handled all this above */
280
#if !defined(NTO) && !defined(SYMBIAN)
347
282
/* the osfd's to redirect stdin, stdout, and stderr to */
348
283
int in_osfd = -1, out_osfd = -1, err_osfd = -1;
405
339
(void)execv(path, argv);
407
341
/* Whoops! It returned. That's a bad sign. */
410
** On OpenVMS we are still in the context of the parent, and so we
411
** can (and should!) perform normal error handling.
413
PR_SetError(PR_UNKNOWN_ERROR, errno);
418
if (VMScurdir[0] != '\0')
420
PR_Unlock(_pr_vms_fork_lock);
425
343
#endif /* !NTO */
429
347
PR_DELETE(newEnvp);
432
/* If we switched directories, then remember to switch back */
433
if (VMScurdir[0] != '\0') {
434
chdir(VMScurdir); /* can't do much if it fails */
436
PR_Unlock(_pr_vms_fork_lock);
439
350
#if defined(_PR_NATIVE_THREADS)
440
351
PR_Lock(pr_wp.ml);
842
753
pr_wp.ml = PR_NewLock();
843
754
PR_ASSERT(NULL != pr_wp.ml);
846
_pr_vms_fork_lock = PR_NewLock();
847
PR_ASSERT(NULL != _pr_vms_fork_lock);
850
756
#if defined(_PR_NATIVE_THREADS)
851
757
pr_wp.numProcs = 0;
852
758
pr_wp.cv = PR_NewCondVar(pr_wp.ml);
980
886
PRErrorCode prerror;
890
/* In Symbian OS, we can not kill other process with Open C */
891
PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, oserror);
983
894
if (kill(process->md.pid, SIGKILL) == 0) {
984
895
return PR_SUCCESS;