From a4937bc897320563091a77087baf1cdbe52885ab Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Wed, 27 Nov 2013 19:43:33 -0500 Subject: * w32/*: Remove TABs from the source code. I know whitespace commits are annoying, but having these TABs is causing me to miss things when I search through the code. This doesn't try to change the w32 code to meet GNU coding standards. --- w32/compat/dirent.c | 284 +++---- w32/include/dirent.h | 12 +- w32/include/sub_proc.h | 8 +- w32/pathstuff.c | 32 +- w32/subproc/misc.c | 74 +- w32/subproc/proc.h | 8 +- w32/subproc/sub_proc.c | 2104 ++++++++++++++++++++++++------------------------ w32/subproc/w32err.c | 60 +- 8 files changed, 1291 insertions(+), 1291 deletions(-) diff --git a/w32/compat/dirent.c b/w32/compat/dirent.c index bc776dd..40c559a 100644 --- a/w32/compat/dirent.c +++ b/w32/compat/dirent.c @@ -27,180 +27,180 @@ this program. If not, see . */ DIR* opendir(const char* pDirName) { - struct stat sb; - DIR* pDir; - char* pEndDirName; - int nBufferLen; - - /* sanity checks */ - if (!pDirName) { - errno = EINVAL; - return NULL; - } - if (stat(pDirName, &sb) != 0) { - errno = ENOENT; - return NULL; - } - if ((sb.st_mode & S_IFMT) != S_IFDIR) { - errno = ENOTDIR; - return NULL; - } - - /* allocate a DIR structure to return */ - pDir = (DIR *) malloc(sizeof (DIR)); - - if (!pDir) - return NULL; - - /* input directory name length */ - nBufferLen = strlen(pDirName); - - /* copy input directory name to DIR buffer */ - strcpy(pDir->dir_pDirectoryName, pDirName); - - /* point to end of the copied directory name */ - pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1]; - - /* if directory name did not end in '/' or '\', add '/' */ - if ((*pEndDirName != '/') && (*pEndDirName != '\\')) { - pEndDirName++; - *pEndDirName = '/'; - } - - /* now append the wildcard character to the buffer */ - pEndDirName++; - *pEndDirName = '*'; - pEndDirName++; - *pEndDirName = '\0'; - - /* other values defaulted */ - pDir->dir_nNumFiles = 0; - pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; - pDir->dir_ulCookie = __DIRENT_COOKIE; - - return pDir; + struct stat sb; + DIR* pDir; + char* pEndDirName; + int nBufferLen; + + /* sanity checks */ + if (!pDirName) { + errno = EINVAL; + return NULL; + } + if (stat(pDirName, &sb) != 0) { + errno = ENOENT; + return NULL; + } + if ((sb.st_mode & S_IFMT) != S_IFDIR) { + errno = ENOTDIR; + return NULL; + } + + /* allocate a DIR structure to return */ + pDir = (DIR *) malloc(sizeof (DIR)); + + if (!pDir) + return NULL; + + /* input directory name length */ + nBufferLen = strlen(pDirName); + + /* copy input directory name to DIR buffer */ + strcpy(pDir->dir_pDirectoryName, pDirName); + + /* point to end of the copied directory name */ + pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1]; + + /* if directory name did not end in '/' or '\', add '/' */ + if ((*pEndDirName != '/') && (*pEndDirName != '\\')) { + pEndDirName++; + *pEndDirName = '/'; + } + + /* now append the wildcard character to the buffer */ + pEndDirName++; + *pEndDirName = '*'; + pEndDirName++; + *pEndDirName = '\0'; + + /* other values defaulted */ + pDir->dir_nNumFiles = 0; + pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; + pDir->dir_ulCookie = __DIRENT_COOKIE; + + return pDir; } void closedir(DIR *pDir) { - /* got a valid pointer? */ - if (!pDir) { - errno = EINVAL; - return; - } + /* got a valid pointer? */ + if (!pDir) { + errno = EINVAL; + return; + } - /* sanity check that this is a DIR pointer */ - if (pDir->dir_ulCookie != __DIRENT_COOKIE) { - errno = EINVAL; - return; - } + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) { + errno = EINVAL; + return; + } - /* close the WINDOWS32 directory handle */ - if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) - FindClose(pDir->dir_hDirHandle); + /* close the WINDOWS32 directory handle */ + if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) + FindClose(pDir->dir_hDirHandle); - free(pDir); + free(pDir); - return; + return; } struct dirent * readdir(DIR* pDir) { - WIN32_FIND_DATA wfdFindData; - - if (!pDir) { - errno = EINVAL; - return NULL; - } - - /* sanity check that this is a DIR pointer */ - if (pDir->dir_ulCookie != __DIRENT_COOKIE) { - errno = EINVAL; - return NULL; - } - - if (pDir->dir_nNumFiles == 0) { - pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData); - if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE) - return NULL; - } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData)) - return NULL; - - /* bump count for next call to readdir() or telldir() */ - pDir->dir_nNumFiles++; - - /* fill in struct dirent values */ - pDir->dir_sdReturn.d_ino = (ino_t)-1; - strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName); - - return &pDir->dir_sdReturn; + WIN32_FIND_DATA wfdFindData; + + if (!pDir) { + errno = EINVAL; + return NULL; + } + + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) { + errno = EINVAL; + return NULL; + } + + if (pDir->dir_nNumFiles == 0) { + pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData); + if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE) + return NULL; + } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData)) + return NULL; + + /* bump count for next call to readdir() or telldir() */ + pDir->dir_nNumFiles++; + + /* fill in struct dirent values */ + pDir->dir_sdReturn.d_ino = (ino_t)-1; + strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName); + + return &pDir->dir_sdReturn; } void rewinddir(DIR* pDir) { - if (!pDir) { - errno = EINVAL; - return; - } - - /* sanity check that this is a DIR pointer */ - if (pDir->dir_ulCookie != __DIRENT_COOKIE) { - errno = EINVAL; - return; - } - - /* close the WINDOWS32 directory handle */ - if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) - if (!FindClose(pDir->dir_hDirHandle)) - errno = EBADF; - - /* reset members which control readdir() */ - pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; - pDir->dir_nNumFiles = 0; - - return; + if (!pDir) { + errno = EINVAL; + return; + } + + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) { + errno = EINVAL; + return; + } + + /* close the WINDOWS32 directory handle */ + if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) + if (!FindClose(pDir->dir_hDirHandle)) + errno = EBADF; + + /* reset members which control readdir() */ + pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; + pDir->dir_nNumFiles = 0; + + return; } int telldir(DIR* pDir) { - if (!pDir) { - errno = EINVAL; - return -1; - } - - /* sanity check that this is a DIR pointer */ - if (pDir->dir_ulCookie != __DIRENT_COOKIE) { - errno = EINVAL; - return -1; - } - - /* return number of times readdir() called */ - return pDir->dir_nNumFiles; + if (!pDir) { + errno = EINVAL; + return -1; + } + + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) { + errno = EINVAL; + return -1; + } + + /* return number of times readdir() called */ + return pDir->dir_nNumFiles; } void seekdir(DIR* pDir, long nPosition) { - if (!pDir) - return; + if (!pDir) + return; - /* sanity check that this is a DIR pointer */ - if (pDir->dir_ulCookie != __DIRENT_COOKIE) - return; + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) + return; - /* go back to beginning of directory */ - rewinddir(pDir); + /* go back to beginning of directory */ + rewinddir(pDir); - /* loop until we have found position we care about */ - for (--nPosition; nPosition && readdir(pDir); nPosition--); + /* loop until we have found position we care about */ + for (--nPosition; nPosition && readdir(pDir); nPosition--); - /* flag invalid nPosition value */ - if (nPosition) - errno = EINVAL; + /* flag invalid nPosition value */ + if (nPosition) + errno = EINVAL; - return; + return; } diff --git a/w32/include/dirent.h b/w32/include/dirent.h index e75a1b1..16f81f7 100644 --- a/w32/include/dirent.h +++ b/w32/include/dirent.h @@ -36,16 +36,16 @@ this program. If not, see . */ struct dirent { - ino_t d_ino; /* unused - no equivalent on WINDOWS32 */ + ino_t d_ino; /* unused - no equivalent on WINDOWS32 */ char d_name[NAME_MAX+1]; }; typedef struct dir_struct { - ULONG dir_ulCookie; - HANDLE dir_hDirHandle; - DWORD dir_nNumFiles; - char dir_pDirectoryName[NAME_MAX+1]; - struct dirent dir_sdReturn; + ULONG dir_ulCookie; + HANDLE dir_hDirHandle; + DWORD dir_nNumFiles; + char dir_pDirectoryName[NAME_MAX+1]; + struct dirent dir_sdReturn; } DIR; DIR *opendir(const char *); diff --git a/w32/include/sub_proc.h b/w32/include/sub_proc.h index c7d9fee..ae93a8a 100644 --- a/w32/include/sub_proc.h +++ b/w32/include/sub_proc.h @@ -32,17 +32,17 @@ this program. If not, see . */ EXTERN_DECL(HANDLE process_init, (VOID_DECL)); EXTERN_DECL(HANDLE process_init_fd, (HANDLE stdinh, HANDLE stdouth, - HANDLE stderrh)); + HANDLE stderrh)); EXTERN_DECL(long process_begin, (HANDLE proc, char **argv, char **envp, - char *exec_path, char *as_user)); + char *exec_path, char *as_user)); EXTERN_DECL(long process_pipe_io, (HANDLE proc, char *stdin_data, - int stdin_data_len)); + int stdin_data_len)); EXTERN_DECL(long process_file_io, (HANDLE proc)); EXTERN_DECL(void process_cleanup, (HANDLE proc)); EXTERN_DECL(HANDLE process_wait_for_any, (int block, DWORD* pdwWaitStatus)); EXTERN_DECL(void process_register, (HANDLE proc)); EXTERN_DECL(HANDLE process_easy, (char** argv, char** env, - int outfd, int errfd)); + int outfd, int errfd)); EXTERN_DECL(BOOL process_kill, (HANDLE proc, int signal)); EXTERN_DECL(int process_used_slots, (VOID_DECL)); diff --git a/w32/pathstuff.c b/w32/pathstuff.c index 0e33821..4b550cb 100644 --- a/w32/pathstuff.c +++ b/w32/pathstuff.c @@ -27,15 +27,15 @@ convert_vpath_to_windows32(char *Path, char to_delim) { char *etok; /* token separator for old Path */ - /* - * Convert all spaces to delimiters. Note that pathnames which - * contain blanks get trounced here. Use 8.3 format as a workaround. - */ - for (etok = Path; etok && *etok; etok++) - if (isblank ((unsigned char) *etok)) - *etok = to_delim; - - return (convert_Path_to_windows32(Path, to_delim)); + /* + * Convert all spaces to delimiters. Note that pathnames which + * contain blanks get trounced here. Use 8.3 format as a workaround. + */ + for (etok = Path; etok && *etok; etok++) + if (isblank ((unsigned char) *etok)) + *etok = to_delim; + + return (convert_Path_to_windows32(Path, to_delim)); } /* @@ -79,7 +79,7 @@ convert_Path_to_windows32(char *Path, char to_delim) if (etok) { *etok = to_delim; p = ++etok; - } else + } else p += strlen(p); } else { /* found another one, no drive letter */ @@ -114,14 +114,14 @@ w32ify(const char *filename, int resolve) char * getcwd_fs(char* buf, int len) { - char *p = getcwd(buf, len); + char *p = getcwd(buf, len); - if (p) { - char *q = w32ify(buf, 0); - strncpy(buf, q, len); - } + if (p) { + char *q = w32ify(buf, 0); + strncpy(buf, q, len); + } - return p; + return p; } #ifdef unused diff --git a/w32/subproc/misc.c b/w32/subproc/misc.c index 1e3f3a1..96e43ae 100644 --- a/w32/subproc/misc.c +++ b/w32/subproc/misc.c @@ -24,59 +24,59 @@ this program. If not, see . */ /* * Description: Convert a NULL string terminated UNIX environment block to - * an environment block suitable for a windows32 system call + * an environment block suitable for a windows32 system call * * Returns: TRUE= success, FALSE=fail * * Notes/Dependencies: the environment block is sorted in case-insensitive - * order, is double-null terminated, and is a char *, not a char ** + * order, is double-null terminated, and is a char *, not a char ** */ int _cdecl compare(const void *a1, const void *a2) { - return _stricoll(*((char**)a1),*((char**)a2)); + return _stricoll(*((char**)a1),*((char**)a2)); } bool_t arr2envblk(char **arr, char **envblk_out) { - char **tmp; - int size_needed; - int arrcnt; - char *ptr; + char **tmp; + int size_needed; + int arrcnt; + char *ptr; - arrcnt = 0; - while (arr[arrcnt]) { - arrcnt++; - } + arrcnt = 0; + while (arr[arrcnt]) { + arrcnt++; + } - tmp = (char**) calloc(arrcnt + 1, sizeof(char *)); - if (!tmp) { - return FALSE; - } + tmp = (char**) calloc(arrcnt + 1, sizeof(char *)); + if (!tmp) { + return FALSE; + } - arrcnt = 0; - size_needed = 0; - while (arr[arrcnt]) { - tmp[arrcnt] = arr[arrcnt]; - size_needed += strlen(arr[arrcnt]) + 1; - arrcnt++; - } - size_needed++; + arrcnt = 0; + size_needed = 0; + while (arr[arrcnt]) { + tmp[arrcnt] = arr[arrcnt]; + size_needed += strlen(arr[arrcnt]) + 1; + arrcnt++; + } + size_needed++; - qsort((void *) tmp, (size_t) arrcnt, sizeof (char*), compare); + qsort((void *) tmp, (size_t) arrcnt, sizeof (char*), compare); - ptr = *envblk_out = calloc(size_needed, 1); - if (!ptr) { - free(tmp); - return FALSE; - } + ptr = *envblk_out = calloc(size_needed, 1); + if (!ptr) { + free(tmp); + return FALSE; + } - arrcnt = 0; - while (tmp[arrcnt]) { - strcpy(ptr, tmp[arrcnt]); - ptr += strlen(tmp[arrcnt]) + 1; - arrcnt++; - } + arrcnt = 0; + while (tmp[arrcnt]) { + strcpy(ptr, tmp[arrcnt]); + ptr += strlen(tmp[arrcnt]) + 1; + arrcnt++; + } - free(tmp); - return TRUE; + free(tmp); + return TRUE; } diff --git a/w32/subproc/proc.h b/w32/subproc/proc.h index 259a119..62ebf65 100644 --- a/w32/subproc/proc.h +++ b/w32/subproc/proc.h @@ -19,10 +19,10 @@ this program. If not, see . */ typedef int bool_t; -#define E_SCALL 101 -#define E_IO 102 -#define E_NO_MEM 103 -#define E_FORK 104 +#define E_SCALL 101 +#define E_IO 102 +#define E_NO_MEM 103 +#define E_FORK 104 extern bool_t arr2envblk(char **arr, char **envblk_out); diff --git a/w32/subproc/sub_proc.c b/w32/subproc/sub_proc.c index dd0c1a4..7cacac6 100644 --- a/w32/subproc/sub_proc.c +++ b/w32/subproc/sub_proc.c @@ -17,7 +17,7 @@ this program. If not, see . */ #include #include #include -#include /* for _get_osfhandle */ +#include /* for _get_osfhandle */ #ifdef _MSC_VER # include /* for intptr_t */ #else @@ -39,21 +39,21 @@ this program. If not, see . */ static char *make_command_line(char *shell_name, char *exec_path, char **argv); typedef struct sub_process_t { - intptr_t sv_stdin[2]; - intptr_t sv_stdout[2]; - intptr_t sv_stderr[2]; - int using_pipes; - char *inp; - DWORD incnt; - char * volatile outp; - volatile DWORD outcnt; - char * volatile errp; - volatile DWORD errcnt; - pid_t pid; - int exit_code; - int signal; - long last_err; - long lerrno; + intptr_t sv_stdin[2]; + intptr_t sv_stdout[2]; + intptr_t sv_stderr[2]; + int using_pipes; + char *inp; + DWORD incnt; + char * volatile outp; + volatile DWORD outcnt; + char * volatile errp; + volatile DWORD errcnt; + pid_t pid; + int exit_code; + int signal; + long last_err; + long lerrno; } sub_process; /* keep track of children so we can implement a waitpid-like routine */ @@ -69,14 +69,14 @@ static HANDLE jobserver_semaphore = NULL; int open_jobserver_semaphore(const char* name) { jobserver_semaphore = OpenSemaphore( - SEMAPHORE_ALL_ACCESS, // Semaphore access setting - FALSE, // Child processes DON'T inherit - name); // Semaphore name + SEMAPHORE_ALL_ACCESS, // Semaphore access setting + FALSE, // Child processes DON'T inherit + name); // Semaphore name if (jobserver_semaphore == NULL) return 0; - return 1; + return 1; } /* Create new jobserver semaphore */ @@ -85,15 +85,15 @@ int create_jobserver_semaphore(int tokens) sprintf(jobserver_semaphore_name, "gmake_semaphore_%d", _getpid()); jobserver_semaphore = CreateSemaphore( - NULL, // Use default security descriptor - tokens, // Initial count - tokens, // Maximum count - jobserver_semaphore_name); // Semaphore name + NULL, // Use default security descriptor + tokens, // Initial count + tokens, // Maximum count + jobserver_semaphore_name); // Semaphore name if (jobserver_semaphore == NULL) return 0; - return 1; + return 1; } /* Close jobserver semaphore */ @@ -110,8 +110,8 @@ void free_jobserver_semaphore() int acquire_jobserver_semaphore() { DWORD dwEvent = WaitForSingleObject( - jobserver_semaphore, // Handle to semaphore - 0); // DON'T wait on semaphore + jobserver_semaphore, // Handle to semaphore + 0); // DON'T wait on semaphore return (dwEvent == WAIT_OBJECT_0); } @@ -119,10 +119,10 @@ int acquire_jobserver_semaphore() /* Increment semaphore count */ int release_jobserver_semaphore() { - BOOL bResult = ReleaseSemaphore( - jobserver_semaphore, // handle to semaphore - 1, // increase count by one - NULL); // not interested in previous count + BOOL bResult = ReleaseSemaphore( + jobserver_semaphore, // handle to semaphore + 1, // increase count by one + NULL); // not interested in previous count return (bResult); } @@ -151,7 +151,7 @@ int wait_for_semaphore_or_child_process() handles[0] = jobserver_semaphore; /* Build array of handles to wait for */ - for (i = 0; i < proc_index; i++) + for (i = 0; i < proc_index; i++) { /* Don't wait on child processes that have already finished */ if (fake_exits_pending && proc_array[i]->exit_code) @@ -160,11 +160,11 @@ int wait_for_semaphore_or_child_process() handles[dwHandleCount++] = (HANDLE) proc_array[i]->pid; } - dwEvent = WaitForMultipleObjects( - dwHandleCount, // number of objects in array - handles, // array of objects - FALSE, // wait for any object - INFINITE); // wait until object is signalled + dwEvent = WaitForMultipleObjects( + dwHandleCount, // number of objects in array + handles, // array of objects + FALSE, // wait for any object + INFINITE); // wait until object is signalled switch(dwEvent) { @@ -188,22 +188,22 @@ int wait_for_semaphore_or_child_process() static void process_adjust_wait_state(sub_process* pproc) { - int i; - - if (!proc_index) - return; - - for (i = 0; i < proc_index; i++) - if (proc_array[i]->pid == pproc->pid) - break; - - if (i < proc_index) { - proc_index--; - if (i != proc_index) - memmove(&proc_array[i], &proc_array[i+1], - (proc_index-i) * sizeof(sub_process*)); - proc_array[proc_index] = NULL; - } + int i; + + if (!proc_index) + return; + + for (i = 0; i < proc_index; i++) + if (proc_array[i]->pid == pproc->pid) + break; + + if (i < proc_index) { + proc_index--; + if (i != proc_index) + memmove(&proc_array[i], &proc_array[i+1], + (proc_index-i) * sizeof(sub_process*)); + proc_array[proc_index] = NULL; + } } /* @@ -212,44 +212,44 @@ process_adjust_wait_state(sub_process* pproc) static sub_process * process_wait_for_any_private(int block, DWORD* pdwWaitStatus) { - HANDLE handles[MAXIMUM_WAIT_OBJECTS]; - DWORD retval, which; - int i; - - if (!proc_index) - return NULL; - - /* build array of handles to wait for */ - for (i = 0; i < proc_index; i++) { - handles[i] = (HANDLE) proc_array[i]->pid; - - if (fake_exits_pending && proc_array[i]->exit_code) - break; - } - - /* wait for someone to exit */ - if (!fake_exits_pending) { - retval = WaitForMultipleObjects(proc_index, handles, FALSE, (block ? INFINITE : 0)); - which = retval - WAIT_OBJECT_0; - } else { - fake_exits_pending--; - retval = !WAIT_FAILED; - which = i; - } + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + DWORD retval, which; + int i; + + if (!proc_index) + return NULL; + + /* build array of handles to wait for */ + for (i = 0; i < proc_index; i++) { + handles[i] = (HANDLE) proc_array[i]->pid; + + if (fake_exits_pending && proc_array[i]->exit_code) + break; + } + + /* wait for someone to exit */ + if (!fake_exits_pending) { + retval = WaitForMultipleObjects(proc_index, handles, FALSE, (block ? INFINITE : 0)); + which = retval - WAIT_OBJECT_0; + } else { + fake_exits_pending--; + retval = !WAIT_FAILED; + which = i; + } /* If the pointer is not NULL, set the wait status result variable. */ if (pdwWaitStatus) *pdwWaitStatus = retval; - /* return pointer to process */ + /* return pointer to process */ if ((retval == WAIT_TIMEOUT) || (retval == WAIT_FAILED)) { - return NULL; + return NULL; + } + else { + sub_process* pproc = proc_array[which]; + process_adjust_wait_state(pproc); + return pproc; } - else { - sub_process* pproc = proc_array[which]; - process_adjust_wait_state(pproc); - return pproc; - } } /* @@ -258,9 +258,9 @@ process_wait_for_any_private(int block, DWORD* pdwWaitStatus) BOOL process_kill(HANDLE proc, int signal) { - sub_process* pproc = (sub_process*) proc; - pproc->signal = signal; - return (TerminateProcess((HANDLE) pproc->pid, signal)); + sub_process* pproc = (sub_process*) proc; + pproc->signal = signal; + return (TerminateProcess((HANDLE) pproc->pid, signal)); } /* @@ -272,8 +272,8 @@ process_kill(HANDLE proc, int signal) void process_register(HANDLE proc) { - if (proc_index < MAXIMUM_WAIT_OBJECTS) - proc_array[proc_index++] = (sub_process *) proc; + if (proc_index < MAXIMUM_WAIT_OBJECTS) + proc_array[proc_index++] = (sub_process *) proc; } /* @@ -282,7 +282,7 @@ process_register(HANDLE proc) int process_used_slots(void) { - return proc_index; + return proc_index; } /* @@ -290,17 +290,17 @@ process_used_slots(void) * of the children to die and return results. To call this function, * you must do 1 of things: * - * x = process_easy(...); + * x = process_easy(...); * * or * - * x = process_init_fd(); - * process_register(x); + * x = process_init_fd(); + * process_register(x); * * or * - * x = process_init(); - * process_register(x); + * x = process_init(); + * process_register(x); * * You must NOT then call process_pipe_io() because this function is * not capable of handling automatic notification of any child @@ -310,18 +310,18 @@ process_used_slots(void) HANDLE process_wait_for_any(int block, DWORD* pdwWaitStatus) { - sub_process* pproc = process_wait_for_any_private(block, pdwWaitStatus); - - if (!pproc) - return NULL; - else { - /* - * Ouch! can't tell caller if this fails directly. Caller - * will have to use process_last_err() + sub_process* pproc = process_wait_for_any_private(block, pdwWaitStatus); + + if (!pproc) + return NULL; + else { + /* + * Ouch! can't tell caller if this fails directly. Caller + * will have to use process_last_err() */ - (void) process_file_io(pproc); - return ((HANDLE) pproc); - } + (void) process_file_io(pproc); + return ((HANDLE) pproc); + } } long @@ -335,14 +335,14 @@ long process_last_err(HANDLE proc) { if (proc == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE; - return (((sub_process *)proc)->last_err); + return (((sub_process *)proc)->last_err); } long process_exit_code(HANDLE proc) { if (proc == INVALID_HANDLE_VALUE) return EXIT_FAILURE; - return (((sub_process *)proc)->exit_code); + return (((sub_process *)proc)->exit_code); } void @@ -351,7 +351,7 @@ process_noinherit(int fd) HANDLE fh = (HANDLE)_get_osfhandle(fd); if (fh && fh != INVALID_HANDLE_VALUE) - SetHandleInformation(fh, HANDLE_FLAG_INHERIT, 0); + SetHandleInformation(fh, HANDLE_FLAG_INHERIT, 0); } /* @@ -364,183 +364,183 @@ a reasonable error handling for this function. char * process_outbuf(HANDLE proc) { - return (((sub_process *)proc)->outp); + return (((sub_process *)proc)->outp); } char * process_errbuf(HANDLE proc) { - return (((sub_process *)proc)->errp); + return (((sub_process *)proc)->errp); } int process_outcnt(HANDLE proc) { - return (((sub_process *)proc)->outcnt); + return (((sub_process *)proc)->outcnt); } int process_errcnt(HANDLE proc) { - return (((sub_process *)proc)->errcnt); + return (((sub_process *)proc)->errcnt); } void process_pipes(HANDLE proc, int pipes[3]) { - pipes[0] = ((sub_process *)proc)->sv_stdin[0]; - pipes[1] = ((sub_process *)proc)->sv_stdout[0]; - pipes[2] = ((sub_process *)proc)->sv_stderr[0]; - return; + pipes[0] = ((sub_process *)proc)->sv_stdin[0]; + pipes[1] = ((sub_process *)proc)->sv_stdout[0]; + pipes[2] = ((sub_process *)proc)->sv_stderr[0]; + return; } */ - HANDLE + HANDLE process_init() { - sub_process *pproc; - /* - * open file descriptors for attaching stdin/stdout/sterr - */ - HANDLE stdin_pipes[2]; - HANDLE stdout_pipes[2]; - HANDLE stderr_pipes[2]; - SECURITY_ATTRIBUTES inherit; - BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; - - pproc = malloc(sizeof(*pproc)); - memset(pproc, 0, sizeof(*pproc)); - - /* We can't use NULL for lpSecurityDescriptor because that - uses the default security descriptor of the calling process. - Instead we use a security descriptor with no DACL. This - allows nonrestricted access to the associated objects. */ - - if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd), - SECURITY_DESCRIPTOR_REVISION)) { - pproc->last_err = GetLastError(); - pproc->lerrno = E_SCALL; - return((HANDLE)pproc); - } - - inherit.nLength = sizeof(inherit); - inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd); - inherit.bInheritHandle = TRUE; - - // By convention, parent gets pipe[0], and child gets pipe[1] - // This means the READ side of stdin pipe goes into pipe[1] - // and the WRITE side of the stdout and stderr pipes go into pipe[1] - if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE || - CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE || - CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) { - - pproc->last_err = GetLastError(); - pproc->lerrno = E_SCALL; - return((HANDLE)pproc); - } - - // - // Mark the parent sides of the pipes as non-inheritable - // - if (SetHandleInformation(stdin_pipes[0], - HANDLE_FLAG_INHERIT, 0) == FALSE || - SetHandleInformation(stdout_pipes[0], - HANDLE_FLAG_INHERIT, 0) == FALSE || - SetHandleInformation(stderr_pipes[0], - HANDLE_FLAG_INHERIT, 0) == FALSE) { - - pproc->last_err = GetLastError(); - pproc->lerrno = E_SCALL; - return((HANDLE)pproc); - } - pproc->sv_stdin[0] = (intptr_t) stdin_pipes[0]; - pproc->sv_stdin[1] = (intptr_t) stdin_pipes[1]; - pproc->sv_stdout[0] = (intptr_t) stdout_pipes[0]; - pproc->sv_stdout[1] = (intptr_t) stdout_pipes[1]; - pproc->sv_stderr[0] = (intptr_t) stderr_pipes[0]; - pproc->sv_stderr[1] = (intptr_t) stderr_pipes[1]; - - pproc->using_pipes = 1; - - pproc->lerrno = 0; - - return((HANDLE)pproc); + sub_process *pproc; + /* + * open file descriptors for attaching stdin/stdout/sterr + */ + HANDLE stdin_pipes[2]; + HANDLE stdout_pipes[2]; + HANDLE stderr_pipes[2]; + SECURITY_ATTRIBUTES inherit; + BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; + + pproc = malloc(sizeof(*pproc)); + memset(pproc, 0, sizeof(*pproc)); + + /* We can't use NULL for lpSecurityDescriptor because that + uses the default security descriptor of the calling process. + Instead we use a security descriptor with no DACL. This + allows nonrestricted access to the associated objects. */ + + if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd), + SECURITY_DESCRIPTOR_REVISION)) { + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + return((HANDLE)pproc); + } + + inherit.nLength = sizeof(inherit); + inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd); + inherit.bInheritHandle = TRUE; + + // By convention, parent gets pipe[0], and child gets pipe[1] + // This means the READ side of stdin pipe goes into pipe[1] + // and the WRITE side of the stdout and stderr pipes go into pipe[1] + if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE || + CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE || + CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + return((HANDLE)pproc); + } + + // + // Mark the parent sides of the pipes as non-inheritable + // + if (SetHandleInformation(stdin_pipes[0], + HANDLE_FLAG_INHERIT, 0) == FALSE || + SetHandleInformation(stdout_pipes[0], + HANDLE_FLAG_INHERIT, 0) == FALSE || + SetHandleInformation(stderr_pipes[0], + HANDLE_FLAG_INHERIT, 0) == FALSE) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + return((HANDLE)pproc); + } + pproc->sv_stdin[0] = (intptr_t) stdin_pipes[0]; + pproc->sv_stdin[1] = (intptr_t) stdin_pipes[1]; + pproc->sv_stdout[0] = (intptr_t) stdout_pipes[0]; + pproc->sv_stdout[1] = (intptr_t) stdout_pipes[1]; + pproc->sv_stderr[0] = (intptr_t) stderr_pipes[0]; + pproc->sv_stderr[1] = (intptr_t) stderr_pipes[1]; + + pproc->using_pipes = 1; + + pproc->lerrno = 0; + + return((HANDLE)pproc); } - HANDLE + HANDLE process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh) { - sub_process *pproc; + sub_process *pproc; - pproc = malloc(sizeof(*pproc)); - if (pproc) { - memset(pproc, 0, sizeof(*pproc)); + pproc = malloc(sizeof(*pproc)); + if (pproc) { + memset(pproc, 0, sizeof(*pproc)); - /* - * Just pass the provided file handles to the 'child - * side' of the pipe, bypassing pipes altogether. - */ - pproc->sv_stdin[1] = (intptr_t) stdinh; - pproc->sv_stdout[1] = (intptr_t) stdouth; - pproc->sv_stderr[1] = (intptr_t) stderrh; + /* + * Just pass the provided file handles to the 'child + * side' of the pipe, bypassing pipes altogether. + */ + pproc->sv_stdin[1] = (intptr_t) stdinh; + pproc->sv_stdout[1] = (intptr_t) stdouth; + pproc->sv_stderr[1] = (intptr_t) stderrh; - pproc->last_err = pproc->lerrno = 0; - } + pproc->last_err = pproc->lerrno = 0; + } - return((HANDLE)pproc); + return((HANDLE)pproc); } static HANDLE find_file(const char *exec_path, const char *path_var, - char *full_fname, DWORD full_len) + char *full_fname, DWORD full_len) { - HANDLE exec_handle; - char *fname; - char *ext; - DWORD req_len; - int i; - static const char *extensions[] = - /* Should .com come before no-extension case? */ - { ".exe", ".cmd", ".bat", "", ".com", NULL }; - - fname = xmalloc(strlen(exec_path) + 5); - strcpy(fname, exec_path); - ext = fname + strlen(fname); - - for (i = 0; extensions[i]; i++) { - strcpy(ext, extensions[i]); - if (((req_len = SearchPath (path_var, fname, NULL, full_len, - full_fname, NULL)) > 0 - /* For compatibility with previous code, which - used OpenFile, and with Windows operation in - general, also look in various default - locations, such as Windows directory and - Windows System directory. Warning: this also - searches PATH in the Make's environment, which - might not be what the Makefile wants, but it - seems to be OK as a fallback, after the - previous SearchPath failed to find on child's - PATH. */ - || (req_len = SearchPath (NULL, fname, NULL, full_len, - full_fname, NULL)) > 0) - && req_len <= full_len - && (exec_handle = - CreateFile(full_fname, - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL)) != INVALID_HANDLE_VALUE) { - free(fname); - return(exec_handle); - } - } - - free(fname); - return INVALID_HANDLE_VALUE; + HANDLE exec_handle; + char *fname; + char *ext; + DWORD req_len; + int i; + static const char *extensions[] = + /* Should .com come before no-extension case? */ + { ".exe", ".cmd", ".bat", "", ".com", NULL }; + + fname = xmalloc(strlen(exec_path) + 5); + strcpy(fname, exec_path); + ext = fname + strlen(fname); + + for (i = 0; extensions[i]; i++) { + strcpy(ext, extensions[i]); + if (((req_len = SearchPath (path_var, fname, NULL, full_len, + full_fname, NULL)) > 0 + /* For compatibility with previous code, which + used OpenFile, and with Windows operation in + general, also look in various default + locations, such as Windows directory and + Windows System directory. Warning: this also + searches PATH in the Make's environment, which + might not be what the Makefile wants, but it + seems to be OK as a fallback, after the + previous SearchPath failed to find on child's + PATH. */ + || (req_len = SearchPath (NULL, fname, NULL, full_len, + full_fname, NULL)) > 0) + && req_len <= full_len + && (exec_handle = + CreateFile(full_fname, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL)) != INVALID_HANDLE_VALUE) { + free(fname); + return(exec_handle); + } + } + + free(fname); + return INVALID_HANDLE_VALUE; } /* @@ -551,16 +551,16 @@ find_file(const char *exec_path, const char *path_var, static int batch_file_with_spaces(const char *fname) { - size_t fnlen = strlen(fname); - - return (fnlen > 4 - && (_strnicmp(fname + fnlen - 4, ".bat", 4) == 0 - || _strnicmp(fname + fnlen - 4, ".cmd", 4) == 0) - /* The set of characters in the 2nd arg to strpbrk - should be the same one used by make_command_line - below to decide whether an argv[] element needs - quoting. */ - && strpbrk(fname, " \t") != NULL); + size_t fnlen = strlen(fname); + + return (fnlen > 4 + && (_strnicmp(fname + fnlen - 4, ".bat", 4) == 0 + || _strnicmp(fname + fnlen - 4, ".cmd", 4) == 0) + /* The set of characters in the 2nd arg to strpbrk + should be the same one used by make_command_line + below to decide whether an argv[] element needs + quoting. */ + && strpbrk(fname, " \t") != NULL); } @@ -573,327 +573,327 @@ batch_file_with_spaces(const char *fname) */ long process_begin( - HANDLE proc, - char **argv, - char **envp, - char *exec_path, - char *as_user) + HANDLE proc, + char **argv, + char **envp, + char *exec_path, + char *as_user) { - sub_process *pproc = (sub_process *)proc; - char *shell_name = 0; - int file_not_found=0; - HANDLE exec_handle; - char exec_fname[MAX_PATH]; - const char *path_var = NULL; - char **ep; - char buf[MAX_PATH]; - DWORD bytes_returned; - DWORD flags; - char *command_line; - STARTUPINFO startInfo; - PROCESS_INFORMATION procInfo; - char *envblk=NULL; - int pass_null_exec_path = 0; - - /* - * Shell script detection... if the exec_path starts with #! then - * we want to exec shell-script-name exec-path, not just exec-path - * NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl. We do not - * hard-code the path to the shell or perl or whatever: Instead, we - * assume it's in the path somewhere (generally, the NT tools - * bin directory) - */ - - /* Use the Makefile's value of PATH to look for the program to - execute, because it could be different from Make's PATH - (e.g., if the target sets its own value. */ - if (envp) - for (ep = envp; *ep; ep++) { - if (strncmp (*ep, "PATH=", 5) == 0 - || strncmp (*ep, "Path=", 5) == 0) { - path_var = *ep + 5; - break; - } - } - exec_handle = find_file(exec_path, path_var, - exec_fname, sizeof(exec_fname)); - - /* - * If we couldn't open the file, just assume that Windows will be - * somehow able to find and execute it. If the first character - * of the command is '/', assume they set SHELL to a Unixy shell - * that have some magic mounts known only to it, and run the whole - * command via $SHELL -c "COMMAND" instead. - */ - if (exec_handle == INVALID_HANDLE_VALUE) { - if (exec_path[0] == '/') { - char *new_argv0; - char **argvi = argv; - int arglen = 0; - - strcpy(buf, variable_expand ("$(SHELL)")); - shell_name = &buf[0]; - strcpy(exec_fname, "-c"); - /* Construct a single command string in argv[0]. */ - while (*argvi) { - arglen += strlen(*argvi) + 1; - argvi++; - } - new_argv0 = xmalloc(arglen + 1); - new_argv0[0] = '\0'; - for (argvi = argv; *argvi; argvi++) { - strcat(new_argv0, *argvi); - strcat(new_argv0, " "); - } - /* Remove the extra blank at the end. */ - new_argv0[arglen-1] = '\0'; - free(argv[0]); - argv[0] = new_argv0; - argv[1] = NULL; - } - else - file_not_found++; - } - else { - /* Attempt to read the first line of the file */ - if (ReadFile( exec_handle, - buf, sizeof(buf) - 1, /* leave room for trailing NULL */ - &bytes_returned, 0) == FALSE || bytes_returned < 2) { - - pproc->last_err = GetLastError(); - pproc->lerrno = E_IO; - CloseHandle(exec_handle); - return(-1); - } - if (buf[0] == '#' && buf[1] == '!') { - /* - * This is a shell script... Change the command line from - * exec_path args to shell_name exec_path args - */ - char *p; - - /* Make sure buf is NULL terminated */ - buf[bytes_returned] = 0; - /* - * Depending on the file system type, etc. the first line - * of the shell script may end with newline or newline-carriage-return - * Whatever it ends with, cut it off. - */ - p= strchr(buf, '\n'); - if (p) - *p = 0; - p = strchr(buf, '\r'); - if (p) - *p = 0; - - /* - * Find base name of shell - */ - shell_name = strrchr( buf, '/'); - if (shell_name) { - shell_name++; - } else { - shell_name = &buf[2];/* skipping "#!" */ - } - - } - CloseHandle(exec_handle); - } - - flags = 0; - - if (file_not_found) - command_line = make_command_line( shell_name, exec_path, argv); - else { - /* If exec_fname includes whitespace, CreateProcess - behaves erratically and unreliably, and often fails - if argv[0] also includes whitespace (and thus will - be quoted by make_command_line below). So in that - case, we don't pass exec_fname as the 1st arg to - CreateProcess, but instead replace argv[0] with - exec_fname (to keep its leading directories and - extension as found by find_file), and pass NULL to - CreateProcess as its 1st arg. This works around - the bugs in CreateProcess, which are probably - caused by its passing the command to cmd.exe with - some incorrect quoting. */ - if (!shell_name - && batch_file_with_spaces(exec_fname) - && _stricmp(exec_path, argv[0]) == 0) { - pass_null_exec_path = 1; - free (argv[0]); - argv[0] = xstrdup(exec_fname); - } - command_line = make_command_line( shell_name, exec_fname, argv); - } - - if ( command_line == NULL ) { - pproc->last_err = 0; - pproc->lerrno = E_NO_MEM; - return(-1); - } - - if (envp) { - if (arr2envblk(envp, &envblk) ==FALSE) { - pproc->last_err = 0; - pproc->lerrno = E_NO_MEM; - free( command_line ); - return(-1); - } - } - - if (shell_name || file_not_found || pass_null_exec_path) { - exec_path = 0; /* Search for the program in %Path% */ - } else { - exec_path = exec_fname; - } - - /* - * Set up inherited stdin, stdout, stderr for child - */ - GetStartupInfo(&startInfo); - startInfo.dwFlags = STARTF_USESTDHANDLES; - startInfo.lpReserved = 0; - startInfo.cbReserved2 = 0; - startInfo.lpReserved2 = 0; - startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1]; - startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1]; - startInfo.hStdError = (HANDLE)pproc->sv_stderr[1]; - - if (as_user) { - if (envblk) free(envblk); - return -1; - } else { - DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n", - exec_path ? exec_path : "NULL", - command_line ? command_line : "NULL")); - if (CreateProcess( - exec_path, - command_line, - NULL, - 0, /* default security attributes for thread */ - TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */ - flags, - envblk, - 0, /* default starting directory */ - &startInfo, - &procInfo) == FALSE) { - - pproc->last_err = GetLastError(); - pproc->lerrno = E_FORK; - fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n", + sub_process *pproc = (sub_process *)proc; + char *shell_name = 0; + int file_not_found=0; + HANDLE exec_handle; + char exec_fname[MAX_PATH]; + const char *path_var = NULL; + char **ep; + char buf[MAX_PATH]; + DWORD bytes_returned; + DWORD flags; + char *command_line; + STARTUPINFO startInfo; + PROCESS_INFORMATION procInfo; + char *envblk=NULL; + int pass_null_exec_path = 0; + + /* + * Shell script detection... if the exec_path starts with #! then + * we want to exec shell-script-name exec-path, not just exec-path + * NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl. We do not + * hard-code the path to the shell or perl or whatever: Instead, we + * assume it's in the path somewhere (generally, the NT tools + * bin directory) + */ + + /* Use the Makefile's value of PATH to look for the program to + execute, because it could be different from Make's PATH + (e.g., if the target sets its own value. */ + if (envp) + for (ep = envp; *ep; ep++) { + if (strncmp (*ep, "PATH=", 5) == 0 + || strncmp (*ep, "Path=", 5) == 0) { + path_var = *ep + 5; + break; + } + } + exec_handle = find_file(exec_path, path_var, + exec_fname, sizeof(exec_fname)); + + /* + * If we couldn't open the file, just assume that Windows will be + * somehow able to find and execute it. If the first character + * of the command is '/', assume they set SHELL to a Unixy shell + * that have some magic mounts known only to it, and run the whole + * command via $SHELL -c "COMMAND" instead. + */ + if (exec_handle == INVALID_HANDLE_VALUE) { + if (exec_path[0] == '/') { + char *new_argv0; + char **argvi = argv; + int arglen = 0; + + strcpy(buf, variable_expand ("$(SHELL)")); + shell_name = &buf[0]; + strcpy(exec_fname, "-c"); + /* Construct a single command string in argv[0]. */ + while (*argvi) { + arglen += strlen(*argvi) + 1; + argvi++; + } + new_argv0 = xmalloc(arglen + 1); + new_argv0[0] = '\0'; + for (argvi = argv; *argvi; argvi++) { + strcat(new_argv0, *argvi); + strcat(new_argv0, " "); + } + /* Remove the extra blank at the end. */ + new_argv0[arglen-1] = '\0'; + free(argv[0]); + argv[0] = new_argv0; + argv[1] = NULL; + } + else + file_not_found++; + } + else { + /* Attempt to read the first line of the file */ + if (ReadFile( exec_handle, + buf, sizeof(buf) - 1, /* leave room for trailing NULL */ + &bytes_returned, 0) == FALSE || bytes_returned < 2) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_IO; + CloseHandle(exec_handle); + return(-1); + } + if (buf[0] == '#' && buf[1] == '!') { + /* + * This is a shell script... Change the command line from + * exec_path args to shell_name exec_path args + */ + char *p; + + /* Make sure buf is NULL terminated */ + buf[bytes_returned] = 0; + /* + * Depending on the file system type, etc. the first line + * of the shell script may end with newline or newline-carriage-return + * Whatever it ends with, cut it off. + */ + p= strchr(buf, '\n'); + if (p) + *p = 0; + p = strchr(buf, '\r'); + if (p) + *p = 0; + + /* + * Find base name of shell + */ + shell_name = strrchr( buf, '/'); + if (shell_name) { + shell_name++; + } else { + shell_name = &buf[2];/* skipping "#!" */ + } + + } + CloseHandle(exec_handle); + } + + flags = 0; + + if (file_not_found) + command_line = make_command_line( shell_name, exec_path, argv); + else { + /* If exec_fname includes whitespace, CreateProcess + behaves erratically and unreliably, and often fails + if argv[0] also includes whitespace (and thus will + be quoted by make_command_line below). So in that + case, we don't pass exec_fname as the 1st arg to + CreateProcess, but instead replace argv[0] with + exec_fname (to keep its leading directories and + extension as found by find_file), and pass NULL to + CreateProcess as its 1st arg. This works around + the bugs in CreateProcess, which are probably + caused by its passing the command to cmd.exe with + some incorrect quoting. */ + if (!shell_name + && batch_file_with_spaces(exec_fname) + && _stricmp(exec_path, argv[0]) == 0) { + pass_null_exec_path = 1; + free (argv[0]); + argv[0] = xstrdup(exec_fname); + } + command_line = make_command_line( shell_name, exec_fname, argv); + } + + if ( command_line == NULL ) { + pproc->last_err = 0; + pproc->lerrno = E_NO_MEM; + return(-1); + } + + if (envp) { + if (arr2envblk(envp, &envblk) ==FALSE) { + pproc->last_err = 0; + pproc->lerrno = E_NO_MEM; + free( command_line ); + return(-1); + } + } + + if (shell_name || file_not_found || pass_null_exec_path) { + exec_path = 0; /* Search for the program in %Path% */ + } else { + exec_path = exec_fname; + } + + /* + * Set up inherited stdin, stdout, stderr for child + */ + GetStartupInfo(&startInfo); + startInfo.dwFlags = STARTF_USESTDHANDLES; + startInfo.lpReserved = 0; + startInfo.cbReserved2 = 0; + startInfo.lpReserved2 = 0; + startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1]; + startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1]; + startInfo.hStdError = (HANDLE)pproc->sv_stderr[1]; + + if (as_user) { + if (envblk) free(envblk); + return -1; + } else { + DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n", + exec_path ? exec_path : "NULL", + command_line ? command_line : "NULL")); + if (CreateProcess( + exec_path, + command_line, + NULL, + 0, /* default security attributes for thread */ + TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */ + flags, + envblk, + 0, /* default starting directory */ + &startInfo, + &procInfo) == FALSE) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_FORK; + fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n", exec_path ? exec_path : "NULL", command_line); - if (envblk) free(envblk); - free( command_line ); - return(-1); - } - } - - pproc->pid = (pid_t)procInfo.hProcess; - /* Close the thread handle -- we'll just watch the process */ - CloseHandle(procInfo.hThread); - - /* Close the halves of the pipes we don't need */ - if ((HANDLE)pproc->sv_stdin[1] != INVALID_HANDLE_VALUE) - CloseHandle((HANDLE)pproc->sv_stdin[1]); - if ((HANDLE)pproc->sv_stdout[1] != INVALID_HANDLE_VALUE) - CloseHandle((HANDLE)pproc->sv_stdout[1]); - if ((HANDLE)pproc->sv_stderr[1] != INVALID_HANDLE_VALUE) - CloseHandle((HANDLE)pproc->sv_stderr[1]); + if (envblk) free(envblk); + free( command_line ); + return(-1); + } + } + + pproc->pid = (pid_t)procInfo.hProcess; + /* Close the thread handle -- we'll just watch the process */ + CloseHandle(procInfo.hThread); + + /* Close the halves of the pipes we don't need */ + if ((HANDLE)pproc->sv_stdin[1] != INVALID_HANDLE_VALUE) + CloseHandle((HANDLE)pproc->sv_stdin[1]); + if ((HANDLE)pproc->sv_stdout[1] != INVALID_HANDLE_VALUE) + CloseHandle((HANDLE)pproc->sv_stdout[1]); + if ((HANDLE)pproc->sv_stderr[1] != INVALID_HANDLE_VALUE) + CloseHandle((HANDLE)pproc->sv_stderr[1]); pproc->sv_stdin[1] = 0; pproc->sv_stdout[1] = 0; pproc->sv_stderr[1] = 0; - free( command_line ); - if (envblk) free(envblk); - pproc->lerrno=0; - return 0; + free( command_line ); + if (envblk) free(envblk); + pproc->lerrno=0; + return 0; } -#if 0 /* unused */ +#if 0 /* unused */ static DWORD proc_stdin_thread(sub_process *pproc) { - DWORD in_done; - for (;;) { - if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt, - &in_done, NULL) == FALSE) - _endthreadex(0); - // This if should never be true for anonymous pipes, but gives - // us a chance to change I/O mechanisms later - if (in_done < pproc->incnt) { - pproc->incnt -= in_done; - pproc->inp += in_done; - } else { - _endthreadex(0); - } - } - return 0; // for compiler warnings only.. not reached + DWORD in_done; + for (;;) { + if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt, + &in_done, NULL) == FALSE) + _endthreadex(0); + // This if should never be true for anonymous pipes, but gives + // us a chance to change I/O mechanisms later + if (in_done < pproc->incnt) { + pproc->incnt -= in_done; + pproc->inp += in_done; + } else { + _endthreadex(0); + } + } + return 0; // for compiler warnings only.. not reached } static DWORD proc_stdout_thread(sub_process *pproc) { - DWORD bufsize = 1024; - char c; - DWORD nread; - pproc->outp = malloc(bufsize); - if (pproc->outp == NULL) - _endthreadex(0); - pproc->outcnt = 0; - - for (;;) { - if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL) - == FALSE) { -/* map_windows32_error_to_string(GetLastError());*/ - _endthreadex(0); - } - if (nread == 0) - _endthreadex(0); - if (pproc->outcnt + nread > bufsize) { - bufsize += nread + 512; - pproc->outp = realloc(pproc->outp, bufsize); - if (pproc->outp == NULL) { - pproc->outcnt = 0; - _endthreadex(0); - } - } - pproc->outp[pproc->outcnt++] = c; - } - return 0; + DWORD bufsize = 1024; + char c; + DWORD nread; + pproc->outp = malloc(bufsize); + if (pproc->outp == NULL) + _endthreadex(0); + pproc->outcnt = 0; + + for (;;) { + if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL) + == FALSE) { +/* map_windows32_error_to_string(GetLastError());*/ + _endthreadex(0); + } + if (nread == 0) + _endthreadex(0); + if (pproc->outcnt + nread > bufsize) { + bufsize += nread + 512; + pproc->outp = realloc(pproc->outp, bufsize); + if (pproc->outp == NULL) { + pproc->outcnt = 0; + _endthreadex(0); + } + } + pproc->outp[pproc->outcnt++] = c; + } + return 0; } static DWORD proc_stderr_thread(sub_process *pproc) { - DWORD bufsize = 1024; - char c; - DWORD nread; - pproc->errp = malloc(bufsize); - if (pproc->errp == NULL) - _endthreadex(0); - pproc->errcnt = 0; - - for (;;) { - if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) { - map_windows32_error_to_string(GetLastError()); - _endthreadex(0); - } - if (nread == 0) - _endthreadex(0); - if (pproc->errcnt + nread > bufsize) { - bufsize += nread + 512; - pproc->errp = realloc(pproc->errp, bufsize); - if (pproc->errp == NULL) { - pproc->errcnt = 0; - _endthreadex(0); - } - } - pproc->errp[pproc->errcnt++] = c; - } - return 0; + DWORD bufsize = 1024; + char c; + DWORD nread; + pproc->errp = malloc(bufsize); + if (pproc->errp == NULL) + _endthreadex(0); + pproc->errcnt = 0; + + for (;;) { + if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) { + map_windows32_error_to_string(GetLastError()); + _endthreadex(0); + } + if (nread == 0) + _endthreadex(0); + if (pproc->errcnt + nread > bufsize) { + bufsize += nread + 512; + pproc->errp = realloc(pproc->errp, bufsize); + if (pproc->errp == NULL) { + pproc->errcnt = 0; + _endthreadex(0); + } + } + pproc->errp[pproc->errcnt++] = c; + } + return 0; } @@ -906,158 +906,158 @@ proc_stderr_thread(sub_process *pproc) * * Notes/Dependencies: */ - long + long process_pipe_io( - HANDLE proc, - char *stdin_data, - int stdin_data_len) + HANDLE proc, + char *stdin_data, + int stdin_data_len) { - sub_process *pproc = (sub_process *)proc; - bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE; - HANDLE childhand = (HANDLE) pproc->pid; - HANDLE tStdin = NULL, tStdout = NULL, tStderr = NULL; - unsigned int dwStdin, dwStdout, dwStderr; - HANDLE wait_list[4]; - DWORD wait_count; - DWORD wait_return; - HANDLE ready_hand; - bool_t child_dead = FALSE; - BOOL GetExitCodeResult; - - /* - * Create stdin thread, if needed - */ - pproc->inp = stdin_data; - pproc->incnt = stdin_data_len; - if (!pproc->inp) { - stdin_eof = TRUE; - CloseHandle((HANDLE)pproc->sv_stdin[0]); - pproc->sv_stdin[0] = 0; - } else { - tStdin = (HANDLE) _beginthreadex( 0, 1024, - (unsigned (__stdcall *) (void *))proc_stdin_thread, - pproc, 0, &dwStdin); - if (tStdin == 0) { - pproc->last_err = GetLastError(); - pproc->lerrno = E_SCALL; - goto done; - } - } - - /* - * Assume child will produce stdout and stderr - */ - tStdout = (HANDLE) _beginthreadex( 0, 1024, - (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0, - &dwStdout); - tStderr = (HANDLE) _beginthreadex( 0, 1024, - (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0, - &dwStderr); - - if (tStdout == 0 || tStderr == 0) { - - pproc->last_err = GetLastError(); - pproc->lerrno = E_SCALL; - goto done; - } - - - /* - * Wait for all I/O to finish and for the child process to exit - */ - - while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) { - wait_count = 0; - if (!stdin_eof) { - wait_list[wait_count++] = tStdin; - } - if (!stdout_eof) { - wait_list[wait_count++] = tStdout; - } - if (!stderr_eof) { - wait_list[wait_count++] = tStderr; - } - if (!child_dead) { - wait_list[wait_count++] = childhand; - } - - wait_return = WaitForMultipleObjects(wait_count, wait_list, - FALSE, /* don't wait for all: one ready will do */ - child_dead? 1000 :INFINITE); /* after the child dies, subthreads have - one second to collect all remaining output */ - - if (wait_return == WAIT_FAILED) { -/* map_windows32_error_to_string(GetLastError());*/ - pproc->last_err = GetLastError(); - pproc->lerrno = E_SCALL; - goto done; - } - - ready_hand = wait_list[wait_return - WAIT_OBJECT_0]; - - if (ready_hand == tStdin) { - CloseHandle((HANDLE)pproc->sv_stdin[0]); - pproc->sv_stdin[0] = 0; - CloseHandle(tStdin); - tStdin = 0; - stdin_eof = TRUE; - - } else if (ready_hand == tStdout) { - - CloseHandle((HANDLE)pproc->sv_stdout[0]); - pproc->sv_stdout[0] = 0; - CloseHandle(tStdout); - tStdout = 0; - stdout_eof = TRUE; - - } else if (ready_hand == tStderr) { - - CloseHandle((HANDLE)pproc->sv_stderr[0]); - pproc->sv_stderr[0] = 0; - CloseHandle(tStderr); - tStderr = 0; - stderr_eof = TRUE; - - } else if (ready_hand == childhand) { - - DWORD ierr; - GetExitCodeResult = GetExitCodeProcess(childhand, &ierr); - if (ierr == CONTROL_C_EXIT) { - pproc->signal = SIGINT; - } else { - pproc->exit_code = ierr; - } - if (GetExitCodeResult == FALSE) { - pproc->last_err = GetLastError(); - pproc->lerrno = E_SCALL; - goto done; - } - child_dead = TRUE; - - } else { - - /* ?? Got back a handle we didn't query ?? */ - pproc->last_err = 0; - pproc->lerrno = E_FAIL; - goto done; - } - } + sub_process *pproc = (sub_process *)proc; + bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE; + HANDLE childhand = (HANDLE) pproc->pid; + HANDLE tStdin = NULL, tStdout = NULL, tStderr = NULL; + unsigned int dwStdin, dwStdout, dwStderr; + HANDLE wait_list[4]; + DWORD wait_count; + DWORD wait_return; + HANDLE ready_hand; + bool_t child_dead = FALSE; + BOOL GetExitCodeResult; + + /* + * Create stdin thread, if needed + */ + pproc->inp = stdin_data; + pproc->incnt = stdin_data_len; + if (!pproc->inp) { + stdin_eof = TRUE; + CloseHandle((HANDLE)pproc->sv_stdin[0]); + pproc->sv_stdin[0] = 0; + } else { + tStdin = (HANDLE) _beginthreadex( 0, 1024, + (unsigned (__stdcall *) (void *))proc_stdin_thread, + pproc, 0, &dwStdin); + if (tStdin == 0) { + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done; + } + } + + /* + * Assume child will produce stdout and stderr + */ + tStdout = (HANDLE) _beginthreadex( 0, 1024, + (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0, + &dwStdout); + tStderr = (HANDLE) _beginthreadex( 0, 1024, + (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0, + &dwStderr); + + if (tStdout == 0 || tStderr == 0) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done; + } + + + /* + * Wait for all I/O to finish and for the child process to exit + */ + + while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) { + wait_count = 0; + if (!stdin_eof) { + wait_list[wait_count++] = tStdin; + } + if (!stdout_eof) { + wait_list[wait_count++] = tStdout; + } + if (!stderr_eof) { + wait_list[wait_count++] = tStderr; + } + if (!child_dead) { + wait_list[wait_count++] = childhand; + } + + wait_return = WaitForMultipleObjects(wait_count, wait_list, + FALSE, /* don't wait for all: one ready will do */ + child_dead? 1000 :INFINITE); /* after the child dies, subthreads have + one second to collect all remaining output */ + + if (wait_return == WAIT_FAILED) { +/* map_windows32_error_to_string(GetLastError());*/ + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done; + } + + ready_hand = wait_list[wait_return - WAIT_OBJECT_0]; + + if (ready_hand == tStdin) { + CloseHandle((HANDLE)pproc->sv_stdin[0]); + pproc->sv_stdin[0] = 0; + CloseHandle(tStdin); + tStdin = 0; + stdin_eof = TRUE; + + } else if (ready_hand == tStdout) { + + CloseHandle((HANDLE)pproc->sv_stdout[0]); + pproc->sv_stdout[0] = 0; + CloseHandle(tStdout); + tStdout = 0; + stdout_eof = TRUE; + + } else if (ready_hand == tStderr) { + + CloseHandle((HANDLE)pproc->sv_stderr[0]); + pproc->sv_stderr[0] = 0; + CloseHandle(tStderr); + tStderr = 0; + stderr_eof = TRUE; + + } else if (ready_hand == childhand) { + + DWORD ierr; + GetExitCodeResult = GetExitCodeProcess(childhand, &ierr); + if (ierr == CONTROL_C_EXIT) { + pproc->signal = SIGINT; + } else { + pproc->exit_code = ierr; + } + if (GetExitCodeResult == FALSE) { + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done; + } + child_dead = TRUE; + + } else { + + /* ?? Got back a handle we didn't query ?? */ + pproc->last_err = 0; + pproc->lerrno = E_FAIL; + goto done; + } + } done: - if (tStdin != 0) - CloseHandle(tStdin); - if (tStdout != 0) - CloseHandle(tStdout); - if (tStderr != 0) - CloseHandle(tStderr); - - if (pproc->lerrno) - return(-1); - else - return(0); + if (tStdin != 0) + CloseHandle(tStdin); + if (tStdout != 0) + CloseHandle(tStdout); + if (tStderr != 0) + CloseHandle(tStderr); + + if (pproc->lerrno) + return(-1); + else + return(0); } -#endif /* unused */ +#endif /* unused */ /* * Purpose: collects output from child process and returns results @@ -1068,74 +1068,74 @@ process_pipe_io( * * Notes/Dependencies: */ - long + long process_file_io( - HANDLE proc) + HANDLE proc) { - sub_process *pproc; - HANDLE childhand; - DWORD wait_return; - BOOL GetExitCodeResult; + sub_process *pproc; + HANDLE childhand; + DWORD wait_return; + BOOL GetExitCodeResult; DWORD ierr; - if (proc == NULL) - pproc = process_wait_for_any_private(1, 0); - else - pproc = (sub_process *)proc; - - /* some sort of internal error */ - if (!pproc) - return -1; - - childhand = (HANDLE) pproc->pid; - - /* - * This function is poorly named, and could also be used just to wait - * for child death if you're doing your own pipe I/O. If that is - * the case, close the pipe handles here. - */ - if (pproc->sv_stdin[0]) { - CloseHandle((HANDLE)pproc->sv_stdin[0]); - pproc->sv_stdin[0] = 0; - } - if (pproc->sv_stdout[0]) { - CloseHandle((HANDLE)pproc->sv_stdout[0]); - pproc->sv_stdout[0] = 0; - } - if (pproc->sv_stderr[0]) { - CloseHandle((HANDLE)pproc->sv_stderr[0]); - pproc->sv_stderr[0] = 0; - } - - /* - * Wait for the child process to exit - */ - - wait_return = WaitForSingleObject(childhand, INFINITE); - - if (wait_return != WAIT_OBJECT_0) { -/* map_windows32_error_to_string(GetLastError());*/ - pproc->last_err = GetLastError(); - pproc->lerrno = E_SCALL; - goto done2; - } - - GetExitCodeResult = GetExitCodeProcess(childhand, &ierr); - if (ierr == CONTROL_C_EXIT) { - pproc->signal = SIGINT; - } else { - pproc->exit_code = ierr; - } - if (GetExitCodeResult == FALSE) { - pproc->last_err = GetLastError(); - pproc->lerrno = E_SCALL; - } + if (proc == NULL) + pproc = process_wait_for_any_private(1, 0); + else + pproc = (sub_process *)proc; + + /* some sort of internal error */ + if (!pproc) + return -1; + + childhand = (HANDLE) pproc->pid; + + /* + * This function is poorly named, and could also be used just to wait + * for child death if you're doing your own pipe I/O. If that is + * the case, close the pipe handles here. + */ + if (pproc->sv_stdin[0]) { + CloseHandle((HANDLE)pproc->sv_stdin[0]); + pproc->sv_stdin[0] = 0; + } + if (pproc->sv_stdout[0]) { + CloseHandle((HANDLE)pproc->sv_stdout[0]); + pproc->sv_stdout[0] = 0; + } + if (pproc->sv_stderr[0]) { + CloseHandle((HANDLE)pproc->sv_stderr[0]); + pproc->sv_stderr[0] = 0; + } + + /* + * Wait for the child process to exit + */ + + wait_return = WaitForSingleObject(childhand, INFINITE); + + if (wait_return != WAIT_OBJECT_0) { +/* map_windows32_error_to_string(GetLastError());*/ + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done2; + } + + GetExitCodeResult = GetExitCodeProcess(childhand, &ierr); + if (ierr == CONTROL_C_EXIT) { + pproc->signal = SIGINT; + } else { + pproc->exit_code = ierr; + } + if (GetExitCodeResult == FALSE) { + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + } done2: - if (pproc->lerrno) - return(-1); - else - return(0); + if (pproc->lerrno) + return(-1); + else + return(0); } @@ -1143,39 +1143,39 @@ done2: * Description: Clean up any leftover handles, etc. It is up to the * caller to manage and free the input, output, and stderr buffers. */ - void + void process_cleanup( - HANDLE proc) + HANDLE proc) { - sub_process *pproc = (sub_process *)proc; - int i; - - if (pproc->using_pipes) { - for (i= 0; i <= 1; i++) { - if ((HANDLE)pproc->sv_stdin[i] - && (HANDLE)pproc->sv_stdin[i] != INVALID_HANDLE_VALUE) - CloseHandle((HANDLE)pproc->sv_stdin[i]); - if ((HANDLE)pproc->sv_stdout[i] - && (HANDLE)pproc->sv_stdout[i] != INVALID_HANDLE_VALUE) - CloseHandle((HANDLE)pproc->sv_stdout[i]); - if ((HANDLE)pproc->sv_stderr[i] - && (HANDLE)pproc->sv_stderr[i] != INVALID_HANDLE_VALUE) - CloseHandle((HANDLE)pproc->sv_stderr[i]); - } - } - if ((HANDLE)pproc->pid) - CloseHandle((HANDLE)pproc->pid); - - free(pproc); + sub_process *pproc = (sub_process *)proc; + int i; + + if (pproc->using_pipes) { + for (i= 0; i <= 1; i++) { + if ((HANDLE)pproc->sv_stdin[i] + && (HANDLE)pproc->sv_stdin[i] != INVALID_HANDLE_VALUE) + CloseHandle((HANDLE)pproc->sv_stdin[i]); + if ((HANDLE)pproc->sv_stdout[i] + && (HANDLE)pproc->sv_stdout[i] != INVALID_HANDLE_VALUE) + CloseHandle((HANDLE)pproc->sv_stdout[i]); + if ((HANDLE)pproc->sv_stderr[i] + && (HANDLE)pproc->sv_stderr[i] != INVALID_HANDLE_VALUE) + CloseHandle((HANDLE)pproc->sv_stderr[i]); + } + } + if ((HANDLE)pproc->pid) + CloseHandle((HANDLE)pproc->pid); + + free(pproc); } /* * Description: - * Create a command line buffer to pass to CreateProcess + * Create a command line buffer to pass to CreateProcess * * Returns: the buffer or NULL for failure - * Shell case: sh_name a:/full/path/to/script argv[1] argv[2] ... + * Shell case: sh_name a:/full/path/to/script argv[1] argv[2] ... * Otherwise: argv[0] argv[1] argv[2] ... * * Notes/Dependencies: @@ -1186,237 +1186,237 @@ process_cleanup( static char * make_command_line( char *shell_name, char *full_exec_path, char **argv) { - int argc = 0; - char** argvi; - int* enclose_in_quotes = NULL; - int* enclose_in_quotes_i; - unsigned int bytes_required = 0; - char* command_line; - char* command_line_i; - int cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */ - int have_sh = 0; /* HAVE_CYGWIN_SHELL */ + int argc = 0; + char** argvi; + int* enclose_in_quotes = NULL; + int* enclose_in_quotes_i; + unsigned int bytes_required = 0; + char* command_line; + char* command_line_i; + int cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */ + int have_sh = 0; /* HAVE_CYGWIN_SHELL */ #ifdef HAVE_CYGWIN_SHELL - have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe")); - cygwin_mode = 1; + have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe")); + cygwin_mode = 1; #endif - if (shell_name && full_exec_path) { - bytes_required - = strlen(shell_name) + 1 + strlen(full_exec_path); - /* - * Skip argv[0] if any, when shell_name is given. - * The special case of "-c" in full_exec_path means - * argv[0] is not the shell name, but the command string - * to pass to the shell. - */ - if (*argv && strcmp(full_exec_path, "-c")) argv++; - /* - * Add one for the intervening space. - */ - if (*argv) bytes_required++; - } - - argvi = argv; - while (*(argvi++)) argc++; - - if (argc) { - enclose_in_quotes = (int*) calloc(1, argc * sizeof(int)); - - if (!enclose_in_quotes) { - return NULL; - } - } - - /* We have to make one pass through each argv[i] to see if we need - * to enclose it in ", so we might as well figure out how much - * memory we'll need on the same pass. - */ - - argvi = argv; - enclose_in_quotes_i = enclose_in_quotes; - while(*argvi) { - char* p = *argvi; - unsigned int backslash_count = 0; - - /* - * We have to enclose empty arguments in ". - */ - if (!(*p)) *enclose_in_quotes_i = 1; - - while(*p) { - switch (*p) { - case '\"': - /* - * We have to insert a backslash for each " - * and each \ that precedes the ". - */ - bytes_required += (backslash_count + 1); - backslash_count = 0; - break; + if (shell_name && full_exec_path) { + bytes_required + = strlen(shell_name) + 1 + strlen(full_exec_path); + /* + * Skip argv[0] if any, when shell_name is given. + * The special case of "-c" in full_exec_path means + * argv[0] is not the shell name, but the command string + * to pass to the shell. + */ + if (*argv && strcmp(full_exec_path, "-c")) argv++; + /* + * Add one for the intervening space. + */ + if (*argv) bytes_required++; + } + + argvi = argv; + while (*(argvi++)) argc++; + + if (argc) { + enclose_in_quotes = (int*) calloc(1, argc * sizeof(int)); + + if (!enclose_in_quotes) { + return NULL; + } + } + + /* We have to make one pass through each argv[i] to see if we need + * to enclose it in ", so we might as well figure out how much + * memory we'll need on the same pass. + */ + + argvi = argv; + enclose_in_quotes_i = enclose_in_quotes; + while(*argvi) { + char* p = *argvi; + unsigned int backslash_count = 0; + + /* + * We have to enclose empty arguments in ". + */ + if (!(*p)) *enclose_in_quotes_i = 1; + + while(*p) { + switch (*p) { + case '\"': + /* + * We have to insert a backslash for each " + * and each \ that precedes the ". + */ + bytes_required += (backslash_count + 1); + backslash_count = 0; + break; #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL) - case '\\': - backslash_count++; - break; + case '\\': + backslash_count++; + break; #endif - /* - * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress - * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so - * that argv in always equals argv out. This was removed. Say you have - * such a program named glob.exe. You enter - * glob '*' - * at the sh command prompt. Obviously the intent is to make glob do the - * wildcarding instead of sh. If we set *enclose_in_quotes_i for '*' or '?', - * then the command line that glob would see would be - * glob "*" - * and the _setargv in SETARGV.OBJ would _not_ expand the *. - */ - case ' ': - case '\t': - *enclose_in_quotes_i = 1; - /* fall through */ - - default: - backslash_count = 0; - break; - } - - /* - * Add one for each character in argv[i]. - */ - bytes_required++; - - p++; - } - - if (*enclose_in_quotes_i) { - /* - * Add one for each enclosing ", - * and one for each \ that precedes the - * closing ". - */ - bytes_required += (backslash_count + 2); - } - - /* - * Add one for the intervening space. - */ - if (*(++argvi)) bytes_required++; - enclose_in_quotes_i++; - } - - /* - * Add one for the terminating NULL. - */ - bytes_required++; - - command_line = (char*) malloc(bytes_required); - - if (!command_line) { - if (enclose_in_quotes) free(enclose_in_quotes); - return NULL; - } - - command_line_i = command_line; - - if (shell_name && full_exec_path) { - while(*shell_name) { - *(command_line_i++) = *(shell_name++); - } - - *(command_line_i++) = ' '; - - while(*full_exec_path) { - *(command_line_i++) = *(full_exec_path++); - } - - if (*argv) { - *(command_line_i++) = ' '; - } - } - - argvi = argv; - enclose_in_quotes_i = enclose_in_quotes; - - while(*argvi) { - char* p = *argvi; - unsigned int backslash_count = 0; - - if (*enclose_in_quotes_i) { - *(command_line_i++) = '\"'; - } - - while(*p) { - if (*p == '\"') { - if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */ - /* instead of a \", cygwin likes "" */ - *(command_line_i++) = '\"'; - } else { - - /* - * We have to insert a backslash for the " - * and each \ that precedes the ". - */ - backslash_count++; - - while(backslash_count) { - *(command_line_i++) = '\\'; - backslash_count--; - }; - } + /* + * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress + * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so + * that argv in always equals argv out. This was removed. Say you have + * such a program named glob.exe. You enter + * glob '*' + * at the sh command prompt. Obviously the intent is to make glob do the + * wildcarding instead of sh. If we set *enclose_in_quotes_i for '*' or '?', + * then the command line that glob would see would be + * glob "*" + * and the _setargv in SETARGV.OBJ would _not_ expand the *. + */ + case ' ': + case '\t': + *enclose_in_quotes_i = 1; + /* fall through */ + + default: + backslash_count = 0; + break; + } + + /* + * Add one for each character in argv[i]. + */ + bytes_required++; + + p++; + } + + if (*enclose_in_quotes_i) { + /* + * Add one for each enclosing ", + * and one for each \ that precedes the + * closing ". + */ + bytes_required += (backslash_count + 2); + } + + /* + * Add one for the intervening space. + */ + if (*(++argvi)) bytes_required++; + enclose_in_quotes_i++; + } + + /* + * Add one for the terminating NULL. + */ + bytes_required++; + + command_line = (char*) malloc(bytes_required); + + if (!command_line) { + if (enclose_in_quotes) free(enclose_in_quotes); + return NULL; + } + + command_line_i = command_line; + + if (shell_name && full_exec_path) { + while(*shell_name) { + *(command_line_i++) = *(shell_name++); + } + + *(command_line_i++) = ' '; + + while(*full_exec_path) { + *(command_line_i++) = *(full_exec_path++); + } + + if (*argv) { + *(command_line_i++) = ' '; + } + } + + argvi = argv; + enclose_in_quotes_i = enclose_in_quotes; + + while(*argvi) { + char* p = *argvi; + unsigned int backslash_count = 0; + + if (*enclose_in_quotes_i) { + *(command_line_i++) = '\"'; + } + + while(*p) { + if (*p == '\"') { + if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */ + /* instead of a \", cygwin likes "" */ + *(command_line_i++) = '\"'; + } else { + + /* + * We have to insert a backslash for the " + * and each \ that precedes the ". + */ + backslash_count++; + + while(backslash_count) { + *(command_line_i++) = '\\'; + backslash_count--; + }; + } #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL) - } else if (*p == '\\') { - backslash_count++; - } else { - backslash_count = 0; + } else if (*p == '\\') { + backslash_count++; + } else { + backslash_count = 0; #endif - } + } - /* - * Copy the character. - */ - *(command_line_i++) = *(p++); - } + /* + * Copy the character. + */ + *(command_line_i++) = *(p++); + } - if (*enclose_in_quotes_i) { + if (*enclose_in_quotes_i) { #if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL) - /* - * Add one \ for each \ that precedes the - * closing ". - */ - while(backslash_count--) { - *(command_line_i++) = '\\'; - }; + /* + * Add one \ for each \ that precedes the + * closing ". + */ + while(backslash_count--) { + *(command_line_i++) = '\\'; + }; #endif - *(command_line_i++) = '\"'; - } - - /* - * Append an intervening space. - */ - if (*(++argvi)) { - *(command_line_i++) = ' '; - } - - enclose_in_quotes_i++; - } - - /* - * Append the terminating NULL. - */ - *command_line_i = '\0'; - - if (enclose_in_quotes) free(enclose_in_quotes); - return command_line; + *(command_line_i++) = '\"'; + } + + /* + * Append an intervening space. + */ + if (*(++argvi)) { + *(command_line_i++) = ' '; + } + + enclose_in_quotes_i++; + } + + /* + * Append the terminating NULL. + */ + *command_line_i = '\0'; + + if (enclose_in_quotes) free(enclose_in_quotes); + return command_line; } /* * Description: Given an argv and optional envp, launch the process * using the default stdin, stdout, and stderr handles. * Also, register process so that process_wait_for_any_private() - * can be used via process_file_io(NULL) or - * process_wait_for_any(). + * can be used via process_file_io(NULL) or + * process_wait_for_any(). * * Returns: * @@ -1424,10 +1424,10 @@ make_command_line( char *shell_name, char *full_exec_path, char **argv) */ HANDLE process_easy( - char **argv, - char **envp, - int outfd, - int errfd) + char **argv, + char **envp, + int outfd, + int errfd) { HANDLE hIn = INVALID_HANDLE_VALUE; HANDLE hOut = INVALID_HANDLE_VALUE; @@ -1436,8 +1436,8 @@ process_easy( DWORD e; if (proc_index >= MAXIMUM_WAIT_OBJECTS) { - DB (DB_JOBS, ("process_easy: All process slots used up\n")); - return INVALID_HANDLE_VALUE; + DB (DB_JOBS, ("process_easy: All process slots used up\n")); + return INVALID_HANDLE_VALUE; } /* Standard handles returned by GetStdHandle can be NULL or INVALID_HANDLE_VALUE if the parent process closed them. If that @@ -1445,25 +1445,25 @@ process_easy( CreateProcess as the corresponding handle to inherit. */ tmpIn = GetStdHandle(STD_INPUT_HANDLE); if (DuplicateHandle(GetCurrentProcess(), - tmpIn, - GetCurrentProcess(), - &hIn, - 0, - TRUE, - DUPLICATE_SAME_ACCESS) == FALSE) { + tmpIn, + GetCurrentProcess(), + &hIn, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) { if ((e = GetLastError()) == ERROR_INVALID_HANDLE) { tmpIn = CreateFile("NUL", GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (tmpIn != INVALID_HANDLE_VALUE - && DuplicateHandle(GetCurrentProcess(), - tmpIn, - GetCurrentProcess(), - &hIn, - 0, - TRUE, - DUPLICATE_SAME_ACCESS) == FALSE) - CloseHandle(tmpIn); + && DuplicateHandle(GetCurrentProcess(), + tmpIn, + GetCurrentProcess(), + &hIn, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) + CloseHandle(tmpIn); } if (hIn == INVALID_HANDLE_VALUE) { fprintf(stderr, "process_easy: DuplicateHandle(In) failed (e=%ld)\n", e); @@ -1475,25 +1475,25 @@ process_easy( else tmpOut = GetStdHandle (STD_OUTPUT_HANDLE); if (DuplicateHandle(GetCurrentProcess(), - tmpOut, - GetCurrentProcess(), - &hOut, - 0, - TRUE, - DUPLICATE_SAME_ACCESS) == FALSE) { + tmpOut, + GetCurrentProcess(), + &hOut, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) { if ((e = GetLastError()) == ERROR_INVALID_HANDLE) { tmpOut = CreateFile("NUL", GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (tmpOut != INVALID_HANDLE_VALUE - && DuplicateHandle(GetCurrentProcess(), - tmpOut, - GetCurrentProcess(), - &hOut, - 0, - TRUE, - DUPLICATE_SAME_ACCESS) == FALSE) - CloseHandle(tmpOut); + && DuplicateHandle(GetCurrentProcess(), + tmpOut, + GetCurrentProcess(), + &hOut, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) + CloseHandle(tmpOut); } if (hOut == INVALID_HANDLE_VALUE) { fprintf(stderr, "process_easy: DuplicateHandle(Out) failed (e=%ld)\n", e); @@ -1505,25 +1505,25 @@ process_easy( else tmpErr = GetStdHandle(STD_ERROR_HANDLE); if (DuplicateHandle(GetCurrentProcess(), - tmpErr, - GetCurrentProcess(), - &hErr, - 0, - TRUE, - DUPLICATE_SAME_ACCESS) == FALSE) { + tmpErr, + GetCurrentProcess(), + &hErr, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) { if ((e = GetLastError()) == ERROR_INVALID_HANDLE) { tmpErr = CreateFile("NUL", GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (tmpErr != INVALID_HANDLE_VALUE - && DuplicateHandle(GetCurrentProcess(), - tmpErr, - GetCurrentProcess(), - &hErr, - 0, - TRUE, - DUPLICATE_SAME_ACCESS) == FALSE) - CloseHandle(tmpErr); + && DuplicateHandle(GetCurrentProcess(), + tmpErr, + GetCurrentProcess(), + &hErr, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) + CloseHandle(tmpErr); } if (hErr == INVALID_HANDLE_VALUE) { fprintf(stderr, "process_easy: DuplicateHandle(Err) failed (e=%ld)\n", e); diff --git a/w32/subproc/w32err.c b/w32/subproc/w32err.c index 9b0866a..b4fe9c1 100644 --- a/w32/subproc/w32err.c +++ b/w32/subproc/w32err.c @@ -45,41 +45,41 @@ map_windows32_error_to_string (DWORD ercode) { * the corresponding GCC qualifier is '__thread'.) */ static char szMessageBuffer[128]; - /* Fill message buffer with a default message in - * case FormatMessage fails - */ + /* Fill message buffer with a default message in + * case FormatMessage fails + */ wsprintf (szMessageBuffer, "Error %ld\n", ercode); - /* - * Special code for winsock error handling. - */ - if (ercode > WSABASEERR) { + /* + * Special code for winsock error handling. + */ + if (ercode > WSABASEERR) { #if 0 - HMODULE hModule = GetModuleHandle("wsock32"); - if (hModule != NULL) { - FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, - hModule, - ercode, - LANG_NEUTRAL, - szMessageBuffer, - sizeof(szMessageBuffer), - NULL); - FreeLibrary(hModule); - } + HMODULE hModule = GetModuleHandle("wsock32"); + if (hModule != NULL) { + FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, + hModule, + ercode, + LANG_NEUTRAL, + szMessageBuffer, + sizeof(szMessageBuffer), + NULL); + FreeLibrary(hModule); + } #else O (fatal, NILF, szMessageBuffer); #endif - } else { - /* - * Default system message handling - */ - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - ercode, - LANG_NEUTRAL, - szMessageBuffer, - sizeof(szMessageBuffer), - NULL); - } + } else { + /* + * Default system message handling + */ + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + ercode, + LANG_NEUTRAL, + szMessageBuffer, + sizeof(szMessageBuffer), + NULL); + } return szMessageBuffer; } -- cgit v1.2.3