Ignore:
Timestamp:
Mar 12, 2018, 8:32:29 PM (7 years ago)
Author:
bird
Message:

Imported make 4.2.1 (2e55f5e4abdc0e38c1d64be703b446695e70b3b6) from https://git.savannah.gnu.org/git/make.git.

Location:
vendor/gnumake/current/w32
Files:
3 added
2 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • vendor/gnumake/current/w32/Makefile.am

    r2596 r3138  
    11# Makefile.am to create libw32.a for mingw32 host.
    2 # Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
    3 # 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2# Copyright (C) 1997-2016 Free Software Foundation, Inc.
    43# This file is part of GNU Make.
    54#
     
    1716# this program.  If not, see <http://www.gnu.org/licenses/>.
    1817
     18AUTOMAKE_OPTIONS = subdir-objects
     19
    1920noinst_LIBRARIES = libw32.a
    2021
    2122libw32_a_SOURCES =  subproc/misc.c subproc/sub_proc.c subproc/w32err.c \
    22                     pathstuff.c
     23                    compat/posixfcn.c pathstuff.c w32os.c
    2324
    24 libw32_a_CPPFLAGS = -I$(srcdir)/include -I$(srcdir)/subproc -I$(top_srcdir)
     25libw32_a_CPPFLAGS = -I$(srcdir)/include -I$(srcdir)/subproc -I$(top_srcdir) \
     26                    -I$(top_srcdir)/glob
  • vendor/gnumake/current/w32/compat/dirent.c

    r2596 r3138  
    11/* Directory entry code for Window platforms.
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
     
    2928opendir(const char* pDirName)
    3029{
    31         struct stat sb;
    32         DIR*    pDir;
    33         char*   pEndDirName;
    34         int     nBufferLen;
    35 
    36         /* sanity checks */
    37         if (!pDirName) {
    38                 errno = EINVAL;
    39                 return NULL;
    40         }
    41         if (stat(pDirName, &sb) != 0) {
    42                 errno = ENOENT;
    43                 return NULL;
    44         }
    45         if ((sb.st_mode & S_IFMT) != S_IFDIR) {
    46                 errno = ENOTDIR;
    47                 return NULL;
    48         }
    49 
    50         /* allocate a DIR structure to return */
    51         pDir = (DIR *) malloc(sizeof (DIR));
    52 
    53         if (!pDir)
    54                 return NULL;
    55 
    56         /* input directory name length */
    57         nBufferLen = strlen(pDirName);
    58 
    59         /* copy input directory name to DIR buffer */
    60         strcpy(pDir->dir_pDirectoryName, pDirName);
    61 
    62         /* point to end of the copied directory name */
    63         pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1];
    64 
    65         /* if directory name did not end in '/' or '\', add '/' */
    66         if ((*pEndDirName != '/') && (*pEndDirName != '\\')) {
    67                 pEndDirName++;
    68                 *pEndDirName = '/';
    69         }
    70 
    71         /* now append the wildcard character to the buffer */
    72         pEndDirName++;
    73         *pEndDirName = '*';
    74         pEndDirName++;
    75         *pEndDirName = '\0';
    76 
    77         /* other values defaulted */
    78         pDir->dir_nNumFiles = 0;
    79         pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
    80         pDir->dir_ulCookie = __DIRENT_COOKIE;
    81 
    82         return pDir;
     30        struct stat sb;
     31        DIR*    pDir;
     32        char*   pEndDirName;
     33        int     nBufferLen;
     34
     35        /* sanity checks */
     36        if (!pDirName) {
     37                errno = EINVAL;
     38                return NULL;
     39        }
     40        if (stat(pDirName, &sb) != 0) {
     41                errno = ENOENT;
     42                return NULL;
     43        }
     44        if ((sb.st_mode & S_IFMT) != S_IFDIR) {
     45                errno = ENOTDIR;
     46                return NULL;
     47        }
     48
     49        /* allocate a DIR structure to return */
     50        pDir = (DIR *) malloc(sizeof (DIR));
     51
     52        if (!pDir)
     53                return NULL;
     54
     55        /* input directory name length */
     56        nBufferLen = strlen(pDirName);
     57
     58        /* copy input directory name to DIR buffer */
     59        strcpy(pDir->dir_pDirectoryName, pDirName);
     60
     61        /* point to end of the copied directory name */
     62        pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1];
     63
     64        /* if directory name did not end in '/' or '\', add '/' */
     65        if ((*pEndDirName != '/') && (*pEndDirName != '\\')) {
     66                pEndDirName++;
     67                *pEndDirName = '/';
     68        }
     69
     70        /* now append the wildcard character to the buffer */
     71        pEndDirName++;
     72        *pEndDirName = '*';
     73        pEndDirName++;
     74        *pEndDirName = '\0';
     75
     76        /* other values defaulted */
     77        pDir->dir_nNumFiles = 0;
     78        pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
     79        pDir->dir_ulCookie = __DIRENT_COOKIE;
     80
     81        return pDir;
    8382}
    8483
     
    8685closedir(DIR *pDir)
    8786{
    88         /* got a valid pointer? */
    89         if (!pDir) {
    90                 errno = EINVAL;
    91                 return;
    92         }
    93 
    94         /* sanity check that this is a DIR pointer */
    95         if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
    96                 errno = EINVAL;
    97                 return;
    98         }
    99 
    100         /* close the WINDOWS32 directory handle */
    101         if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
    102                 FindClose(pDir->dir_hDirHandle);
    103 
    104         free(pDir);
    105 
    106         return;
     87        /* got a valid pointer? */
     88        if (!pDir) {
     89                errno = EINVAL;
     90                return;
     91        }
     92
     93        /* sanity check that this is a DIR pointer */
     94        if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
     95                errno = EINVAL;
     96                return;
     97        }
     98
     99        /* close the WINDOWS32 directory handle */
     100        if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
     101                FindClose(pDir->dir_hDirHandle);
     102
     103        free(pDir);
     104
     105        return;
    107106}
    108107
     
    110109readdir(DIR* pDir)
    111110{
    112         WIN32_FIND_DATA wfdFindData;
    113 
    114         if (!pDir) {
    115                 errno = EINVAL;
    116                 return NULL;
    117         }
    118 
    119         /* sanity check that this is a DIR pointer */
    120         if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
    121                 errno = EINVAL;
    122                 return NULL;
    123         }
    124 
    125         if (pDir->dir_nNumFiles == 0) {
    126                 pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData);
    127                 if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE)
    128                         return NULL;
    129         } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData))
    130                         return NULL;
    131 
    132         /* bump count for next call to readdir() or telldir() */
    133         pDir->dir_nNumFiles++;
    134 
    135         /* fill in struct dirent values */
    136         pDir->dir_sdReturn.d_ino = (ino_t)-1;
    137         strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName);
    138 
    139         return &pDir->dir_sdReturn;
     111        WIN32_FIND_DATA wfdFindData;
     112
     113        if (!pDir) {
     114                errno = EINVAL;
     115                return NULL;
     116        }
     117
     118        /* sanity check that this is a DIR pointer */
     119        if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
     120                errno = EINVAL;
     121                return NULL;
     122        }
     123
     124        if (pDir->dir_nNumFiles == 0) {
     125                pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData);
     126                if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE)
     127                        return NULL;
     128        } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData))
     129                        return NULL;
     130
     131        /* bump count for next call to readdir() or telldir() */
     132        pDir->dir_nNumFiles++;
     133
     134        /* fill in struct dirent values */
     135        pDir->dir_sdReturn.d_ino = (ino_t)-1;
     136        strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName);
     137
     138        return &pDir->dir_sdReturn;
    140139}
    141140
     
    143142rewinddir(DIR* pDir)
    144143{
    145         if (!pDir) {
    146                 errno = EINVAL;
    147                 return;
    148         }
    149 
    150         /* sanity check that this is a DIR pointer */
    151         if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
    152                 errno = EINVAL;
    153                 return;
    154         }
    155 
    156         /* close the WINDOWS32 directory handle */
    157         if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
    158                 if (!FindClose(pDir->dir_hDirHandle))
    159                         errno = EBADF;
    160 
    161         /* reset members which control readdir() */
    162         pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
    163         pDir->dir_nNumFiles = 0;
    164 
    165         return;
     144        if (!pDir) {
     145                errno = EINVAL;
     146                return;
     147        }
     148
     149        /* sanity check that this is a DIR pointer */
     150        if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
     151                errno = EINVAL;
     152                return;
     153        }
     154
     155        /* close the WINDOWS32 directory handle */
     156        if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
     157                if (!FindClose(pDir->dir_hDirHandle))
     158                        errno = EBADF;
     159
     160        /* reset members which control readdir() */
     161        pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
     162        pDir->dir_nNumFiles = 0;
     163
     164        return;
    166165}
    167166
     
    169168telldir(DIR* pDir)
    170169{
    171         if (!pDir) {
    172                 errno = EINVAL;
    173                 return -1;
    174         }
    175 
    176         /* sanity check that this is a DIR pointer */
    177         if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
    178                 errno = EINVAL;
    179                 return -1;
    180         }
    181 
    182         /* return number of times readdir() called */
    183         return pDir->dir_nNumFiles;
     170        if (!pDir) {
     171                errno = EINVAL;
     172                return -1;
     173        }
     174
     175        /* sanity check that this is a DIR pointer */
     176        if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
     177                errno = EINVAL;
     178                return -1;
     179        }
     180
     181        /* return number of times readdir() called */
     182        return pDir->dir_nNumFiles;
    184183}
    185184
     
    187186seekdir(DIR* pDir, long nPosition)
    188187{
    189         if (!pDir)
    190                 return;
    191 
    192         /* sanity check that this is a DIR pointer */
    193         if (pDir->dir_ulCookie != __DIRENT_COOKIE)
    194                 return;
    195 
    196         /* go back to beginning of directory */
    197         rewinddir(pDir);
    198 
    199         /* loop until we have found position we care about */
    200         for (--nPosition; nPosition && readdir(pDir); nPosition--);
    201 
    202         /* flag invalid nPosition value */
    203         if (nPosition)
    204                 errno = EINVAL;
    205 
    206         return;
    207 }
     188        if (!pDir)
     189                return;
     190
     191        /* sanity check that this is a DIR pointer */
     192        if (pDir->dir_ulCookie != __DIRENT_COOKIE)
     193                return;
     194
     195        /* go back to beginning of directory */
     196        rewinddir(pDir);
     197
     198        /* loop until we have found position we care about */
     199        for (--nPosition; nPosition && readdir(pDir); nPosition--);
     200
     201        /* flag invalid nPosition value */
     202        if (nPosition)
     203                errno = EINVAL;
     204
     205        return;
     206}
  • vendor/gnumake/current/w32/include/dirent.h

    r2596 r3138  
    11/* Windows version of dirent.h
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
    3 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
     
    3837struct dirent
    3938{
    40   ino_t d_ino;                  /* unused - no equivalent on WINDOWS32 */
     39  ino_t d_ino;                  /* unused - no equivalent on WINDOWS32 */
    4140  char d_name[NAME_MAX+1];
    4241};
    4342
    4443typedef struct dir_struct {
    45         ULONG   dir_ulCookie;
    46         HANDLE  dir_hDirHandle;
    47         DWORD   dir_nNumFiles;
    48         char    dir_pDirectoryName[NAME_MAX+1];
    49         struct dirent dir_sdReturn;
     44        ULONG   dir_ulCookie;
     45        HANDLE  dir_hDirHandle;
     46        DWORD   dir_nNumFiles;
     47        char    dir_pDirectoryName[NAME_MAX+1];
     48        struct dirent dir_sdReturn;
    5049} DIR;
    5150
  • vendor/gnumake/current/w32/include/pathstuff.h

    r2596 r3138  
    11/* Definitions for Windows path manipulation.
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
    3 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
  • vendor/gnumake/current/w32/include/sub_proc.h

    r2596 r3138  
    11/* Definitions for Windows process invocation.
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
     
    2221 * Component Name:
    2322 *
    24  * $Date: 2010/07/13 01:20:43 $
     23 * $Date$
    2524 *
    26  * $Source: /sources/make/make/w32/include/sub_proc.h,v $
     25 * $Source$
    2726 *
    28  * $Id: sub_proc.h,v 1.12 2010/07/13 01:20:43 psmith Exp $
     27 * $Id$
    2928 */
    3029
     
    3433EXTERN_DECL(HANDLE process_init, (VOID_DECL));
    3534EXTERN_DECL(HANDLE process_init_fd, (HANDLE stdinh, HANDLE stdouth,
    36         HANDLE stderrh));
     35                                     HANDLE stderrh));
    3736EXTERN_DECL(long process_begin, (HANDLE proc, char **argv, char **envp,
    38         char *exec_path, char *as_user));
     37                                 char *exec_path, char *as_user));
    3938EXTERN_DECL(long process_pipe_io, (HANDLE proc, char *stdin_data,
    40         int stdin_data_len));
     39                                   int stdin_data_len));
    4140EXTERN_DECL(long process_file_io, (HANDLE proc));
    4241EXTERN_DECL(void process_cleanup, (HANDLE proc));
    43 EXTERN_DECL(HANDLE process_wait_for_any, (VOID_DECL));
     42EXTERN_DECL(HANDLE process_wait_for_any, (int block, DWORD* pdwWaitStatus));
    4443EXTERN_DECL(void process_register, (HANDLE proc));
    45 EXTERN_DECL(HANDLE process_easy, (char** argv, char** env));
     44EXTERN_DECL(HANDLE process_easy, (char** argv, char** env,
     45                                  int outfd, int errfd));
    4646EXTERN_DECL(BOOL process_kill, (HANDLE proc, int signal));
    4747EXTERN_DECL(int process_used_slots, (VOID_DECL));
     48EXTERN_DECL(DWORD process_set_handles, (HANDLE *handles));
    4849
    4950/* support routines */
     
    5758EXTERN_DECL(int process_errcnt, (HANDLE proc));
    5859EXTERN_DECL(void process_pipes, (HANDLE proc, int pipes[3]));
     60EXTERN_DECL(void process_noinherit, (int fildes));
    5961
    6062#endif
  • vendor/gnumake/current/w32/include/w32err.h

    r2596 r3138  
    11/* Definitions for Windows error handling.
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
     
    2322#endif
    2423
    25 EXTERN_DECL(char * map_windows32_error_to_string, (DWORD error));
     24EXTERN_DECL(const char * map_windows32_error_to_string, (DWORD error));
    2625
    2726#endif /* !_W32ERR_H */
  • vendor/gnumake/current/w32/pathstuff.c

    r2596 r3138  
    11/* Path conversion for Windows pathnames.
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
    3 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
     
    1615this program.  If not, see <http://www.gnu.org/licenses/>.  */
    1716
    18 #include "make.h"
     17#include "makeint.h"
    1918#include <string.h>
    2019#include <stdlib.h>
     
    2928    char *etok;            /* token separator for old Path */
    3029
    31         /*
    32         * Convert all spaces to delimiters. Note that pathnames which
    33         * contain blanks get trounced here. Use 8.3 format as a workaround.
    34         */
    35         for (etok = Path; etok && *etok; etok++)
    36                 if (isblank ((unsigned char) *etok))
    37                         *etok = to_delim;
    38 
    39         return (convert_Path_to_windows32(Path, to_delim));
     30        /*
     31        * Convert all spaces to delimiters. Note that pathnames which
     32        * contain blanks get trounced here. Use 8.3 format as a workaround.
     33        */
     34        for (etok = Path; etok && *etok; etok++)
     35                if (ISBLANK ((unsigned char) *etok))
     36                        *etok = to_delim;
     37
     38        return (convert_Path_to_windows32(Path, to_delim));
    4039}
    4140
     
    8180                *etok = to_delim;
    8281                p = ++etok;
    83             } else
     82            } else
    8483                p += strlen(p);
    8584        } else {
     
    116115getcwd_fs(char* buf, int len)
    117116{
    118         char *p = getcwd(buf, len);
    119 
    120         if (p) {
    121                 char *q = w32ify(buf, 0);
    122                 strncpy(buf, q, len);
    123         }
    124 
    125         return p;
     117        char *p = getcwd(buf, len);
     118
     119        if (p) {
     120                char *q = w32ify(buf, 0);
     121                strncpy(buf, q, len);
     122        }
     123
     124        return p;
    126125}
    127126
  • vendor/gnumake/current/w32/subproc/NMakefile

    r2596 r3138  
    1 # NOTE: If you have no `make' program at all to process this makefile, run
    2 # `build.bat' instead.
     1# NOTE: If you have no 'make' program at all to process this makefile, run
     2# 'build.bat' instead.
    33#
    4 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    5 # 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     4# Copyright (C) 1996-2016 Free Software Foundation, Inc.
    65# This file is part of GNU Make.
    76#
  • vendor/gnumake/current/w32/subproc/misc.c

    r2596 r3138  
    11/* Process handling for Windows
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
     
    2625/*
    2726 * Description:  Convert a NULL string terminated UNIX environment block to
    28  *              an environment block suitable for a windows32 system call
     27 *              an environment block suitable for a windows32 system call
    2928 *
    3029 * Returns:  TRUE= success, FALSE=fail
    3130 *
    3231 * Notes/Dependencies:  the environment block is sorted in case-insensitive
    33  *      order, is double-null terminated, and is a char *, not a char **
     32 *      order, is double-null terminated, and is a char *, not a char **
    3433 */
    3534int _cdecl compare(const void *a1, const void *a2)
    3635{
    37         return _stricoll(*((char**)a1),*((char**)a2));
     36        return _stricoll(*((char**)a1),*((char**)a2));
    3837}
    3938bool_t
    40 arr2envblk(char **arr, char **envblk_out)
     39arr2envblk(char **arr, char **envblk_out, int *envsize_needed)
    4140{
    42         char **tmp;
    43         int size_needed;
    44         int arrcnt;
    45         char *ptr;
     41        char **tmp;
     42        int size_needed;
     43        int arrcnt;
     44        char *ptr;
    4645
    47         arrcnt = 0;
    48         while (arr[arrcnt]) {
    49                 arrcnt++;
    50         }
     46        arrcnt = 0;
     47        while (arr[arrcnt]) {
     48                arrcnt++;
     49        }
    5150
    52         tmp = (char**) calloc(arrcnt + 1, sizeof(char *));
    53         if (!tmp) {
    54                 return FALSE;
    55         }
     51        tmp = (char**) calloc(arrcnt + 1, sizeof(char *));
     52        if (!tmp) {
     53                return FALSE;
     54        }
    5655
    57         arrcnt = 0;
    58         size_needed = 0;
    59         while (arr[arrcnt]) {
    60                 tmp[arrcnt] = arr[arrcnt];
    61                 size_needed += strlen(arr[arrcnt]) + 1;
    62                 arrcnt++;
    63         }
    64         size_needed++;
     56        arrcnt = 0;
     57        size_needed = *envsize_needed = 0;
     58        while (arr[arrcnt]) {
     59                tmp[arrcnt] = arr[arrcnt];
     60                size_needed += strlen(arr[arrcnt]) + 1;
     61                arrcnt++;
     62        }
     63        size_needed++;
     64        *envsize_needed = size_needed;
    6565
    66         qsort((void *) tmp, (size_t) arrcnt, sizeof (char*), compare);
     66        qsort((void *) tmp, (size_t) arrcnt, sizeof (char*), compare);
    6767
    68         ptr = *envblk_out = calloc(size_needed, 1);
    69         if (!ptr) {
    70                 free(tmp);
    71                 return FALSE;
    72         }
     68        ptr = *envblk_out = calloc(size_needed, 1);
     69        if (!ptr) {
     70                free(tmp);
     71                return FALSE;
     72        }
    7373
    74         arrcnt = 0;
    75         while (tmp[arrcnt]) {
    76                 strcpy(ptr, tmp[arrcnt]);
    77                 ptr += strlen(tmp[arrcnt]) + 1;
    78                 arrcnt++;
    79         }
     74        arrcnt = 0;
     75        while (tmp[arrcnt]) {
     76                strcpy(ptr, tmp[arrcnt]);
     77                ptr += strlen(tmp[arrcnt]) + 1;
     78                arrcnt++;
     79        }
    8080
    81         free(tmp);
    82         return TRUE;
     81        free(tmp);
     82        return TRUE;
    8383}
  • vendor/gnumake/current/w32/subproc/proc.h

    r2596 r3138  
    11/* Definitions for Windows
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
     
    2120typedef int bool_t;
    2221
    23 #define E_SCALL         101
    24 #define E_IO            102
    25 #define E_NO_MEM        103
    26 #define E_FORK          104
     22#define E_SCALL         101
     23#define E_IO            102
     24#define E_NO_MEM        103
     25#define E_FORK          104
    2726
    28 extern bool_t arr2envblk(char **arr, char **envblk_out);
     27extern bool_t arr2envblk(char **arr, char **envblk_out, int *envsize_needed);
    2928
    3029#endif
  • vendor/gnumake/current/w32/subproc/sub_proc.c

    r2596 r3138  
    11/* Process handling for Windows.
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
     
    1918#include <stdlib.h>
    2019#include <stdio.h>
     20#include <io.h>         /* for _get_osfhandle */
    2121#ifdef _MSC_VER
    2222# include <stddef.h>    /* for intptr_t */
     
    2424# include <stdint.h>
    2525#endif
     26#include <string.h>
    2627#include <process.h>  /* for msvc _beginthreadex, _endthreadex */
    2728#include <signal.h>
    2829#include <windows.h>
    2930
     31#include "makeint.h"
     32#include "filedef.h"
     33#include "variable.h"
    3034#include "sub_proc.h"
    3135#include "proc.h"
     
    3438
    3539static char *make_command_line(char *shell_name, char *exec_path, char **argv);
    36 extern char *xmalloc (unsigned int);
    3740
    3841typedef struct sub_process_t {
    39         intptr_t sv_stdin[2];
    40         intptr_t sv_stdout[2];
    41         intptr_t sv_stderr[2];
    42         int using_pipes;
    43         char *inp;
    44         DWORD incnt;
    45         char * volatile outp;
    46         volatile DWORD outcnt;
    47         char * volatile errp;
    48         volatile DWORD errcnt;
    49         pid_t pid;
    50         int exit_code;
    51         int signal;
    52         long last_err;
    53         long lerrno;
     42        intptr_t sv_stdin[2];
     43        intptr_t sv_stdout[2];
     44        intptr_t sv_stderr[2];
     45        int using_pipes;
     46        char *inp;
     47        DWORD incnt;
     48        char * volatile outp;
     49        volatile DWORD outcnt;
     50        char * volatile errp;
     51        volatile DWORD errcnt;
     52        pid_t pid;
     53        int exit_code;
     54        int signal;
     55        long last_err;
     56        long lerrno;
    5457} sub_process;
    5558
     
    5861static int proc_index = 0;
    5962static int fake_exits_pending = 0;
     63
     64
     65/*
     66 * Fill a HANDLE list with handles to wait for.
     67 */
     68DWORD
     69process_set_handles(HANDLE *handles)
     70{
     71    DWORD count = 0;
     72    int i;
     73
     74    /* Build array of handles to wait for */
     75    for (i = 0; i < proc_index; i++) {
     76        /* Don't wait on child processes that have already finished */
     77        if (fake_exits_pending && proc_array[i]->exit_code)
     78            continue;
     79
     80        handles[count++] = (HANDLE) proc_array[i]->pid;
     81    }
     82
     83    return count;
     84}
    6085
    6186/*
     
    6691process_adjust_wait_state(sub_process* pproc)
    6792{
    68         int i;
    69 
    70         if (!proc_index)
    71                 return;
    72 
    73         for (i = 0; i < proc_index; i++)
    74                 if (proc_array[i]->pid == pproc->pid)
    75                         break;
    76 
    77         if (i < proc_index) {
    78                 proc_index--;
    79                 if (i != proc_index)
    80                         memmove(&proc_array[i], &proc_array[i+1],
    81                                 (proc_index-i) * sizeof(sub_process*));
    82                 proc_array[proc_index] = NULL;
    83         }
     93        int i;
     94
     95        if (!proc_index)
     96                return;
     97
     98        for (i = 0; i < proc_index; i++)
     99                if (proc_array[i]->pid == pproc->pid)
     100                        break;
     101
     102        if (i < proc_index) {
     103                proc_index--;
     104                if (i != proc_index)
     105                        memmove(&proc_array[i], &proc_array[i+1],
     106                                (proc_index-i) * sizeof(sub_process*));
     107                proc_array[proc_index] = NULL;
     108        }
    84109}
    85110
     
    88113 */
    89114static sub_process *
    90 process_wait_for_any_private(void)
    91 {
    92         HANDLE handles[MAXIMUM_WAIT_OBJECTS];
    93         DWORD retval, which;
    94         int i;
    95 
    96         if (!proc_index)
    97                 return NULL;
    98 
    99         /* build array of handles to wait for */
    100         for (i = 0; i < proc_index; i++) {
    101                 handles[i] = (HANDLE) proc_array[i]->pid;
    102 
    103                 if (fake_exits_pending && proc_array[i]->exit_code)
    104                         break;
    105         }
    106 
    107         /* wait for someone to exit */
    108         if (!fake_exits_pending) {
    109                 retval = WaitForMultipleObjects(proc_index, handles, FALSE, INFINITE);
    110                 which = retval - WAIT_OBJECT_0;
    111         } else {
    112                 fake_exits_pending--;
    113                 retval = !WAIT_FAILED;
    114                 which = i;
    115         }
    116 
    117         /* return pointer to process */
    118         if (retval != WAIT_FAILED) {
    119                 sub_process* pproc = proc_array[which];
    120                 process_adjust_wait_state(pproc);
    121                 return pproc;
    122         } else
    123                 return NULL;
     115process_wait_for_any_private(int block, DWORD* pdwWaitStatus)
     116{
     117        HANDLE handles[MAXIMUM_WAIT_OBJECTS];
     118        DWORD retval, which;
     119        int i;
     120
     121        if (!proc_index)
     122                return NULL;
     123
     124        /* build array of handles to wait for */
     125        for (i = 0; i < proc_index; i++) {
     126                handles[i] = (HANDLE) proc_array[i]->pid;
     127
     128                if (fake_exits_pending && proc_array[i]->exit_code)
     129                        break;
     130        }
     131
     132        /* wait for someone to exit */
     133        if (!fake_exits_pending) {
     134                retval = WaitForMultipleObjects(proc_index, handles, FALSE, (block ? INFINITE : 0));
     135                which = retval - WAIT_OBJECT_0;
     136        } else {
     137                fake_exits_pending--;
     138                retval = !WAIT_FAILED;
     139                which = i;
     140        }
     141
     142        /* If the pointer is not NULL, set the wait status result variable. */
     143        if (pdwWaitStatus)
     144            *pdwWaitStatus = retval;
     145
     146        /* return pointer to process */
     147        if ((retval == WAIT_TIMEOUT) || (retval == WAIT_FAILED)) {
     148                return NULL;
     149        }
     150        else {
     151                sub_process* pproc = proc_array[which];
     152                process_adjust_wait_state(pproc);
     153                return pproc;
     154        }
    124155}
    125156
     
    130161process_kill(HANDLE proc, int signal)
    131162{
    132         sub_process* pproc = (sub_process*) proc;
    133         pproc->signal = signal;
    134         return (TerminateProcess((HANDLE) pproc->pid, signal));
     163        sub_process* pproc = (sub_process*) proc;
     164        pproc->signal = signal;
     165        return (TerminateProcess((HANDLE) pproc->pid, signal));
    135166}
    136167
     
    144175process_register(HANDLE proc)
    145176{
    146         if (proc_index < MAXIMUM_WAIT_OBJECTS)
    147                 proc_array[proc_index++] = (sub_process *) proc;
     177        if (proc_index < MAXIMUM_WAIT_OBJECTS)
     178                proc_array[proc_index++] = (sub_process *) proc;
    148179}
    149180
     
    154185process_used_slots(void)
    155186{
    156         return proc_index;
     187        return proc_index;
    157188}
    158189
     
    162193 * you must do 1 of things:
    163194 *
    164  *      x = process_easy(...);
     195 *      x = process_easy(...);
    165196 *
    166197 * or
    167198 *
    168  *      x = process_init_fd();
    169  *      process_register(x);
     199 *      x = process_init_fd();
     200 *      process_register(x);
    170201 *
    171202 * or
    172203 *
    173  *      x = process_init();
    174  *      process_register(x);
     204 *      x = process_init();
     205 *      process_register(x);
    175206 *
    176207 * You must NOT then call process_pipe_io() because this function is
     
    180211
    181212HANDLE
    182 process_wait_for_any(void)
    183 {
    184         sub_process* pproc = process_wait_for_any_private();
    185 
    186         if (!pproc)
    187                 return NULL;
    188         else {
    189                 /*
    190                 * Ouch! can't tell caller if this fails directly. Caller
    191                 * will have to use process_last_err()
     213process_wait_for_any(int block, DWORD* pdwWaitStatus)
     214{
     215        sub_process* pproc = process_wait_for_any_private(block, pdwWaitStatus);
     216
     217        if (!pproc)
     218                return NULL;
     219        else {
     220                /*
     221                * Ouch! can't tell caller if this fails directly. Caller
     222                * will have to use process_last_err()
    192223                 */
    193                 (void) process_file_io(pproc);
    194                 return ((HANDLE) pproc);
    195         }
     224                (void) process_file_io(pproc);
     225                return ((HANDLE) pproc);
     226        }
    196227}
    197228
     
    207238{
    208239        if (proc == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
    209         return (((sub_process *)proc)->last_err);
     240        return (((sub_process *)proc)->last_err);
    210241}
    211242
     
    214245{
    215246        if (proc == INVALID_HANDLE_VALUE) return EXIT_FAILURE;
    216         return (((sub_process *)proc)->exit_code);
     247        return (((sub_process *)proc)->exit_code);
     248}
     249
     250void
     251process_noinherit(int fd)
     252{
     253  HANDLE fh = (HANDLE)_get_osfhandle(fd);
     254
     255  if (fh && fh != INVALID_HANDLE_VALUE)
     256        SetHandleInformation(fh, HANDLE_FLAG_INHERIT, 0);
    217257}
    218258
     
    227267process_outbuf(HANDLE proc)
    228268{
    229         return (((sub_process *)proc)->outp);
     269        return (((sub_process *)proc)->outp);
    230270}
    231271
     
    233273process_errbuf(HANDLE proc)
    234274{
    235         return (((sub_process *)proc)->errp);
     275        return (((sub_process *)proc)->errp);
    236276}
    237277
     
    239279process_outcnt(HANDLE proc)
    240280{
    241         return (((sub_process *)proc)->outcnt);
     281        return (((sub_process *)proc)->outcnt);
    242282}
    243283
     
    245285process_errcnt(HANDLE proc)
    246286{
    247         return (((sub_process *)proc)->errcnt);
     287        return (((sub_process *)proc)->errcnt);
    248288}
    249289
     
    251291process_pipes(HANDLE proc, int pipes[3])
    252292{
    253         pipes[0] = ((sub_process *)proc)->sv_stdin[0];
    254         pipes[1] = ((sub_process *)proc)->sv_stdout[0];
    255         pipes[2] = ((sub_process *)proc)->sv_stderr[0];
    256         return;
     293        pipes[0] = ((sub_process *)proc)->sv_stdin[0];
     294        pipes[1] = ((sub_process *)proc)->sv_stdout[0];
     295        pipes[2] = ((sub_process *)proc)->sv_stderr[0];
     296        return;
    257297}
    258298*/
    259299
    260         HANDLE
     300        HANDLE
    261301process_init()
    262302{
    263         sub_process *pproc;
    264         /*
    265         * open file descriptors for attaching stdin/stdout/sterr
    266         */
    267         HANDLE stdin_pipes[2];
    268         HANDLE stdout_pipes[2];
    269         HANDLE stderr_pipes[2];
    270         SECURITY_ATTRIBUTES inherit;
    271         BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
    272 
    273         pproc = malloc(sizeof(*pproc));
    274         memset(pproc, 0, sizeof(*pproc));
    275 
    276         /* We can't use NULL for lpSecurityDescriptor because that
    277            uses the default security descriptor of the calling process.
    278            Instead we use a security descriptor with no DACL.  This
    279            allows nonrestricted access to the associated objects. */
    280 
    281         if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd),
    282                                           SECURITY_DESCRIPTOR_REVISION)) {
    283                 pproc->last_err = GetLastError();
    284                 pproc->lerrno = E_SCALL;
    285                 return((HANDLE)pproc);
    286         }
    287 
    288         inherit.nLength = sizeof(inherit);
    289         inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd);
    290         inherit.bInheritHandle = TRUE;
    291 
    292         // By convention, parent gets pipe[0], and child gets pipe[1]
    293         // This means the READ side of stdin pipe goes into pipe[1]
    294         // and the WRITE side of the stdout and stderr pipes go into pipe[1]
    295         if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE ||
    296         CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE ||
    297         CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) {
    298 
    299                 pproc->last_err = GetLastError();
    300                 pproc->lerrno = E_SCALL;
    301                 return((HANDLE)pproc);
    302         }
    303 
    304         //
    305         // Mark the parent sides of the pipes as non-inheritable
    306         //
    307         if (SetHandleInformation(stdin_pipes[0],
    308                                 HANDLE_FLAG_INHERIT, 0) == FALSE ||
    309                 SetHandleInformation(stdout_pipes[0],
    310                                 HANDLE_FLAG_INHERIT, 0) == FALSE ||
    311                 SetHandleInformation(stderr_pipes[0],
    312                                 HANDLE_FLAG_INHERIT, 0) == FALSE) {
    313 
    314                 pproc->last_err = GetLastError();
    315                 pproc->lerrno = E_SCALL;
    316                 return((HANDLE)pproc);
    317         }
    318         pproc->sv_stdin[0]  = (intptr_t) stdin_pipes[0];
    319         pproc->sv_stdin[1]  = (intptr_t) stdin_pipes[1];
    320         pproc->sv_stdout[0] = (intptr_t) stdout_pipes[0];
    321         pproc->sv_stdout[1] = (intptr_t) stdout_pipes[1];
    322         pproc->sv_stderr[0] = (intptr_t) stderr_pipes[0];
    323         pproc->sv_stderr[1] = (intptr_t) stderr_pipes[1];
    324 
    325         pproc->using_pipes = 1;
    326 
    327         pproc->lerrno = 0;
    328 
    329         return((HANDLE)pproc);
    330 }
    331 
    332 
    333         HANDLE
     303        sub_process *pproc;
     304        /*
     305        * open file descriptors for attaching stdin/stdout/sterr
     306        */
     307        HANDLE stdin_pipes[2];
     308        HANDLE stdout_pipes[2];
     309        HANDLE stderr_pipes[2];
     310        SECURITY_ATTRIBUTES inherit;
     311        BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
     312
     313        pproc = malloc(sizeof(*pproc));
     314        memset(pproc, 0, sizeof(*pproc));
     315
     316        /* We can't use NULL for lpSecurityDescriptor because that
     317           uses the default security descriptor of the calling process.
     318           Instead we use a security descriptor with no DACL.  This
     319           allows nonrestricted access to the associated objects. */
     320
     321        if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd),
     322                                          SECURITY_DESCRIPTOR_REVISION)) {
     323                pproc->last_err = GetLastError();
     324                pproc->lerrno = E_SCALL;
     325                return((HANDLE)pproc);
     326        }
     327
     328        inherit.nLength = sizeof(inherit);
     329        inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd);
     330        inherit.bInheritHandle = TRUE;
     331
     332        // By convention, parent gets pipe[0], and child gets pipe[1]
     333        // This means the READ side of stdin pipe goes into pipe[1]
     334        // and the WRITE side of the stdout and stderr pipes go into pipe[1]
     335        if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE ||
     336        CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE ||
     337        CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) {
     338
     339                pproc->last_err = GetLastError();
     340                pproc->lerrno = E_SCALL;
     341                return((HANDLE)pproc);
     342        }
     343
     344        //
     345        // Mark the parent sides of the pipes as non-inheritable
     346        //
     347        if (SetHandleInformation(stdin_pipes[0],
     348                                HANDLE_FLAG_INHERIT, 0) == FALSE ||
     349                SetHandleInformation(stdout_pipes[0],
     350                                HANDLE_FLAG_INHERIT, 0) == FALSE ||
     351                SetHandleInformation(stderr_pipes[0],
     352                                HANDLE_FLAG_INHERIT, 0) == FALSE) {
     353
     354                pproc->last_err = GetLastError();
     355                pproc->lerrno = E_SCALL;
     356                return((HANDLE)pproc);
     357        }
     358        pproc->sv_stdin[0]  = (intptr_t) stdin_pipes[0];
     359        pproc->sv_stdin[1]  = (intptr_t) stdin_pipes[1];
     360        pproc->sv_stdout[0] = (intptr_t) stdout_pipes[0];
     361        pproc->sv_stdout[1] = (intptr_t) stdout_pipes[1];
     362        pproc->sv_stderr[0] = (intptr_t) stderr_pipes[0];
     363        pproc->sv_stderr[1] = (intptr_t) stderr_pipes[1];
     364
     365        pproc->using_pipes = 1;
     366
     367        pproc->lerrno = 0;
     368
     369        return((HANDLE)pproc);
     370}
     371
     372
     373        HANDLE
    334374process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh)
    335375{
    336         sub_process *pproc;
    337 
    338         pproc = malloc(sizeof(*pproc));
    339         memset(pproc, 0, sizeof(*pproc));
    340 
    341         /*
    342          * Just pass the provided file handles to the 'child side' of the
    343          * pipe, bypassing pipes altogether.
    344          */
    345         pproc->sv_stdin[1]  = (intptr_t) stdinh;
    346         pproc->sv_stdout[1] = (intptr_t) stdouth;
    347         pproc->sv_stderr[1] = (intptr_t) stderrh;
    348 
    349         pproc->last_err = pproc->lerrno = 0;
    350 
    351         return((HANDLE)pproc);
     376        sub_process *pproc;
     377
     378        pproc = malloc(sizeof(*pproc));
     379        if (pproc) {
     380                memset(pproc, 0, sizeof(*pproc));
     381
     382                /*
     383                 * Just pass the provided file handles to the 'child
     384                 * side' of the pipe, bypassing pipes altogether.
     385                 */
     386                pproc->sv_stdin[1]  = (intptr_t) stdinh;
     387                pproc->sv_stdout[1] = (intptr_t) stdouth;
     388                pproc->sv_stderr[1] = (intptr_t) stderrh;
     389
     390                pproc->last_err = pproc->lerrno = 0;
     391        }
     392
     393        return((HANDLE)pproc);
    352394}
    353395
     
    355397static HANDLE
    356398find_file(const char *exec_path, const char *path_var,
    357           char *full_fname, DWORD full_len)
    358 {
    359         HANDLE exec_handle;
    360         char *fname;
    361         char *ext;
    362         DWORD req_len;
    363         int i;
    364         static const char *extensions[] =
    365           /* Should .com come before no-extension case?  */
    366           { ".exe", ".cmd", ".bat", "", ".com", NULL };
    367 
    368         fname = xmalloc(strlen(exec_path) + 5);
    369         strcpy(fname, exec_path);
    370         ext = fname + strlen(fname);
    371 
    372         for (i = 0; extensions[i]; i++) {
    373                 strcpy(ext, extensions[i]);
    374                 if (((req_len = SearchPath (path_var, fname, NULL, full_len,
    375                                             full_fname, NULL)) > 0
    376                      /* For compatibility with previous code, which
    377                         used OpenFile, and with Windows operation in
    378                         general, also look in various default
    379                         locations, such as Windows directory and
    380                         Windows System directory.  Warning: this also
    381                         searches PATH in the Make's environment, which
    382                         might not be what the Makefile wants, but it
    383                         seems to be OK as a fallback, after the
    384                         previous SearchPath failed to find on child's
    385                         PATH.  */
    386                      || (req_len = SearchPath (NULL, fname, NULL, full_len,
    387                                                full_fname, NULL)) > 0)
    388                     && req_len <= full_len
    389                     && (exec_handle =
    390                                 CreateFile(full_fname,
    391                                            GENERIC_READ,
    392                                            FILE_SHARE_READ | FILE_SHARE_WRITE,
    393                                            NULL,
    394                                            OPEN_EXISTING,
    395                                            FILE_ATTRIBUTE_NORMAL,
    396                                            NULL)) != INVALID_HANDLE_VALUE) {
    397                         free(fname);
    398                         return(exec_handle);
    399                 }
    400         }
    401 
    402         free(fname);
    403         return INVALID_HANDLE_VALUE;
     399          char *full_fname, DWORD full_len)
     400{
     401        HANDLE exec_handle;
     402        char *fname;
     403        char *ext;
     404        DWORD req_len;
     405        int i;
     406        static const char *extensions[] =
     407          /* Should .com come before no-extension case?  */
     408          { ".exe", ".cmd", ".bat", "", ".com", NULL };
     409
     410        fname = xmalloc(strlen(exec_path) + 5);
     411        strcpy(fname, exec_path);
     412        ext = fname + strlen(fname);
     413
     414        for (i = 0; extensions[i]; i++) {
     415                strcpy(ext, extensions[i]);
     416                if (((req_len = SearchPath (path_var, fname, NULL, full_len,
     417                                            full_fname, NULL)) > 0
     418                     /* For compatibility with previous code, which
     419                        used OpenFile, and with Windows operation in
     420                        general, also look in various default
     421                        locations, such as Windows directory and
     422                        Windows System directory.  Warning: this also
     423                        searches PATH in the Make's environment, which
     424                        might not be what the Makefile wants, but it
     425                        seems to be OK as a fallback, after the
     426                        previous SearchPath failed to find on child's
     427                        PATH.  */
     428                     || (req_len = SearchPath (NULL, fname, NULL, full_len,
     429                                               full_fname, NULL)) > 0)
     430                    && req_len <= full_len
     431                    && (exec_handle =
     432                                CreateFile(full_fname,
     433                                           GENERIC_READ,
     434                                           FILE_SHARE_READ | FILE_SHARE_WRITE,
     435                                           NULL,
     436                                           OPEN_EXISTING,
     437                                           FILE_ATTRIBUTE_NORMAL,
     438                                           NULL)) != INVALID_HANDLE_VALUE) {
     439                        free(fname);
     440                        return(exec_handle);
     441                }
     442        }
     443
     444        free(fname);
     445        return INVALID_HANDLE_VALUE;
     446}
     447
     448/*
     449 * Return non-zero of FNAME specifies a batch file and its name
     450 * includes embedded whitespace.
     451 */
     452
     453static int
     454batch_file_with_spaces(const char *fname)
     455{
     456        size_t fnlen = strlen(fname);
     457
     458        return (fnlen > 4
     459                && (_strnicmp(fname + fnlen - 4, ".bat", 4) == 0
     460                    || _strnicmp(fname + fnlen - 4, ".cmd", 4) == 0)
     461                /* The set of characters in the 2nd arg to strpbrk
     462                   should be the same one used by make_command_line
     463                   below to decide whether an argv[] element needs
     464                   quoting.  */
     465                && strpbrk(fname, " \t") != NULL);
    404466}
    405467
     
    414476long
    415477process_begin(
    416         HANDLE proc,
    417         char **argv,
    418         char **envp,
    419         char *exec_path,
    420         char *as_user)
    421 {
    422         sub_process *pproc = (sub_process *)proc;
    423         char *shell_name = 0;
    424         int file_not_found=0;
    425         HANDLE exec_handle;
    426         char exec_fname[MAX_PATH];
    427         const char *path_var = NULL;
    428         char **ep;
    429         char buf[256];
    430         DWORD bytes_returned;
    431         DWORD flags;
    432         char *command_line;
    433         STARTUPINFO startInfo;
    434         PROCESS_INFORMATION procInfo;
    435         char *envblk=NULL;
    436 
    437         /*
    438          *  Shell script detection...  if the exec_path starts with #! then
    439          *  we want to exec shell-script-name exec-path, not just exec-path
    440          *  NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl.  We do not
    441          *  hard-code the path to the shell or perl or whatever:  Instead, we
    442          *  assume it's in the path somewhere (generally, the NT tools
    443          *  bin directory)
    444          */
    445 
    446         /* Use the Makefile's value of PATH to look for the program to
    447            execute, because it could be different from Make's PATH
    448            (e.g., if the target sets its own value.  */
    449         if (envp)
    450                 for (ep = envp; *ep; ep++) {
    451                         if (strncmp (*ep, "PATH=", 5) == 0
    452                             || strncmp (*ep, "Path=", 5) == 0) {
    453                                 path_var = *ep + 5;
    454                                 break;
    455                         }
    456                 }
    457         exec_handle = find_file(exec_path, path_var,
    458                                 exec_fname, sizeof(exec_fname));
    459 
    460         /*
    461          * If we couldn't open the file, just assume that Windows will be
    462          * somehow able to find and execute it.
    463          */
    464         if (exec_handle == INVALID_HANDLE_VALUE) {
    465                 file_not_found++;
    466         }
    467         else {
    468                 /* Attempt to read the first line of the file */
    469                 if (ReadFile( exec_handle,
    470                                 buf, sizeof(buf) - 1, /* leave room for trailing NULL */
    471                                 &bytes_returned, 0) == FALSE || bytes_returned < 2) {
    472 
    473                         pproc->last_err = GetLastError();
    474                         pproc->lerrno = E_IO;
    475                         CloseHandle(exec_handle);
    476                         return(-1);
    477                 }
    478                 if (buf[0] == '#' && buf[1] == '!') {
    479                         /*
    480                          *  This is a shell script...  Change the command line from
    481                          *      exec_path args to shell_name exec_path args
    482                          */
    483                         char *p;
    484 
    485                         /*  Make sure buf is NULL terminated */
    486                         buf[bytes_returned] = 0;
    487                         /*
    488                          * Depending on the file system type, etc. the first line
    489                          * of the shell script may end with newline or newline-carriage-return
    490                          * Whatever it ends with, cut it off.
    491                          */
    492                         p= strchr(buf, '\n');
    493                         if (p)
    494                                 *p = 0;
    495                         p = strchr(buf, '\r');
    496                         if (p)
    497                                 *p = 0;
    498 
    499                         /*
    500                          *  Find base name of shell
    501                          */
    502                         shell_name = strrchr( buf, '/');
    503                         if (shell_name) {
    504                                 shell_name++;
    505                         } else {
    506                                 shell_name = &buf[2];/* skipping "#!" */
    507                         }
    508 
    509                 }
    510                 CloseHandle(exec_handle);
    511         }
    512 
    513         flags = 0;
    514 
    515         if (file_not_found)
    516                 command_line = make_command_line( shell_name, exec_path, argv);
    517         else
    518                 command_line = make_command_line( shell_name, exec_fname, argv);
    519 
    520         if ( command_line == NULL ) {
    521                 pproc->last_err = 0;
    522                 pproc->lerrno = E_NO_MEM;
    523                 return(-1);
    524         }
    525 
    526         if (envp) {
    527                 if (arr2envblk(envp, &envblk) ==FALSE) {
    528                         pproc->last_err = 0;
    529                         pproc->lerrno = E_NO_MEM;
    530                         free( command_line );
    531                         return(-1);
    532                 }
    533         }
    534 
    535         if ((shell_name) || (file_not_found)) {
    536                 exec_path = 0;  /* Search for the program in %Path% */
    537         } else {
    538                 exec_path = exec_fname;
    539         }
    540 
    541         /*
    542          *  Set up inherited stdin, stdout, stderr for child
    543          */
    544         GetStartupInfo(&startInfo);
    545         startInfo.dwFlags = STARTF_USESTDHANDLES;
    546         startInfo.lpReserved = 0;
    547         startInfo.cbReserved2 = 0;
    548         startInfo.lpReserved2 = 0;
    549         startInfo.lpTitle = shell_name ? shell_name : exec_path;
    550         startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];
    551         startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];
    552         startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];
    553 
    554         if (as_user) {
    555                 if (envblk) free(envblk);
    556                 return -1;
    557         } else {
    558                 DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n",
    559                         exec_path ? exec_path : "NULL",
    560                         command_line ? command_line : "NULL"));
    561                 if (CreateProcess(
    562                         exec_path,
    563                         command_line,
    564                         NULL,
    565                         0, /* default security attributes for thread */
    566                         TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */
    567                         flags,
    568                         envblk,
    569                         0, /* default starting directory */
    570                         &startInfo,
    571                         &procInfo) == FALSE) {
    572 
    573                         pproc->last_err = GetLastError();
    574                         pproc->lerrno = E_FORK;
    575                         fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
     478        HANDLE proc,
     479        char **argv,
     480        char **envp,
     481        char *exec_path,
     482        char *as_user)
     483{
     484        sub_process *pproc = (sub_process *)proc;
     485        char *shell_name = 0;
     486        int file_not_found=0;
     487        HANDLE exec_handle;
     488        char exec_fname[MAX_PATH];
     489        const char *path_var = NULL;
     490        char **ep;
     491        char buf[MAX_PATH];
     492        DWORD bytes_returned;
     493        DWORD flags;
     494        char *command_line;
     495        STARTUPINFO startInfo;
     496        PROCESS_INFORMATION procInfo;
     497        char *envblk=NULL;
     498        int envsize_needed = 0;
     499        int pass_null_exec_path = 0;
     500
     501        /*
     502         *  Shell script detection...  if the exec_path starts with #! then
     503         *  we want to exec shell-script-name exec-path, not just exec-path
     504         *  NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl.  We do not
     505         *  hard-code the path to the shell or perl or whatever:  Instead, we
     506         *  assume it's in the path somewhere (generally, the NT tools
     507         *  bin directory)
     508         */
     509
     510        /* Use the Makefile's value of PATH to look for the program to
     511           execute, because it could be different from Make's PATH
     512           (e.g., if the target sets its own value.  */
     513        if (envp)
     514                for (ep = envp; *ep; ep++) {
     515                        if (strncmp (*ep, "PATH=", 5) == 0
     516                            || strncmp (*ep, "Path=", 5) == 0) {
     517                                path_var = *ep + 5;
     518                                break;
     519                        }
     520                }
     521        exec_handle = find_file(exec_path, path_var,
     522                                exec_fname, sizeof(exec_fname));
     523
     524        /*
     525         * If we couldn't open the file, just assume that Windows will be
     526         * somehow able to find and execute it.  If the first character
     527         * of the command is '/', assume they set SHELL to a Unixy shell
     528         * that have some magic mounts known only to it, and run the whole
     529         * command via $SHELL -c "COMMAND" instead.
     530         */
     531        if (exec_handle == INVALID_HANDLE_VALUE) {
     532                if (exec_path[0] == '/') {
     533                        char *new_argv0;
     534                        char **argvi = argv;
     535                        int arglen = 0;
     536
     537                        strcpy(buf, variable_expand ("$(SHELL)"));
     538                        shell_name = &buf[0];
     539                        strcpy(exec_fname, "-c");
     540                        /* Construct a single command string in argv[0].  */
     541                        while (*argvi) {
     542                                arglen += strlen(*argvi) + 1;
     543                                argvi++;
     544                        }
     545                        new_argv0 = xmalloc(arglen + 1);
     546                        new_argv0[0] = '\0';
     547                        for (argvi = argv; *argvi; argvi++) {
     548                                strcat(new_argv0, *argvi);
     549                                strcat(new_argv0, " ");
     550                        }
     551                        /* Remove the extra blank at the end.  */
     552                        new_argv0[arglen-1] = '\0';
     553                        free(argv[0]);
     554                        argv[0] = new_argv0;
     555                        argv[1] = NULL;
     556                }
     557                else
     558                        file_not_found++;
     559        }
     560        else {
     561                /* Attempt to read the first line of the file */
     562                if (ReadFile( exec_handle,
     563                                buf, sizeof(buf) - 1, /* leave room for trailing NULL */
     564                                &bytes_returned, 0) == FALSE || bytes_returned < 2) {
     565
     566                        pproc->last_err = GetLastError();
     567                        pproc->lerrno = E_IO;
     568                        CloseHandle(exec_handle);
     569                        return(-1);
     570                }
     571                if (buf[0] == '#' && buf[1] == '!') {
     572                        /*
     573                         *  This is a shell script...  Change the command line from
     574                         *      exec_path args to shell_name exec_path args
     575                         */
     576                        char *p;
     577
     578                        /*  Make sure buf is NULL terminated */
     579                        buf[bytes_returned] = 0;
     580                        /*
     581                         * Depending on the file system type, etc. the first line
     582                         * of the shell script may end with newline or newline-carriage-return
     583                         * Whatever it ends with, cut it off.
     584                         */
     585                        p= strchr(buf, '\n');
     586                        if (p)
     587                                *p = 0;
     588                        p = strchr(buf, '\r');
     589                        if (p)
     590                                *p = 0;
     591
     592                        /*
     593                         *  Find base name of shell
     594                         */
     595                        shell_name = strrchr( buf, '/');
     596                        if (shell_name) {
     597                                shell_name++;
     598                        } else {
     599                                shell_name = &buf[2];/* skipping "#!" */
     600                        }
     601
     602                }
     603                CloseHandle(exec_handle);
     604        }
     605
     606        flags = 0;
     607
     608        if (file_not_found)
     609                command_line = make_command_line( shell_name, exec_path, argv);
     610        else {
     611                /* If exec_fname includes whitespace, CreateProcess
     612                   behaves erratically and unreliably, and often fails
     613                   if argv[0] also includes whitespace (and thus will
     614                   be quoted by make_command_line below).  So in that
     615                   case, we don't pass exec_fname as the 1st arg to
     616                   CreateProcess, but instead replace argv[0] with
     617                   exec_fname (to keep its leading directories and
     618                   extension as found by find_file), and pass NULL to
     619                   CreateProcess as its 1st arg.  This works around
     620                   the bugs in CreateProcess, which are probably
     621                   caused by its passing the command to cmd.exe with
     622                   some incorrect quoting.  */
     623                if (!shell_name
     624                    && batch_file_with_spaces(exec_fname)
     625                    && _stricmp(exec_path, argv[0]) == 0) {
     626                        char *new_argv, *p;
     627                        char **argvi;
     628                        int arglen, i;
     629                        pass_null_exec_path = 1;
     630                        /* Rewrite argv[] replacing argv[0] with exec_fname.  */
     631                        for (argvi = argv + 1, arglen = strlen(exec_fname) + 1;
     632                             *argvi;
     633                             argvi++) {
     634                                arglen += strlen(*argvi) + 1;
     635                        }
     636                        new_argv = xmalloc(arglen);
     637                        p = strcpy(new_argv, exec_fname) + strlen(exec_fname) + 1;
     638                        for (argvi = argv + 1, i = 1; *argvi; argvi++, i++) {
     639                                strcpy(p, *argvi);
     640                                argv[i] = p;
     641                                p += strlen(*argvi) + 1;
     642                        }
     643                        argv[i] = NULL;
     644                        free (argv[0]);
     645                        argv[0] = new_argv;
     646                }
     647                command_line = make_command_line( shell_name, exec_fname, argv);
     648        }
     649
     650        if ( command_line == NULL ) {
     651                pproc->last_err = 0;
     652                pproc->lerrno = E_NO_MEM;
     653                return(-1);
     654        }
     655
     656        if (envp) {
     657                if (arr2envblk(envp, &envblk, &envsize_needed) == FALSE) {
     658                        pproc->lerrno = E_NO_MEM;
     659                        free( command_line );
     660                        if ((pproc->last_err == ERROR_INVALID_PARAMETER
     661                             || pproc->last_err == ERROR_MORE_DATA)
     662                            && envsize_needed > 32*1024) {
     663                                fprintf (stderr, "CreateProcess failed, probably because environment is too large (%d bytes).\n",
     664                                         envsize_needed);
     665                        }
     666                        pproc->last_err = 0;
     667                        return(-1);
     668                }
     669        }
     670
     671        if (shell_name || file_not_found || pass_null_exec_path) {
     672                exec_path = 0;  /* Search for the program in %Path% */
     673        } else {
     674                exec_path = exec_fname;
     675        }
     676
     677        /*
     678         *  Set up inherited stdin, stdout, stderr for child
     679         */
     680        memset(&startInfo, '\0', sizeof(startInfo));
     681        GetStartupInfo(&startInfo);
     682        startInfo.dwFlags = STARTF_USESTDHANDLES;
     683        startInfo.lpReserved = 0;
     684        startInfo.cbReserved2 = 0;
     685        startInfo.lpReserved2 = 0;
     686        startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];
     687        startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];
     688        startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];
     689
     690        if (as_user) {
     691                free(envblk);
     692                return -1;
     693        } else {
     694                DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n",
     695                        exec_path ? exec_path : "NULL",
     696                        command_line ? command_line : "NULL"));
     697                if (CreateProcess(
     698                        exec_path,
     699                        command_line,
     700                        NULL,
     701                        0, /* default security attributes for thread */
     702                        TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */
     703                        flags,
     704                        envblk,
     705                        0, /* default starting directory */
     706                        &startInfo,
     707                        &procInfo) == FALSE) {
     708
     709                        pproc->last_err = GetLastError();
     710                        pproc->lerrno = E_FORK;
     711                        fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
    576712                                exec_path ? exec_path : "NULL", command_line);
    577                         if (envblk) free(envblk);
    578                         free( command_line );
    579                         return(-1);
    580                 }
    581         }
    582 
    583         pproc->pid = (pid_t)procInfo.hProcess;
    584         /* Close the thread handle -- we'll just watch the process */
    585         CloseHandle(procInfo.hThread);
    586 
    587         /* Close the halves of the pipes we don't need */
    588         CloseHandle((HANDLE)pproc->sv_stdin[1]);
    589         CloseHandle((HANDLE)pproc->sv_stdout[1]);
    590         CloseHandle((HANDLE)pproc->sv_stderr[1]);
     713                        free(envblk);
     714                        free( command_line );
     715                        return(-1);
     716                }
     717        }
     718
     719        pproc->pid = (pid_t)procInfo.hProcess;
     720        /* Close the thread handle -- we'll just watch the process */
     721        CloseHandle(procInfo.hThread);
     722
     723        /* Close the halves of the pipes we don't need */
     724        if ((HANDLE)pproc->sv_stdin[1] != INVALID_HANDLE_VALUE)
     725          CloseHandle((HANDLE)pproc->sv_stdin[1]);
     726        if ((HANDLE)pproc->sv_stdout[1] != INVALID_HANDLE_VALUE)
     727          CloseHandle((HANDLE)pproc->sv_stdout[1]);
     728        if ((HANDLE)pproc->sv_stderr[1] != INVALID_HANDLE_VALUE)
     729          CloseHandle((HANDLE)pproc->sv_stderr[1]);
    591730        pproc->sv_stdin[1] = 0;
    592731        pproc->sv_stdout[1] = 0;
    593732        pproc->sv_stderr[1] = 0;
    594733
    595         free( command_line );
    596         if (envblk) free(envblk);
    597         pproc->lerrno=0;
    598         return 0;
    599 }
    600 
    601 
    602 
     734        free( command_line );
     735        free(envblk);
     736        pproc->lerrno=0;
     737        return 0;
     738}
     739
     740
     741
     742#if 0   /* unused */
    603743static DWORD
    604744proc_stdin_thread(sub_process *pproc)
    605745{
    606         DWORD in_done;
    607         for (;;) {
    608                 if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt,
    609                                         &in_done, NULL) == FALSE)
    610                         _endthreadex(0);
    611                 // This if should never be true for anonymous pipes, but gives
    612                 // us a chance to change I/O mechanisms later
    613                 if (in_done < pproc->incnt) {
    614                         pproc->incnt -= in_done;
    615                         pproc->inp += in_done;
    616                 } else {
    617                         _endthreadex(0);
    618                 }
    619         }
    620         return 0; // for compiler warnings only.. not reached
     746        DWORD in_done;
     747        for (;;) {
     748                if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt,
     749                                        &in_done, NULL) == FALSE)
     750                        _endthreadex(0);
     751                // This if should never be true for anonymous pipes, but gives
     752                // us a chance to change I/O mechanisms later
     753                if (in_done < pproc->incnt) {
     754                        pproc->incnt -= in_done;
     755                        pproc->inp += in_done;
     756                } else {
     757                        _endthreadex(0);
     758                }
     759        }
     760        return 0; // for compiler warnings only.. not reached
    621761}
    622762
     
    624764proc_stdout_thread(sub_process *pproc)
    625765{
    626         DWORD bufsize = 1024;
    627         char c;
    628         DWORD nread;
    629         pproc->outp = malloc(bufsize);
    630         if (pproc->outp == NULL)
    631                 _endthreadex(0);
    632         pproc->outcnt = 0;
    633 
    634         for (;;) {
    635                 if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL)
    636                                         == FALSE) {
    637 /*                      map_windows32_error_to_string(GetLastError());*/
    638                         _endthreadex(0);
    639                 }
    640                 if (nread == 0)
    641                         _endthreadex(0);
    642                 if (pproc->outcnt + nread > bufsize) {
    643                         bufsize += nread + 512;
    644                         pproc->outp = realloc(pproc->outp, bufsize);
    645                         if (pproc->outp == NULL) {
    646                                 pproc->outcnt = 0;
    647                                 _endthreadex(0);
    648                         }
    649                 }
    650                 pproc->outp[pproc->outcnt++] = c;
    651         }
    652         return 0;
     766        DWORD bufsize = 1024;
     767        char c;
     768        DWORD nread;
     769        pproc->outp = malloc(bufsize);
     770        if (pproc->outp == NULL)
     771                _endthreadex(0);
     772        pproc->outcnt = 0;
     773
     774        for (;;) {
     775                if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL)
     776                                        == FALSE) {
     777/*                      map_windows32_error_to_string(GetLastError());*/
     778                        _endthreadex(0);
     779                }
     780                if (nread == 0)
     781                        _endthreadex(0);
     782                if (pproc->outcnt + nread > bufsize) {
     783                        bufsize += nread + 512;
     784                        pproc->outp = realloc(pproc->outp, bufsize);
     785                        if (pproc->outp == NULL) {
     786                                pproc->outcnt = 0;
     787                                _endthreadex(0);
     788                        }
     789                }
     790                pproc->outp[pproc->outcnt++] = c;
     791        }
     792        return 0;
    653793}
    654794
     
    656796proc_stderr_thread(sub_process *pproc)
    657797{
    658         DWORD bufsize = 1024;
    659         char c;
    660         DWORD nread;
    661         pproc->errp = malloc(bufsize);
    662         if (pproc->errp == NULL)
    663                 _endthreadex(0);
    664         pproc->errcnt = 0;
    665 
    666         for (;;) {
    667                 if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) {
    668                         map_windows32_error_to_string(GetLastError());
    669                         _endthreadex(0);
    670                 }
    671                 if (nread == 0)
    672                         _endthreadex(0);
    673                 if (pproc->errcnt + nread > bufsize) {
    674                         bufsize += nread + 512;
    675                         pproc->errp = realloc(pproc->errp, bufsize);
    676                         if (pproc->errp == NULL) {
    677                                 pproc->errcnt = 0;
    678                                 _endthreadex(0);
    679                         }
    680                 }
    681                 pproc->errp[pproc->errcnt++] = c;
    682         }
    683         return 0;
     798        DWORD bufsize = 1024;
     799        char c;
     800        DWORD nread;
     801        pproc->errp = malloc(bufsize);
     802        if (pproc->errp == NULL)
     803                _endthreadex(0);
     804        pproc->errcnt = 0;
     805
     806        for (;;) {
     807                if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) {
     808                        map_windows32_error_to_string(GetLastError());
     809                        _endthreadex(0);
     810                }
     811                if (nread == 0)
     812                        _endthreadex(0);
     813                if (pproc->errcnt + nread > bufsize) {
     814                        bufsize += nread + 512;
     815                        pproc->errp = realloc(pproc->errp, bufsize);
     816                        if (pproc->errp == NULL) {
     817                                pproc->errcnt = 0;
     818                                _endthreadex(0);
     819                        }
     820                }
     821                pproc->errp[pproc->errcnt++] = c;
     822        }
     823        return 0;
    684824}
    685825
     
    694834 * Notes/Dependencies:
    695835 */
    696         long
     836        long
    697837process_pipe_io(
    698         HANDLE proc,
    699         char *stdin_data,
    700         int stdin_data_len)
    701 {
    702         sub_process *pproc = (sub_process *)proc;
    703         bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE;
    704         HANDLE childhand = (HANDLE) pproc->pid;
    705         HANDLE tStdin = NULL, tStdout = NULL, tStderr = NULL;
    706         unsigned int dwStdin, dwStdout, dwStderr;
    707         HANDLE wait_list[4];
    708         DWORD wait_count;
    709         DWORD wait_return;
    710         HANDLE ready_hand;
    711         bool_t child_dead = FALSE;
    712         BOOL GetExitCodeResult;
    713 
    714         /*
    715         *  Create stdin thread, if needed
    716         */
    717         pproc->inp = stdin_data;
    718         pproc->incnt = stdin_data_len;
    719         if (!pproc->inp) {
    720                 stdin_eof = TRUE;
    721                 CloseHandle((HANDLE)pproc->sv_stdin[0]);
    722                 pproc->sv_stdin[0] = 0;
    723         } else {
    724                 tStdin = (HANDLE) _beginthreadex( 0, 1024,
    725                         (unsigned (__stdcall *) (void *))proc_stdin_thread,
    726                                                   pproc, 0, &dwStdin);
    727                 if (tStdin == 0) {
    728                         pproc->last_err = GetLastError();
    729                         pproc->lerrno = E_SCALL;
    730                         goto done;
    731                 }
    732         }
    733 
    734         /*
    735         *   Assume child will produce stdout and stderr
    736         */
    737         tStdout = (HANDLE) _beginthreadex( 0, 1024,
    738                 (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0,
    739                 &dwStdout);
    740         tStderr = (HANDLE) _beginthreadex( 0, 1024,
    741                 (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0,
    742                 &dwStderr);
    743 
    744         if (tStdout == 0 || tStderr == 0) {
    745 
    746                 pproc->last_err = GetLastError();
    747                 pproc->lerrno = E_SCALL;
    748                 goto done;
    749         }
    750 
    751 
    752         /*
    753         *  Wait for all I/O to finish and for the child process to exit
    754         */
    755 
    756         while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) {
    757                 wait_count = 0;
    758                 if (!stdin_eof) {
    759                         wait_list[wait_count++] = tStdin;
    760                 }
    761                 if (!stdout_eof) {
    762                         wait_list[wait_count++] = tStdout;
    763                 }
    764                 if (!stderr_eof) {
    765                         wait_list[wait_count++] = tStderr;
    766                 }
    767                 if (!child_dead) {
    768                         wait_list[wait_count++] = childhand;
    769                 }
    770 
    771                 wait_return = WaitForMultipleObjects(wait_count, wait_list,
    772                         FALSE, /* don't wait for all: one ready will do */
    773                         child_dead? 1000 :INFINITE); /* after the child dies, subthreads have
    774                                 one second to collect all remaining output */
    775 
    776                 if (wait_return == WAIT_FAILED) {
    777 /*                      map_windows32_error_to_string(GetLastError());*/
    778                         pproc->last_err = GetLastError();
    779                         pproc->lerrno = E_SCALL;
    780                         goto done;
    781                 }
    782 
    783                 ready_hand = wait_list[wait_return - WAIT_OBJECT_0];
    784 
    785                 if (ready_hand == tStdin) {
    786                         CloseHandle((HANDLE)pproc->sv_stdin[0]);
    787                         pproc->sv_stdin[0] = 0;
    788                         CloseHandle(tStdin);
    789                         tStdin = 0;
    790                         stdin_eof = TRUE;
    791 
    792                 } else if (ready_hand == tStdout) {
    793 
    794                         CloseHandle((HANDLE)pproc->sv_stdout[0]);
    795                         pproc->sv_stdout[0] = 0;
    796                         CloseHandle(tStdout);
    797                         tStdout = 0;
    798                         stdout_eof = TRUE;
    799 
    800                 } else if (ready_hand == tStderr) {
    801 
    802                         CloseHandle((HANDLE)pproc->sv_stderr[0]);
    803                         pproc->sv_stderr[0] = 0;
    804                         CloseHandle(tStderr);
    805                         tStderr = 0;
    806                         stderr_eof = TRUE;
    807 
    808                 } else if (ready_hand == childhand) {
    809 
    810                         DWORD ierr;
    811                         GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
    812                         if (ierr == CONTROL_C_EXIT) {
    813                                 pproc->signal = SIGINT;
    814                         } else {
    815                                 pproc->exit_code = ierr;
    816                         }
    817                         if (GetExitCodeResult == FALSE) {
    818                                 pproc->last_err = GetLastError();
    819                                 pproc->lerrno = E_SCALL;
    820                                 goto done;
    821                         }
    822                         child_dead = TRUE;
    823 
    824                 } else {
    825 
    826                         /* ?? Got back a handle we didn't query ?? */
    827                         pproc->last_err = 0;
    828                         pproc->lerrno = E_FAIL;
    829                         goto done;
    830                 }
    831         }
     838        HANDLE proc,
     839        char *stdin_data,
     840        int stdin_data_len)
     841{
     842        sub_process *pproc = (sub_process *)proc;
     843        bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE;
     844        HANDLE childhand = (HANDLE) pproc->pid;
     845        HANDLE tStdin = NULL, tStdout = NULL, tStderr = NULL;
     846        unsigned int dwStdin, dwStdout, dwStderr;
     847        HANDLE wait_list[4];
     848        DWORD wait_count;
     849        DWORD wait_return;
     850        HANDLE ready_hand;
     851        bool_t child_dead = FALSE;
     852        BOOL GetExitCodeResult;
     853
     854        /*
     855        *  Create stdin thread, if needed
     856        */
     857        pproc->inp = stdin_data;
     858        pproc->incnt = stdin_data_len;
     859        if (!pproc->inp) {
     860                stdin_eof = TRUE;
     861                CloseHandle((HANDLE)pproc->sv_stdin[0]);
     862                pproc->sv_stdin[0] = 0;
     863        } else {
     864                tStdin = (HANDLE) _beginthreadex( 0, 1024,
     865                        (unsigned (__stdcall *) (void *))proc_stdin_thread,
     866                                                  pproc, 0, &dwStdin);
     867                if (tStdin == 0) {
     868                        pproc->last_err = GetLastError();
     869                        pproc->lerrno = E_SCALL;
     870                        goto done;
     871                }
     872        }
     873
     874        /*
     875        *   Assume child will produce stdout and stderr
     876        */
     877        tStdout = (HANDLE) _beginthreadex( 0, 1024,
     878                (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0,
     879                &dwStdout);
     880        tStderr = (HANDLE) _beginthreadex( 0, 1024,
     881                (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0,
     882                &dwStderr);
     883
     884        if (tStdout == 0 || tStderr == 0) {
     885
     886                pproc->last_err = GetLastError();
     887                pproc->lerrno = E_SCALL;
     888                goto done;
     889        }
     890
     891
     892        /*
     893        *  Wait for all I/O to finish and for the child process to exit
     894        */
     895
     896        while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) {
     897                wait_count = 0;
     898                if (!stdin_eof) {
     899                        wait_list[wait_count++] = tStdin;
     900                }
     901                if (!stdout_eof) {
     902                        wait_list[wait_count++] = tStdout;
     903                }
     904                if (!stderr_eof) {
     905                        wait_list[wait_count++] = tStderr;
     906                }
     907                if (!child_dead) {
     908                        wait_list[wait_count++] = childhand;
     909                }
     910
     911                wait_return = WaitForMultipleObjects(wait_count, wait_list,
     912                        FALSE, /* don't wait for all: one ready will do */
     913                        child_dead? 1000 :INFINITE); /* after the child dies, subthreads have
     914                                one second to collect all remaining output */
     915
     916                if (wait_return == WAIT_FAILED) {
     917/*                      map_windows32_error_to_string(GetLastError());*/
     918                        pproc->last_err = GetLastError();
     919                        pproc->lerrno = E_SCALL;
     920                        goto done;
     921                }
     922
     923                ready_hand = wait_list[wait_return - WAIT_OBJECT_0];
     924
     925                if (ready_hand == tStdin) {
     926                        CloseHandle((HANDLE)pproc->sv_stdin[0]);
     927                        pproc->sv_stdin[0] = 0;
     928                        CloseHandle(tStdin);
     929                        tStdin = 0;
     930                        stdin_eof = TRUE;
     931
     932                } else if (ready_hand == tStdout) {
     933
     934                        CloseHandle((HANDLE)pproc->sv_stdout[0]);
     935                        pproc->sv_stdout[0] = 0;
     936                        CloseHandle(tStdout);
     937                        tStdout = 0;
     938                        stdout_eof = TRUE;
     939
     940                } else if (ready_hand == tStderr) {
     941
     942                        CloseHandle((HANDLE)pproc->sv_stderr[0]);
     943                        pproc->sv_stderr[0] = 0;
     944                        CloseHandle(tStderr);
     945                        tStderr = 0;
     946                        stderr_eof = TRUE;
     947
     948                } else if (ready_hand == childhand) {
     949
     950                        DWORD ierr;
     951                        GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
     952                        if (ierr == CONTROL_C_EXIT) {
     953                                pproc->signal = SIGINT;
     954                        } else {
     955                                pproc->exit_code = ierr;
     956                        }
     957                        if (GetExitCodeResult == FALSE) {
     958                                pproc->last_err = GetLastError();
     959                                pproc->lerrno = E_SCALL;
     960                                goto done;
     961                        }
     962                        child_dead = TRUE;
     963
     964                } else {
     965
     966                        /* ?? Got back a handle we didn't query ?? */
     967                        pproc->last_err = 0;
     968                        pproc->lerrno = E_FAIL;
     969                        goto done;
     970                }
     971        }
    832972
    833973 done:
    834         if (tStdin != 0)
    835                 CloseHandle(tStdin);
    836         if (tStdout != 0)
    837                 CloseHandle(tStdout);
    838         if (tStderr != 0)
    839                 CloseHandle(tStderr);
    840 
    841         if (pproc->lerrno)
    842                 return(-1);
    843         else
    844                 return(0);
    845 
    846 }
     974        if (tStdin != 0)
     975                CloseHandle(tStdin);
     976        if (tStdout != 0)
     977                CloseHandle(tStdout);
     978        if (tStderr != 0)
     979                CloseHandle(tStderr);
     980
     981        if (pproc->lerrno)
     982                return(-1);
     983        else
     984                return(0);
     985
     986}
     987#endif  /* unused */
    847988
    848989/*
     
    855996 * Notes/Dependencies:
    856997 */
    857         long
     998        long
    858999process_file_io(
    859         HANDLE proc)
    860 {
    861         sub_process *pproc;
    862         HANDLE childhand;
    863         DWORD wait_return;
    864         BOOL GetExitCodeResult;
     1000        HANDLE proc)
     1001{
     1002        sub_process *pproc;
     1003        HANDLE childhand;
     1004        DWORD wait_return;
     1005        BOOL GetExitCodeResult;
    8651006        DWORD ierr;
    8661007
    867         if (proc == NULL)
    868                 pproc = process_wait_for_any_private();
    869         else
    870                 pproc = (sub_process *)proc;
    871 
    872         /* some sort of internal error */
    873         if (!pproc)
    874                 return -1;
    875 
    876         childhand = (HANDLE) pproc->pid;
    877 
    878         /*
    879         * This function is poorly named, and could also be used just to wait
    880         * for child death if you're doing your own pipe I/O.  If that is
    881         * the case, close the pipe handles here.
    882         */
    883         if (pproc->sv_stdin[0]) {
    884                 CloseHandle((HANDLE)pproc->sv_stdin[0]);
    885                 pproc->sv_stdin[0] = 0;
    886         }
    887         if (pproc->sv_stdout[0]) {
    888                 CloseHandle((HANDLE)pproc->sv_stdout[0]);
    889                 pproc->sv_stdout[0] = 0;
    890         }
    891         if (pproc->sv_stderr[0]) {
    892                 CloseHandle((HANDLE)pproc->sv_stderr[0]);
    893                 pproc->sv_stderr[0] = 0;
    894         }
    895 
    896         /*
    897         *  Wait for the child process to exit
    898         */
    899 
    900         wait_return = WaitForSingleObject(childhand, INFINITE);
    901 
    902         if (wait_return != WAIT_OBJECT_0) {
    903 /*              map_windows32_error_to_string(GetLastError());*/
    904                 pproc->last_err = GetLastError();
    905                 pproc->lerrno = E_SCALL;
    906                 goto done2;
    907         }
    908 
    909         GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
    910         if (ierr == CONTROL_C_EXIT) {
    911                 pproc->signal = SIGINT;
    912         } else {
    913                 pproc->exit_code = ierr;
    914         }
    915         if (GetExitCodeResult == FALSE) {
    916                 pproc->last_err = GetLastError();
    917                 pproc->lerrno = E_SCALL;
    918         }
     1008        if (proc == NULL)
     1009                pproc = process_wait_for_any_private(1, 0);
     1010        else
     1011                pproc = (sub_process *)proc;
     1012
     1013        /* some sort of internal error */
     1014        if (!pproc)
     1015                return -1;
     1016
     1017        childhand = (HANDLE) pproc->pid;
     1018
     1019        /*
     1020        * This function is poorly named, and could also be used just to wait
     1021        * for child death if you're doing your own pipe I/O.  If that is
     1022        * the case, close the pipe handles here.
     1023        */
     1024        if (pproc->sv_stdin[0]) {
     1025                CloseHandle((HANDLE)pproc->sv_stdin[0]);
     1026                pproc->sv_stdin[0] = 0;
     1027        }
     1028        if (pproc->sv_stdout[0]) {
     1029                CloseHandle((HANDLE)pproc->sv_stdout[0]);
     1030                pproc->sv_stdout[0] = 0;
     1031        }
     1032        if (pproc->sv_stderr[0]) {
     1033                CloseHandle((HANDLE)pproc->sv_stderr[0]);
     1034                pproc->sv_stderr[0] = 0;
     1035        }
     1036
     1037        /*
     1038        *  Wait for the child process to exit
     1039        */
     1040
     1041        wait_return = WaitForSingleObject(childhand, INFINITE);
     1042
     1043        if (wait_return != WAIT_OBJECT_0) {
     1044/*              map_windows32_error_to_string(GetLastError());*/
     1045                pproc->last_err = GetLastError();
     1046                pproc->lerrno = E_SCALL;
     1047                goto done2;
     1048        }
     1049
     1050        GetExitCodeResult = GetExitCodeProcess(childhand, &ierr);
     1051        if (ierr == CONTROL_C_EXIT) {
     1052                pproc->signal = SIGINT;
     1053        } else {
     1054                pproc->exit_code = ierr;
     1055        }
     1056        if (GetExitCodeResult == FALSE) {
     1057                pproc->last_err = GetLastError();
     1058                pproc->lerrno = E_SCALL;
     1059        }
    9191060
    9201061done2:
    921         if (pproc->lerrno)
    922                 return(-1);
    923         else
    924                 return(0);
     1062        if (pproc->lerrno)
     1063                return(-1);
     1064        else
     1065                return(0);
    9251066
    9261067}
     
    9281069/*
    9291070 * Description:  Clean up any leftover handles, etc.  It is up to the
    930  * caller to manage and free the input, ouput, and stderr buffers.
     1071 * caller to manage and free the input, output, and stderr buffers.
    9311072 */
    932         void
     1073        void
    9331074process_cleanup(
    934         HANDLE proc)
    935 {
    936         sub_process *pproc = (sub_process *)proc;
    937         int i;
    938 
    939         if (pproc->using_pipes) {
    940                 for (i= 0; i <= 1; i++) {
    941                         if ((HANDLE)pproc->sv_stdin[i])
    942                                 CloseHandle((HANDLE)pproc->sv_stdin[i]);
    943                         if ((HANDLE)pproc->sv_stdout[i])
    944                                 CloseHandle((HANDLE)pproc->sv_stdout[i]);
    945                         if ((HANDLE)pproc->sv_stderr[i])
    946                                 CloseHandle((HANDLE)pproc->sv_stderr[i]);
    947                 }
    948         }
    949         if ((HANDLE)pproc->pid)
    950                 CloseHandle((HANDLE)pproc->pid);
    951 
    952         free(pproc);
     1075        HANDLE proc)
     1076{
     1077        sub_process *pproc = (sub_process *)proc;
     1078        int i;
     1079
     1080        if (pproc->using_pipes) {
     1081                for (i= 0; i <= 1; i++) {
     1082                        if ((HANDLE)pproc->sv_stdin[i]
     1083                            && (HANDLE)pproc->sv_stdin[i] != INVALID_HANDLE_VALUE)
     1084                                CloseHandle((HANDLE)pproc->sv_stdin[i]);
     1085                        if ((HANDLE)pproc->sv_stdout[i]
     1086                            && (HANDLE)pproc->sv_stdout[i] != INVALID_HANDLE_VALUE)
     1087                                CloseHandle((HANDLE)pproc->sv_stdout[i]);
     1088                        if ((HANDLE)pproc->sv_stderr[i]
     1089                            && (HANDLE)pproc->sv_stderr[i] != INVALID_HANDLE_VALUE)
     1090                                CloseHandle((HANDLE)pproc->sv_stderr[i]);
     1091                }
     1092        }
     1093        if ((HANDLE)pproc->pid)
     1094                CloseHandle((HANDLE)pproc->pid);
     1095
     1096        free(pproc);
    9531097}
    9541098
     
    9561100/*
    9571101 * Description:
    958  *      Create a command line buffer to pass to CreateProcess
     1102 *      Create a command line buffer to pass to CreateProcess
    9591103 *
    9601104 * Returns:  the buffer or NULL for failure
    961  *      Shell case:  sh_name a:/full/path/to/script argv[1] argv[2] ...
     1105 *      Shell case:  sh_name a:/full/path/to/script argv[1] argv[2] ...
    9621106 *  Otherwise:   argv[0] argv[1] argv[2] ...
    9631107 *
     
    9701114make_command_line( char *shell_name, char *full_exec_path, char **argv)
    9711115{
    972         int             argc = 0;
    973         char**          argvi;
    974         int*            enclose_in_quotes = NULL;
    975         int*            enclose_in_quotes_i;
    976         unsigned int    bytes_required = 0;
    977         char*           command_line;
    978         char*           command_line_i;
    979         int  cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */
    980         int have_sh = 0; /* HAVE_CYGWIN_SHELL */
     1116        int             argc = 0;
     1117        char**          argvi;
     1118        int*            enclose_in_quotes = NULL;
     1119        int*            enclose_in_quotes_i;
     1120        unsigned int    bytes_required = 0;
     1121        char*           command_line;
     1122        char*           command_line_i;
     1123        int  cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */
     1124        int have_sh = 0; /* HAVE_CYGWIN_SHELL */
    9811125
    9821126#ifdef HAVE_CYGWIN_SHELL
    983         have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe"));
    984         cygwin_mode = 1;
     1127        have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe"));
     1128        cygwin_mode = 1;
    9851129#endif
    9861130
    987         if (shell_name && full_exec_path) {
    988                 bytes_required
    989                   = strlen(shell_name) + 1 + strlen(full_exec_path);
    990                 /*
    991                  * Skip argv[0] if any, when shell_name is given.
    992                  */
    993                 if (*argv) argv++;
    994                 /*
    995                  * Add one for the intervening space.
    996                  */
    997                 if (*argv) bytes_required++;
    998         }
    999 
    1000         argvi = argv;
    1001         while (*(argvi++)) argc++;
    1002 
    1003         if (argc) {
    1004                 enclose_in_quotes = (int*) calloc(1, argc * sizeof(int));
    1005 
    1006                 if (!enclose_in_quotes) {
    1007                         return NULL;
    1008                 }
    1009         }
    1010 
    1011         /* We have to make one pass through each argv[i] to see if we need
    1012          * to enclose it in ", so we might as well figure out how much
    1013          * memory we'll need on the same pass.
    1014          */
    1015 
    1016         argvi = argv;
    1017         enclose_in_quotes_i = enclose_in_quotes;
    1018         while(*argvi) {
    1019                 char* p = *argvi;
    1020                 unsigned int backslash_count = 0;
    1021 
    1022                 /*
    1023                  * We have to enclose empty arguments in ".
    1024                  */
    1025                 if (!(*p)) *enclose_in_quotes_i = 1;
    1026 
    1027                 while(*p) {
    1028                         switch (*p) {
    1029                         case '\"':
    1030                                 /*
    1031                                  * We have to insert a backslash for each "
    1032                                  * and each \ that precedes the ".
    1033                                  */
    1034                                 bytes_required += (backslash_count + 1);
    1035                                 backslash_count = 0;
    1036                                 break;
     1131        if (shell_name && full_exec_path) {
     1132                bytes_required
     1133                  = strlen(shell_name) + 1 + strlen(full_exec_path);
     1134                /*
     1135                 * Skip argv[0] if any, when shell_name is given.
     1136                 * The special case of "-c" in full_exec_path means
     1137                 * argv[0] is not the shell name, but the command string
     1138                 * to pass to the shell.
     1139                 */
     1140                if (*argv && strcmp(full_exec_path, "-c")) argv++;
     1141                /*
     1142                 * Add one for the intervening space.
     1143                 */
     1144                if (*argv) bytes_required++;
     1145        }
     1146
     1147        argvi = argv;
     1148        while (*(argvi++)) argc++;
     1149
     1150        if (argc) {
     1151                enclose_in_quotes = (int*) calloc(1, argc * sizeof(int));
     1152
     1153                if (!enclose_in_quotes) {
     1154                        return NULL;
     1155                }
     1156        }
     1157
     1158        /* We have to make one pass through each argv[i] to see if we need
     1159         * to enclose it in ", so we might as well figure out how much
     1160         * memory we'll need on the same pass.
     1161         */
     1162
     1163        argvi = argv;
     1164        enclose_in_quotes_i = enclose_in_quotes;
     1165        while(*argvi) {
     1166                char* p = *argvi;
     1167                unsigned int backslash_count = 0;
     1168
     1169                /*
     1170                 * We have to enclose empty arguments in ".
     1171                 */
     1172                if (!(*p)) *enclose_in_quotes_i = 1;
     1173
     1174                while(*p) {
     1175                        switch (*p) {
     1176                        case '\"':
     1177                                /*
     1178                                 * We have to insert a backslash for each "
     1179                                 * and each \ that precedes the ".
     1180                                 */
     1181                                bytes_required += (backslash_count + 1);
     1182                                backslash_count = 0;
     1183                                break;
    10371184
    10381185#if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
    1039                         case '\\':
    1040                                 backslash_count++;
    1041                                 break;
     1186                        case '\\':
     1187                                backslash_count++;
     1188                                break;
    10421189#endif
    1043         /*
    1044         * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress
    1045         * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so
    1046         * that argv in always equals argv out. This was removed.  Say you have
    1047         * such a program named glob.exe.  You enter
    1048         * glob '*'
    1049         * at the sh command prompt.  Obviously the intent is to make glob do the
    1050         * wildcarding instead of sh.  If we set *enclose_in_quotes_i for '*' or '?',
    1051         * then the command line that glob would see would be
    1052         * glob "*"
    1053         * and the _setargv in SETARGV.OBJ would _not_ expand the *.
    1054         */
    1055                         case ' ':
    1056                         case '\t':
    1057                                 *enclose_in_quotes_i = 1;
    1058                                 /* fall through */
    1059 
    1060                         default:
    1061                                 backslash_count = 0;
    1062                                 break;
    1063                         }
    1064 
    1065                         /*
    1066                         * Add one for each character in argv[i].
    1067                         */
    1068                         bytes_required++;
    1069 
    1070                         p++;
    1071                 }
    1072 
    1073                 if (*enclose_in_quotes_i) {
    1074                         /*
    1075                         * Add one for each enclosing ",
    1076                         * and one for each \ that precedes the
    1077                         * closing ".
    1078                         */
    1079                         bytes_required += (backslash_count + 2);
    1080                 }
    1081 
    1082                 /*
    1083                 * Add one for the intervening space.
    1084                 */
    1085                 if (*(++argvi)) bytes_required++;
    1086                 enclose_in_quotes_i++;
    1087         }
    1088 
    1089         /*
    1090         * Add one for the terminating NULL.
    1091         */
    1092         bytes_required++;
    1093 
    1094         command_line = (char*) malloc(bytes_required);
    1095 
    1096         if (!command_line) {
    1097                 if (enclose_in_quotes) free(enclose_in_quotes);
    1098                 return NULL;
    1099         }
    1100 
    1101         command_line_i = command_line;
    1102 
    1103         if (shell_name && full_exec_path) {
    1104                 while(*shell_name) {
    1105                         *(command_line_i++) = *(shell_name++);
    1106                 }
    1107 
    1108                 *(command_line_i++) = ' ';
    1109 
    1110                 while(*full_exec_path) {
    1111                         *(command_line_i++) = *(full_exec_path++);
    1112                 }
    1113 
    1114                 if (*argv) {
    1115                         *(command_line_i++) = ' ';
    1116                 }
    1117         }
    1118 
    1119         argvi = argv;
    1120         enclose_in_quotes_i = enclose_in_quotes;
    1121 
    1122         while(*argvi) {
    1123                 char* p = *argvi;
    1124                 unsigned int backslash_count = 0;
    1125 
    1126                 if (*enclose_in_quotes_i) {
    1127                         *(command_line_i++) = '\"';
    1128                 }
    1129 
    1130                 while(*p) {
    1131                         if (*p == '\"') {
    1132                                 if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */
    1133                                         /* instead of a \", cygwin likes "" */
    1134                                         *(command_line_i++) = '\"';
    1135                                 } else {
    1136 
    1137                                 /*
    1138                                 * We have to insert a backslash for the "
    1139                                 * and each \ that precedes the ".
    1140                                 */
    1141                                 backslash_count++;
    1142 
    1143                                 while(backslash_count) {
    1144                                         *(command_line_i++) = '\\';
    1145                                         backslash_count--;
    1146                                 };
    1147                                 }
     1190        /*
     1191        * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress
     1192        * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so
     1193        * that argv in always equals argv out. This was removed.  Say you have
     1194        * such a program named glob.exe.  You enter
     1195        * glob '*'
     1196        * at the sh command prompt.  Obviously the intent is to make glob do the
     1197        * wildcarding instead of sh.  If we set *enclose_in_quotes_i for '*' or '?',
     1198        * then the command line that glob would see would be
     1199        * glob "*"
     1200        * and the _setargv in SETARGV.OBJ would _not_ expand the *.
     1201        */
     1202                        case ' ':
     1203                        case '\t':
     1204                                *enclose_in_quotes_i = 1;
     1205                                /* fall through */
     1206
     1207                        default:
     1208                                backslash_count = 0;
     1209                                break;
     1210                        }
     1211
     1212                        /*
     1213                        * Add one for each character in argv[i].
     1214                        */
     1215                        bytes_required++;
     1216
     1217                        p++;
     1218                }
     1219
     1220                if (*enclose_in_quotes_i) {
     1221                        /*
     1222                        * Add one for each enclosing ",
     1223                        * and one for each \ that precedes the
     1224                        * closing ".
     1225                        */
     1226                        bytes_required += (backslash_count + 2);
     1227                }
     1228
     1229                /*
     1230                * Add one for the intervening space.
     1231                */
     1232                if (*(++argvi)) bytes_required++;
     1233                enclose_in_quotes_i++;
     1234        }
     1235
     1236        /*
     1237        * Add one for the terminating NULL.
     1238        */
     1239        bytes_required++;
     1240
     1241        command_line = (char*) malloc(bytes_required);
     1242
     1243        if (!command_line) {
     1244                free(enclose_in_quotes);
     1245                return NULL;
     1246        }
     1247
     1248        command_line_i = command_line;
     1249
     1250        if (shell_name && full_exec_path) {
     1251                while(*shell_name) {
     1252                        *(command_line_i++) = *(shell_name++);
     1253                }
     1254
     1255                *(command_line_i++) = ' ';
     1256
     1257                while(*full_exec_path) {
     1258                        *(command_line_i++) = *(full_exec_path++);
     1259                }
     1260
     1261                if (*argv) {
     1262                        *(command_line_i++) = ' ';
     1263                }
     1264        }
     1265
     1266        argvi = argv;
     1267        enclose_in_quotes_i = enclose_in_quotes;
     1268
     1269        while(*argvi) {
     1270                char* p = *argvi;
     1271                unsigned int backslash_count = 0;
     1272
     1273                if (*enclose_in_quotes_i) {
     1274                        *(command_line_i++) = '\"';
     1275                }
     1276
     1277                while(*p) {
     1278                        if (*p == '\"') {
     1279                                if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */
     1280                                        /* instead of a \", cygwin likes "" */
     1281                                        *(command_line_i++) = '\"';
     1282                                } else {
     1283
     1284                                /*
     1285                                * We have to insert a backslash for the "
     1286                                * and each \ that precedes the ".
     1287                                */
     1288                                backslash_count++;
     1289
     1290                                while(backslash_count) {
     1291                                        *(command_line_i++) = '\\';
     1292                                        backslash_count--;
     1293                                };
     1294                                }
    11481295#if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
    1149                         } else if (*p == '\\') {
    1150                                 backslash_count++;
    1151                         } else {
    1152                                 backslash_count = 0;
     1296                        } else if (*p == '\\') {
     1297                                backslash_count++;
     1298                        } else {
     1299                                backslash_count = 0;
    11531300#endif
    1154                         }
    1155 
    1156                         /*
    1157                         * Copy the character.
    1158                         */
    1159                         *(command_line_i++) = *(p++);
    1160                 }
    1161 
    1162                 if (*enclose_in_quotes_i) {
     1301                        }
     1302
     1303                        /*
     1304                        * Copy the character.
     1305                        */
     1306                        *(command_line_i++) = *(p++);
     1307                }
     1308
     1309                if (*enclose_in_quotes_i) {
    11631310#if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL)
    1164                         /*
    1165                         * Add one \ for each \ that precedes the
    1166                         * closing ".
    1167                         */
    1168                         while(backslash_count--) {
    1169                                 *(command_line_i++) = '\\';
    1170                         };
     1311                        /*
     1312                        * Add one \ for each \ that precedes the
     1313                        * closing ".
     1314                        */
     1315                        while(backslash_count--) {
     1316                                *(command_line_i++) = '\\';
     1317                        };
    11711318#endif
    1172                         *(command_line_i++) = '\"';
    1173                 }
    1174 
    1175                 /*
    1176                 * Append an intervening space.
    1177                 */
    1178                 if (*(++argvi)) {
    1179                         *(command_line_i++) = ' ';
    1180                 }
    1181 
    1182                 enclose_in_quotes_i++;
    1183         }
    1184 
    1185         /*
    1186         * Append the terminating NULL.
    1187         */
    1188         *command_line_i = '\0';
    1189 
    1190         if (enclose_in_quotes) free(enclose_in_quotes);
    1191         return command_line;
     1319                        *(command_line_i++) = '\"';
     1320                }
     1321
     1322                /*
     1323                * Append an intervening space.
     1324                */
     1325                if (*(++argvi)) {
     1326                        *(command_line_i++) = ' ';
     1327                }
     1328
     1329                enclose_in_quotes_i++;
     1330        }
     1331
     1332        /*
     1333        * Append the terminating NULL.
     1334        */
     1335        *command_line_i = '\0';
     1336
     1337        free(enclose_in_quotes);
     1338        return command_line;
    11921339}
    11931340
     
    11961343 *              using the default stdin, stdout, and stderr handles.
    11971344 *              Also, register process so that process_wait_for_any_private()
    1198  *              can be used via process_file_io(NULL) or
    1199  *              process_wait_for_any().
     1345 *              can be used via process_file_io(NULL) or
     1346 *              process_wait_for_any().
    12001347 *
    12011348 * Returns:
     
    12051352HANDLE
    12061353process_easy(
    1207         char **argv,
    1208         char **envp)
    1209 {
    1210   HANDLE hIn;
    1211   HANDLE hOut;
    1212   HANDLE hErr;
    1213   HANDLE hProcess;
     1354        char **argv,
     1355        char **envp,
     1356        int outfd,
     1357        int errfd)
     1358{
     1359  HANDLE hIn = INVALID_HANDLE_VALUE;
     1360  HANDLE hOut = INVALID_HANDLE_VALUE;
     1361  HANDLE hErr = INVALID_HANDLE_VALUE;
     1362  HANDLE hProcess, tmpIn, tmpOut, tmpErr;
     1363  DWORD e;
    12141364
    12151365  if (proc_index >= MAXIMUM_WAIT_OBJECTS) {
    1216         DB (DB_JOBS, ("process_easy: All process slots used up\n"));
    1217         return INVALID_HANDLE_VALUE;
     1366        DB (DB_JOBS, ("process_easy: All process slots used up\n"));
     1367        return INVALID_HANDLE_VALUE;
    12181368  }
     1369  /* Standard handles returned by GetStdHandle can be NULL or
     1370     INVALID_HANDLE_VALUE if the parent process closed them.  If that
     1371     happens, we open the null device and pass its handle to
     1372     CreateProcess as the corresponding handle to inherit.  */
     1373  tmpIn = GetStdHandle(STD_INPUT_HANDLE);
    12191374  if (DuplicateHandle(GetCurrentProcess(),
    1220                       GetStdHandle(STD_INPUT_HANDLE),
     1375                      tmpIn,
    12211376                      GetCurrentProcess(),
    12221377                      &hIn,
     
    12241379                      TRUE,
    12251380                      DUPLICATE_SAME_ACCESS) == FALSE) {
    1226     fprintf(stderr,
    1227             "process_easy: DuplicateHandle(In) failed (e=%ld)\n",
    1228             GetLastError());
    1229     return INVALID_HANDLE_VALUE;
     1381    if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
     1382      tmpIn = CreateFile("NUL", GENERIC_READ,
     1383                         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
     1384                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     1385      if (tmpIn != INVALID_HANDLE_VALUE
     1386          && DuplicateHandle(GetCurrentProcess(),
     1387                             tmpIn,
     1388                             GetCurrentProcess(),
     1389                             &hIn,
     1390                             0,
     1391                             TRUE,
     1392                             DUPLICATE_SAME_ACCESS) == FALSE)
     1393        CloseHandle(tmpIn);
     1394    }
     1395    if (hIn == INVALID_HANDLE_VALUE) {
     1396      fprintf(stderr, "process_easy: DuplicateHandle(In) failed (e=%ld)\n", e);
     1397      return INVALID_HANDLE_VALUE;
     1398    }
    12301399  }
     1400  if (outfd >= 0)
     1401    tmpOut = (HANDLE)_get_osfhandle (outfd);
     1402  else
     1403    tmpOut = GetStdHandle (STD_OUTPUT_HANDLE);
    12311404  if (DuplicateHandle(GetCurrentProcess(),
    1232                       GetStdHandle(STD_OUTPUT_HANDLE),
     1405                      tmpOut,
    12331406                      GetCurrentProcess(),
    12341407                      &hOut,
     
    12361409                      TRUE,
    12371410                      DUPLICATE_SAME_ACCESS) == FALSE) {
    1238     fprintf(stderr,
    1239            "process_easy: DuplicateHandle(Out) failed (e=%ld)\n",
    1240            GetLastError());
    1241     return INVALID_HANDLE_VALUE;
     1411    if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
     1412      tmpOut = CreateFile("NUL", GENERIC_WRITE,
     1413                          FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
     1414                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     1415      if (tmpOut != INVALID_HANDLE_VALUE
     1416          && DuplicateHandle(GetCurrentProcess(),
     1417                             tmpOut,
     1418                             GetCurrentProcess(),
     1419                             &hOut,
     1420                             0,
     1421                             TRUE,
     1422                             DUPLICATE_SAME_ACCESS) == FALSE)
     1423        CloseHandle(tmpOut);
     1424    }
     1425    if (hOut == INVALID_HANDLE_VALUE) {
     1426      fprintf(stderr, "process_easy: DuplicateHandle(Out) failed (e=%ld)\n", e);
     1427      return INVALID_HANDLE_VALUE;
     1428    }
    12421429  }
     1430  if (errfd >= 0)
     1431    tmpErr = (HANDLE)_get_osfhandle (errfd);
     1432  else
     1433    tmpErr = GetStdHandle(STD_ERROR_HANDLE);
    12431434  if (DuplicateHandle(GetCurrentProcess(),
    1244                       GetStdHandle(STD_ERROR_HANDLE),
     1435                      tmpErr,
    12451436                      GetCurrentProcess(),
    12461437                      &hErr,
     
    12481439                      TRUE,
    12491440                      DUPLICATE_SAME_ACCESS) == FALSE) {
    1250     fprintf(stderr,
    1251             "process_easy: DuplicateHandle(Err) failed (e=%ld)\n",
    1252             GetLastError());
    1253     return INVALID_HANDLE_VALUE;
     1441    if ((e = GetLastError()) == ERROR_INVALID_HANDLE) {
     1442      tmpErr = CreateFile("NUL", GENERIC_WRITE,
     1443                          FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
     1444                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     1445      if (tmpErr != INVALID_HANDLE_VALUE
     1446          && DuplicateHandle(GetCurrentProcess(),
     1447                             tmpErr,
     1448                             GetCurrentProcess(),
     1449                             &hErr,
     1450                             0,
     1451                             TRUE,
     1452                             DUPLICATE_SAME_ACCESS) == FALSE)
     1453        CloseHandle(tmpErr);
     1454    }
     1455    if (hErr == INVALID_HANDLE_VALUE) {
     1456      fprintf(stderr, "process_easy: DuplicateHandle(Err) failed (e=%ld)\n", e);
     1457      return INVALID_HANDLE_VALUE;
     1458    }
    12541459  }
    12551460
     
    12641469
    12651470    /* close up unused handles */
    1266     CloseHandle(hIn);
    1267     CloseHandle(hOut);
    1268     CloseHandle(hErr);
     1471    if (hIn != INVALID_HANDLE_VALUE)
     1472      CloseHandle(hIn);
     1473    if (hOut != INVALID_HANDLE_VALUE)
     1474      CloseHandle(hOut);
     1475    if (hErr != INVALID_HANDLE_VALUE)
     1476      CloseHandle(hErr);
    12691477  }
    12701478
  • vendor/gnumake/current/w32/subproc/w32err.c

    r2596 r3138  
    11/* Error handling for Windows
    2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
     2Copyright (C) 1996-2016 Free Software Foundation, Inc.
    43This file is part of GNU Make.
    54
     
    1615this program.  If not, see <http://www.gnu.org/licenses/>.  */
    1716
     17#include <stdlib.h>
    1818#include <windows.h>
     19#include "makeint.h"
    1920#include "w32err.h"
    2021
     
    2728 *      comp.os.ms-windows.programmer.win32
    2829 */
    29 char *
     30const char *
    3031map_windows32_error_to_string (DWORD ercode) {
    31 /* __declspec (thread) necessary if you will use multiple threads on MSVC */
    32 #ifdef _MSC_VER
    33 __declspec (thread) static char szMessageBuffer[128];
    34 #else
    35 static char szMessageBuffer[128];
    36 #endif
    37         /* Fill message buffer with a default message in
    38          * case FormatMessage fails
    39          */
     32/*
     33 * We used to have an MSVC-specific '__declspec (thread)' qualifier
     34 * here, with the following comment:
     35 *
     36 * __declspec (thread) necessary if you will use multiple threads on MSVC
     37 *
     38 * However, Make was never multithreaded on Windows (except when
     39 * Ctrl-C is hit, in which case the main thread is stopped
     40 * immediately, so it doesn't matter in this context).  The functions
     41 * on sub_proc.c that started and stopped additional threads were
     42 * never used, and are now #ifdef'ed away.  Until we need more than
     43 * one thread, we have no problems with the following buffer being
     44 * static.  (If and when we do need it to be in thread-local storage,
     45 * the corresponding GCC qualifier is '__thread'.)
     46 */
     47    static char szMessageBuffer[128];
     48        /* Fill message buffer with a default message in
     49         * case FormatMessage fails
     50         */
    4051    wsprintf (szMessageBuffer, "Error %ld\n", ercode);
    4152
    42         /*
    43          *  Special code for winsock error handling.
    44          */
    45         if (ercode > WSABASEERR) {
    46                 HMODULE hModule = GetModuleHandle("wsock32");
    47                 if (hModule != NULL) {
    48                         FormatMessage(FORMAT_MESSAGE_FROM_HMODULE,
    49                                 hModule,
    50                                 ercode,
    51                                 LANG_NEUTRAL,
    52                                 szMessageBuffer,
    53                                 sizeof(szMessageBuffer),
    54                                 NULL);
    55                         FreeLibrary(hModule);
    56                 }
    57         } else {
    58                 /*
    59                  *  Default system message handling
    60                  */
    61         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
    62                   NULL,
    63                   ercode,
    64                   LANG_NEUTRAL,
    65                   szMessageBuffer,
    66                   sizeof(szMessageBuffer),
    67                   NULL);
    68         }
     53        /*
     54         *  Special code for winsock error handling.
     55         */
     56        if (ercode > WSABASEERR) {
     57#if 0
     58                HMODULE hModule = GetModuleHandle("wsock32");
     59                if (hModule != NULL) {
     60                        FormatMessage(FORMAT_MESSAGE_FROM_HMODULE,
     61                                hModule,
     62                                ercode,
     63                                LANG_NEUTRAL,
     64                                szMessageBuffer,
     65                                sizeof(szMessageBuffer),
     66                                NULL);
     67                        FreeLibrary(hModule);
     68                }
     69#else
     70                O (fatal, NILF, szMessageBuffer);
     71#endif
     72        } else {
     73                /*
     74                 *  Default system message handling
     75                 */
     76                FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
     77                        NULL,
     78                        ercode,
     79                        LANG_NEUTRAL,
     80                        szMessageBuffer,
     81                        sizeof(szMessageBuffer),
     82                        NULL);
     83        }
    6984    return szMessageBuffer;
    7085}
Note: See TracChangeset for help on using the changeset viewer.