/*===========================================================================* * * * sflproco.imp - * * * * Copyright (c) 1991-2003 iMatix Corporation * * * * ------------------ GPL Licensed Source Code ------------------ * * iMatix makes this software available under the GNU General * * Public License (GPL) license for open source projects. For * * details of the GPL license please see www.gnu.org or read the * * file license.gpl provided in this package. * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public * * License along with this program in the file 'license.gpl'; if * * not, write to the Free Software Foundation, Inc., 59 Temple * * Place - Suite 330, Boston, MA 02111-1307, USA. * * * * You can also license this software under iMatix's General Terms * * of Business (GTB) for commercial projects. If you have not * * explicitly licensed this software under the iMatix GTB you may * * only use it under the terms of the GNU General Public License. * * * * For more information, send an email to info@imatix.com. * * -------------------------------------------------------------- * *===========================================================================*/ /* OS/2 implementation of the SFL process_create_full() function */ /* This function receives input in the form of a pointer to a PROCESS_DATA */ /* structure called procinfo. See sflproc.c for details. */ # if (!defined (__EMX__)) # error This function requires the EMX runtime # endif ARGLIST *arglist; /* Argument list */ int process = 0, /* Process number */ old_stdin = NULL_HANDLE, /* Dup'd handle for old stdin */ old_stdout = NULL_HANDLE, /* Dup'd handle for old stdout */ old_stderr = NULL_HANDLE; /* Dup'd handle for old stderr */ Bool free_envv = FALSE; /* True if we should free envv */ const char *path, /* Path to search */ *shell, /* Shell to use */ **searchext, /* Extensions to search */ *interpreter; /* Name of script interpreter */ char *full_filename, /* Full filename to run */ **argv, /* Arguments for program */ **envv, /* Environment for program */ *curdir = NULL; /* Current working directory */ /* First, check that minimum arguments needed to do something are set */ ASSERT (procinfo); if (!procinfo) return (NULL_PROCESS); ASSERT (procinfo-> filename); if (!procinfo-> filename) { procinfo-> error = EINVAL; return (NULL_PROCESS); } /* Initialise return information */ procinfo-> pid = NULL_PROCESS; procinfo-> error = 0; procinfo-> returncode = -1; /* For comparison... Unix version splits into parent & child here... */ # include "sflprocx.imp" /* Get implementation core */ /* If requested, change to a different root directory, and/or work dir */ if (procinfo-> error == 0 && (procinfo-> rootdir || procinfo-> workdir)) { int rc = 0; curdir = _getcwd2 (NULL, 256); if (curdir == NULL) procinfo-> error = errno? errno: EACCES; else { if (procinfo-> rootdir) rc = _chdir2 (procinfo-> rootdir); if (procinfo-> workdir && rc == 0) rc = chdir (procinfo-> workdir); if (rc == -1) { procinfo-> error = errno? errno: EACCES; _chdir2 (curdir); /* Try to restore existing dir */ } } } /* Now spawn the process */ if (procinfo-> error == 0) { int spawn_mode; /* Build final argv[] from arglist */ argv = arglist_to_table (arglist); if (argv) { /* Spawn the new program, and pick-up its process ID */ if (procinfo-> createdaemon) spawn_mode = P_DETACH; else spawn_mode = P_NOWAIT; { char **ptr = argv; fprintf(stderr, "About to run: (%s) ", full_filename); for (ptr = argv; *ptr; ptr++) fprintf(stderr, "[%s] ", *ptr); fprintf(stderr, "\n"); } process = spawnve (spawn_mode, full_filename, argv, envv); procinfo-> pid = ((PROCESS) process); if (process <= -1) procinfo-> error = errno? errno: EACCES; else if (procinfo-> wait) procinfo-> returncode = waitpid (process, 0, 0); mem_free (argv); } else procinfo-> error = errno; } /* Put things back the way they were before */ restore_redirection (old_stdin, old_stdout, old_stderr); if (curdir != NULL) /* If directory changed, restore it */ { _chdir2 (curdir); free (curdir); } if (free_envv) strtfree (envv); arglist_free (arglist); /* Now, return the process ID or NULL_PROCESS if there was an error */ if (procinfo-> error == 0) return ((PROCESS) process); else return (NULL_PROCESS);