| iMatix home page | << | < | > | >> |
SFL Version 2.11 |
#include "sflproc.h" PROCESS process_create ( const char *filename, /* Name of file to execute */ char *argv [], /* Arguments for process, or NULL */ const char *workdir, /* Working directory, or NULL */ const char *std_in, /* Stdin device, or NULL */ const char *std_out, /* Stdout device, or NULL */ const char *std_err, /* Stderr device, or NULL */ char *envv [], /* Environment variables, or NULL */ Bool wait /* Wait for process to end */ )
Creates a subprocess and returns a PROCESS identifying the new process. Optionally directs standard input, output, and error streams to specified devices. The caller can also specify environment symbols that the subprocess can access. Accepts these arguments:
filename | File to execute; if bare filename, searches PATH. |
argv [] | List of arguments; argv [0] is filename; ends in a NULL. |
workdir | Working directory; if NULL, remains in current directory. |
std in | Device to use for standard input; NULL = no redirection. |
std out | Device to use for standard output; NULL = no redirection. |
std err | Device to use for standard error; NULL = no redirection. |
envs [] | List of environment symbols to define, or NULL. |
{ #if (defined (__UNIX__) || defined (__OS2__) || defined (WIN32)) PROCESS_DATA procinfo = PROCESS_DATA_INIT; PROCESS process = NULL_PROCESS; ASSERT (filename); if (!filename) return (NULL_PROCESS); /* Set up information to start the new process */ procinfo.filename = filename; procinfo.argv = argv; procinfo.workdir = workdir; procinfo.envv = envv; procinfo.wait = wait; /* process_setinfo handles: * 1. Determining if the path can be searched * 2. Determining if root privileges should be preserved (if applicable) * 3. Redirecting IO streams (if required) */ if (process setinfo (&procinfo, std_in, std_out, TRUE, std_err, FALSE) == 0) { process = process create full (&procinfo); process close io (&procinfo); /* Stuff value into errno, to emulate old behaviour */ errno = procinfo.error; } return (process); #elif (defined (__VMS__)) PROCESS process; /* Our created process handle */ char *curdir, /* Current directory */ *clean_filename, /* Unescaped filename */ *full_filename = NULL, *full_std_in = NULL, *full_std_out = NULL; qbyte process_flags; /* Process creation flags */ int argn, /* Argument number */ rc; /* Return code from lib$spawn */ Bool rebuilt_argv = FALSE; /* Did we rebuild argv[]? */ VMS_STRING (command_dsc, ""); /* Define string descriptors */ VMS_STRING (std_in_dsc, ""); VMS_STRING (std_out_dsc, ""); /* If argv[] array was not supplied, build it now from filename */ if (!argv) { argv = tok split (filename); filename = argv [0]; rebuilt_argv = TRUE; } /* If filename contains a path or extension, disregard them */ clean_filename = strrchr (filename, '/'); if (clean_filename) clean_filename++; else clean_filename = (char *) filename; if (strchr (clean_filename, '.')) *strchr (clean_filename, '.') = '\0'; /* Rebuild full command from filename and arguments */ full_filename = mem_alloc (tok text size ((char **) argv) + strlen (clean_filename) + 1); strcpy (full_filename, clean_filename); for (argn = 1; argv [argn]; argn++) xstrcat (full_filename, " ", argv [argn], NULL); /* Free argument table if we allocated it dynamically here */ if (rebuilt_argv) tok free (argv); command_dsc.value = full_filename; command_dsc.length = strlen (full_filename); /* Prepare full names for stdin and stdout */ curdir = get curdir (); if (std_in) { if (strchr (std_in, '/')) /* If already with path, use as is */ full_std_in = mem_strdup (std_in); else { xstrcpy_debug (); full_std_in = xstrcpy (NULL, curdir, "/", std_in, NULL); } translate_to_vms (full_std_in); std_in_dsc.value = full_std_in; } if (std_out) { if (strchr (std_out, '/')) /* If already with path, use as is */ full_std_out = mem_strdup (std_out); else { xstrcpy_debug (); full_std_out = xstrcpy (NULL, curdir, "/", std_out, NULL); } translate_to_vms (full_std_out); std_out_dsc.value = full_std_out; } std_in_dsc.length = std_in? strlen (std_in_dsc.value): 0; std_out_dsc.length = std_out? strlen (std_out_dsc.value): 0; /* If requested, change to working directory */ if (workdir) chdir (workdir); /* Prepare process flags */ if (wait) process_flags = 0; else process_flags = 1; /* Bit 1 = don't wait for child */ process = mem_alloc (sizeof (PROC_HANDLE)); process-> id = 0; process-> status = 0; /* Completion status */ /* char *envv [], */ /* Environment variables, or NULL */ rc = lib$spawn ( &command_dsc, /* Command to run */ std_in? &std_in_dsc: NULL, /* Stdin descriptor */ std_out? &std_out_dsc: NULL, /* Stdout+stderr */ &process_flags, /* Options for new process */ &NULL, /* Process name -- generated */ &process-> id, /* Returned process ID */ &process-> status); if (workdir) /* Switch back to original dir */ chdir (curdir); mem_free (curdir); mem_strfree (&full_filename); /* Deallocate various buffers, */ mem_strfree (&full_std_in); /* if they were used */ mem_strfree (&full_std_out); /* */ /* Return process ID. If we waited for completion, the process id */ /* is always NULL. */ if (rc != 1) /* Process failed with error */ { process close (process); process = NULL; } else if (wait) /* Finished with process */ process close (process); return (process); #else return ((PROCESS) 0); /* Not supported on this system */ #endif }
| << | < | > | >> | Copyright © 1996-2000 iMatix Corporation |