(linenum→info "unix/slp.c:2238")

binutils/2.18/libiberty/pex-win32.c

    1: /* Utilities to execute a program in a subprocess (possibly linked by pipes
    2:    with other subprocesses), and wait for it.  Generic Win32 specialization.
    3:    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
    4:    Free Software Foundation, Inc.
    5: 
    6: This file is part of the libiberty library.
    7: Libiberty is free software; you can redistribute it and/or
    8: modify it under the terms of the GNU Library General Public
    9: License as published by the Free Software Foundation; either
   10: version 2 of the License, or (at your option) any later version.
   11: 
   12: Libiberty is distributed in the hope that it will be useful,
   13: but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15: Library General Public License for more details.
   16: 
   17: You should have received a copy of the GNU Library General Public
   18: License along with libiberty; see the file COPYING.LIB.  If not,
   19: write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
   20: Boston, MA 02110-1301, USA.  */
   21: 
   22: #include "pex-common.h"
   23: 
   24: #include <windows.h>
   25: 
   26: #ifdef HAVE_STDLIB_H
   27: #include <stdlib.h>
   28: #endif
   29: #ifdef HAVE_STRING_H
   30: #include <string.h>
   31: #endif
   32: #ifdef HAVE_UNISTD_H
   33: #include <unistd.h>
   34: #endif
   35: #ifdef HAVE_SYS_WAIT_H
   36: #include <sys/wait.h>
   37: #endif
   38: 
   39: #include <assert.h>
   40: #include <process.h>
   41: #include <io.h>
   42: #include <fcntl.h>
   43: #include <signal.h>
   44: #include <sys/stat.h>
   45: #include <errno.h>
   46: #include <ctype.h>
   47: 
   48: /* mingw32 headers may not define the following.  */
   49: 
   50: #ifndef _P_WAIT
   51: #  define _P_WAIT       0
   52: #  define _P_NOWAIT     1
   53: #  define _P_OVERLAY    2
   54: #  define _P_NOWAITO    3
   55: #  define _P_DETACH     4
   56: 
   57: #  define WAIT_CHILD            0
   58: #  define WAIT_GRANDCHILD       1
   59: #endif
   60: 
   61: #define MINGW_NAME "Minimalist GNU for Windows"
   62: #define MINGW_NAME_LEN (sizeof(MINGW_NAME) - 1)
   63: 
   64: extern char *stpcpy (char *dst, const char *src);
   65: 
   66: /* Ensure that the executable pathname uses Win32 backslashes. This
   67:    is not necessary on NT, but on W9x, forward slashes causes
   68:    failure of spawn* and exec* functions (and probably any function
   69:    that calls CreateProcess) *iff* the executable pathname (argv[0])
   70:    is a quoted string.  And quoting is necessary in case a pathname
   71:    contains embedded white space.  You can't win.  */
   72: static void
   73: backslashify (char *s)
   74: {
   75:   while ((s = strchr (s, '/')) != NULL)
   76:     *s = '\\';
   77:   return;
   78: }
   79: 
   80: static int pex_win32_open_read (struct pex_obj *, const char *, int);
   81: static int pex_win32_open_write (struct pex_obj *, const char *, int);
   82: static long pex_win32_exec_child (struct pex_obj *, int, const char *,
   83:                                   char * const *, char * const *,
   84:                                   int, int, int, int,
   85:                                   const char **, int *);
   86: static int pex_win32_close (struct pex_obj *, int);
   87: static int pex_win32_wait (struct pex_obj *, long, int *,
   88:                            struct pex_time *, int, const char **, int *);
   89: static int pex_win32_pipe (struct pex_obj *, int *, int);
   90: static FILE *pex_win32_fdopenr (struct pex_obj *, int, int);
   91: static FILE *pex_win32_fdopenw (struct pex_obj *, int, int);
   92: 
   93: /* The list of functions we pass to the common routines.  */
   94: 
   95: const struct pex_funcs funcs =
   96: {
   97:   pex_win32_open_read,
   98:   pex_win32_open_write,
   99:   pex_win32_exec_child,
  100:   pex_win32_close,
  101:   pex_win32_wait,
  102:   pex_win32_pipe,
  103:   pex_win32_fdopenr,
  104:   pex_win32_fdopenw,
  105:   NULL /* cleanup */
  106: };
  107: 
  108: /* Return a newly initialized pex_obj structure.  */
  109: 
  110: struct pex_obj *
  111: pex_init (int flags, const char *pname, const char *tempbase)
  112: {
  113:   return pex_init_common (flags, pname, tempbase, &funcs);
  114: }
  115: 
  116: /* Open a file for reading.  */
  117: 
  118: static int
  119: pex_win32_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
  120:                      int binary)
  121: {
  122:   return _open (name, _O_RDONLY | (binary ? _O_BINARY : _O_TEXT));
  123: }
  124: 
  125: /* Open a file for writing.  */
  126: 
  127: static int
  128: pex_win32_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
  129:                       int binary)
  130: {
  131:   /* Note that we can't use O_EXCL here because gcc may have already
  132:      created the temporary file via make_temp_file.  */
  133:   return _open (name,
  134:                 (_O_WRONLY | _O_CREAT | _O_TRUNC
  135:                  | (binary ? _O_BINARY : _O_TEXT)),
  136:                 _S_IREAD | _S_IWRITE);
  137: }
  138: 
  139: /* Close a file.  */
  140: 
  141: static int
  142: pex_win32_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
  143: {
  144:   return _close (fd);
  145: }
  146: 
  147: #ifdef USE_MINGW_MSYS
  148: static const char *mingw_keys[] = {"SOFTWARE", "Microsoft", "Windows", "CurrentVersion", "Uninstall", NULL};
  149: 
  150: /* Tack the executable on the end of a (possibly slash terminated) buffer
  151:    and convert everything to \. */
  152: static const char *
  153: tack_on_executable (char *buf, const char *executable)
  154: {
  155:   char *p = strchr (buf, '\0');
  156:   if (p > buf && (p[-1] == '\\' || p[-1] == '/'))
  157:     p[-1] = '\0';
  158:   backslashify (strcat (buf, executable));
  159:   return buf;
  160: }
  161: 
  162: /* Walk down a registry hierarchy until the end.  Return the key. */
  163: static HKEY
  164: openkey (HKEY hStart, const char *keys[])
  165: {
  166:   HKEY hKey, hTmp;
  167:   for (hKey = hStart; *keys; keys++)
  168:     {
  169:       LONG res;
  170:       hTmp = hKey;
  171:       res = RegOpenKey (hTmp, *keys, &hKey);
  172: 
  173:       if (hTmp != HKEY_LOCAL_MACHINE)
  174:         RegCloseKey (hTmp);
  175: 
  176:       if (res != ERROR_SUCCESS)
  177:         return NULL;
  178:     }
  179:   return hKey;
  180: }
  181: 
  182: /* Return the "mingw root" as derived from the mingw uninstall information. */
  183: static const char *
  184: mingw_rootify (const char *executable)
  185: {
  186:   HKEY hKey, hTmp;
  187:   DWORD maxlen;
  188:   char *namebuf, *foundbuf;
  189:   DWORD i;
  190:   LONG res;
  191: 
  192:   /* Open the uninstall "directory". */
  193:   hKey = openkey (HKEY_LOCAL_MACHINE, mingw_keys);
  194: 
  195:   /* Not found. */
  196:   if (!hKey)
  197:     return executable;
  198: 
  199:   /* Need to enumerate all of the keys here looking for one the most recent
  200:      one for MinGW. */
  201:   if (RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, &maxlen, NULL, NULL,
  202:                        NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
  203:     {
  204:       RegCloseKey (hKey);
  205:       return executable;
  206:     }
  207:   namebuf = XNEWVEC (char, ++maxlen);
  208:   foundbuf = XNEWVEC (char, maxlen);
  209:   foundbuf[0] = '\0';
  210:   if (!namebuf || !foundbuf)
  211:     {
  212:       RegCloseKey (hKey);
  213:       if (namebuf)
  214:         free (namebuf);
  215:       if (foundbuf)
  216:         free (foundbuf);
  217:       return executable;
  218:     }
  219: 
  220:   /* Look through all of the keys for one that begins with Minimal GNU...
  221:      Try to get the latest version by doing a string compare although that
  222:      string never really works with version number sorting. */
  223:   for (i = 0; RegEnumKey (hKey, i, namebuf, maxlen) == ERROR_SUCCESS; i++)
  224:     {
  225:       int match = strcasecmp (namebuf, MINGW_NAME);
  226:       if (match < 0)
  227:         continue;
  228:       if (match > 0 && strncasecmp (namebuf, MINGW_NAME, MINGW_NAME_LEN) > 0)
  229:         continue;
  230:       if (strcasecmp (namebuf, foundbuf) > 0)
  231:         strcpy (foundbuf, namebuf);
  232:     }
  233:   free (namebuf);
  234: 
  235:   /* If foundbuf is empty, we didn't find anything.  Punt. */
  236:   if (!foundbuf[0])
  237:     {
  238:       free (foundbuf);
  239:       RegCloseKey (hKey);
  240:       return executable;
  241:     }
  242: 
  243:   /* Open the key that we wanted */
  244:   res = RegOpenKey (hKey, foundbuf, &hTmp);
  245:   RegCloseKey (hKey);
  246:   free (foundbuf);
  247: 
  248:   /* Don't know why this would fail, but you gotta check */
  249:   if (res != ERROR_SUCCESS)
  250:     return executable;
  251: 
  252:   maxlen = 0;
  253:   /* Get the length of the value pointed to by InstallLocation */
  254:   if (RegQueryValueEx (hTmp, "InstallLocation", 0, NULL, NULL,
  255:                        &maxlen) != ERROR_SUCCESS || maxlen == 0)
  256:     {
  257:       RegCloseKey (hTmp);
  258:       return executable;
  259:     }
  260: 
  261:   /* Allocate space for the install location */
  262:   foundbuf = XNEWVEC (char, maxlen + strlen (executable));
  263:   if (!foundbuf)
  264:     {
  265:       free (foundbuf);
  266:       RegCloseKey (hTmp);
  267:     }
  268: 
  269:   /* Read the install location into the buffer */
  270:   res = RegQueryValueEx (hTmp, "InstallLocation", 0, NULL, (LPBYTE) foundbuf,
  271:                          &maxlen);
  272:   RegCloseKey (hTmp);
  273:   if (res != ERROR_SUCCESS)
  274:     {
  275:       free (foundbuf);
  276:       return executable;
  277:     }
  278: 
  279:   /* Concatenate the install location and the executable, turn all slashes
  280:      to backslashes, and return that. */
  281:   return tack_on_executable (foundbuf, executable);
  282: }
  283: 
  284: /* Read the install location of msys from it's installation file and
  285:    rootify the executable based on that. */
  286: static const char *
  287: msys_rootify (const char *executable)
  288: {
  289:   size_t bufsize = 64;
  290:   size_t execlen = strlen (executable) + 1;
  291:   char *buf;
  292:   DWORD res = 0;
  293:   for (;;)
  294:     {
  295:       buf = XNEWVEC (char, bufsize + execlen);
  296:       if (!buf)
  297:         break;
  298:       res = GetPrivateProfileString ("InstallSettings", "InstallPath", NULL,
  299:                                      buf, bufsize, "msys.ini");
  300:       if (!res)
  301:         break;
  302:       if (strlen (buf) < bufsize)
  303:         break;
  304:       res = 0;
  305:       free (buf);
  306:       bufsize *= 2;
  307:       if (bufsize > 65536)
  308:         {
  309:           buf = NULL;
  310:           break;
  311:         }
  312:     }
  313: 
  314:   if (res)
  315:     return tack_on_executable (buf, executable);
  316: 
  317:   /* failed */
  318:   if (buf)
  319:     free (buf);
  320:   return executable;
  321: }
  322: #endif
  323: 
  324: /* Return a Windows command-line from ARGV.  It is the caller's
  325:    responsibility to free the string returned.  */
  326: 
  327: static char *
  328: argv_to_cmdline (char *const *argv)
  329: {
  330:   char *cmdline;
  331:   char *p;
  332:   size_t cmdline_len;
  333:   int i, j, k;
  334: 
  335:   cmdline_len = 0;
  336:   for (i = 0; argv[i]; i++)
  337:     {
  338:       /* We quote every last argument.  This simplifies the problem;
  339:          we need only escape embedded double-quotes and immediately
  340:          preceeding backslash characters.  A sequence of backslach characters
  341:          that is not follwed by a double quote character will not be
  342:          escaped.  */
  343:       for (j = 0; argv[i][j]; j++)
  344:         {
  345:           if (argv[i][j] == '"')
  346:             {
  347:               /* Escape preceeding backslashes.  */
  348:               for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--)
  349:                 cmdline_len++;
  350:               /* Escape the qote character.  */
  351:               cmdline_len++;
  352:             }
  353:         }
  354:       /* Trailing backslashes also need to be escaped because they will be
  355:          followed by the terminating quote.  */
  356:       for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--)
  357:         cmdline_len++;
  358:       cmdline_len += j;
  359:       cmdline_len += 3;  /* for leading and trailing quotes and space */
  360:     }
  361:   cmdline = XNEWVEC (char, cmdline_len);
  362:   p = cmdline;
  363:   for (i = 0; argv[i]; i++)
  364:     {
  365:       *p++ = '"';
  366:       for (j = 0; argv[i][j]; j++)
  367:         {
  368:           if (argv[i][j] == '"')
  369:             {
  370:               for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--)
  371:                 *p++ = '\\';
  372:               *p++ = '\\';
  373:             }
  374:           *p++ = argv[i][j];
  375:         }
  376:       for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--)
  377:         *p++ = '\\';
  378:       *p++ = '"';
  379:       *p++ = ' ';
  380:     }
  381:   p[-1] = '\0';
  382:   return cmdline;
  383: }
  384: 
  385: /* We'll try the passed filename with all the known standard
  386:    extensions, and then without extension.  We try no extension
  387:    last so that we don't try to run some random extension-less
  388:    file that might be hanging around.  We try both extension
  389:    and no extension so that we don't need any fancy logic
  390:    to determine if a file has extension.  */
  391: static const char *const
  392: std_suffixes[] = {
  393:   ".com",
  394:   ".exe",
  395:   ".bat",
  396:   ".cmd",
  397:   "",
  398:   0
  399: };
  400: 
  401: /* Returns the full path to PROGRAM.  If SEARCH is true, look for
  402:    PROGRAM in each directory in PATH.  */
  403: 
  404: static char *
  405: find_executable (const char *program, BOOL search)
  406: {
  407:   char *full_executable;
  408:   char *e;
  409:   size_t fe_len;
  410:   const char *path = 0;
  411:   const char *const *ext;
  412:   const char *p, *q;
  413:   size_t proglen = strlen (program);
  414:   int has_slash = (strchr (program, '/') || strchr (program, '\\'));
  415:   HANDLE h;
  416: 
  417:   if (has_slash)
  418:     search = FALSE;
  419: 
  420:   if (search)
  421:     path = getenv ("PATH");
  422:   if (!path)
  423:     path = "";
  424: 
  425:   fe_len = 0;
  426:   for (p = path; *p; p = q)
  427:     {
  428:       q = p;
  429:       while (*q != ';' && *q != '\0')
  430:         q++;
  431:       if ((size_t)(q - p) > fe_len)
  432:         fe_len = q - p;
  433:       if (*q == ';')
  434:         q++;
  435:     }
  436:   fe_len = fe_len + 1 + proglen + 5 /* space for extension */;
  437:   full_executable = XNEWVEC (char, fe_len);
  438: 
  439:   p = path;
  440:   do
  441:     {
  442:       q = p;
  443:       while (*q != ';' && *q != '\0')
  444:         q++;
  445: 
  446:       e = full_executable;
  447:       memcpy (e, p, q - p);
  448:       e += (q - p);
  449:       if (q - p)
  450:         *e++ = '\\';
  451:       strcpy (e, program);
  452: 
  453:       if (*q == ';')
  454:         q++;
  455: 
  456:       for (e = full_executable; *e; e++)
  457:         if (*e == '/')
  458:           *e = '\\';
  459: 
  460:       /* At this point, e points to the terminating NUL character for
  461:          full_executable.  */
  462:       for (ext = std_suffixes; *ext; ext++)
  463:         {
  464:           /* Remove any current extension.  */
  465:           *e = '\0';
  466:           /* Add the new one.  */
  467:           strcat (full_executable, *ext);
  468: 
  469:           /* Attempt to open this file.  */
  470:           h = CreateFile (full_executable, GENERIC_READ,
  471:                           FILE_SHARE_READ | FILE_SHARE_WRITE,
  472:                           0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  473:           if (h != INVALID_HANDLE_VALUE)
  474:             goto found;
  475:         }
  476:       p = q;
  477:     }
  478:   while (*p);
  479:   free (full_executable);
  480:   return 0;
  481: 
  482:  found:
  483:   CloseHandle (h);
  484:   return full_executable;
  485: }
  486: 
  487: /* Low-level process creation function and helper.  */
  488: 
  489: static int
  490: env_compare (const void *a_ptr, const void *b_ptr)
  491: {
  492:   const char *a;
  493:   const char *b;
  494:   unsigned char c1;
  495:   unsigned char c2;
  496: 
  497:   a = *(const char **) a_ptr;
  498:   b = *(const char **) b_ptr;
  499: 
  500:   /* a and b will be of the form: VAR=VALUE
  501:      We compare only the variable name part here using a case-insensitive
  502:      comparison algorithm.  It might appear that in fact strcasecmp () can
  503:      take the place of this whole function, and indeed it could, save for
  504:      the fact that it would fail in cases such as comparing A1=foo and
  505:      A=bar (because 1 is less than = in the ASCII character set).
  506:      (Environment variables containing no numbers would work in such a
  507:      scenario.)  */
  508: 
  509:   do
  510:     {
  511:       c1 = (unsigned char) tolower (*a++);
  512:       c2 = (unsigned char) tolower (*b++);
  513: 
  514:       if (c1 == '=')
  515:         c1 = '\0';
  516: 
  517:       if (c2 == '=')
  518:         c2 = '\0';
  519:     }
  520:   while (c1 == c2 && c1 != '\0');
  521: 
  522:   return c1 - c2;
  523: }
  524: 
  525: static long
  526: win32_spawn (const char *executable,
  527:              BOOL search,
  528:              char *const *argv,
  529:              char *const *env, /* array of strings of the form: VAR=VALUE */
  530:              DWORD dwCreationFlags,
  531:              LPSTARTUPINFO si,
  532:              LPPROCESS_INFORMATION pi)
  533: {
  534:   char *full_executable;
  535:   char *cmdline;
  536:   char **env_copy;
  537:   char *env_block = NULL;
  538: 
  539:   full_executable = NULL;
  540:   cmdline = NULL;
  541: 
  542:   if (env)
  543:     {
  544:       int env_size;
  545: 
  546:       /* Count the number of environment bindings supplied.  */
  547:       for (env_size = 0; env[env_size]; env_size++)
  548:         continue;
  549:     
  550:       /* Assemble an environment block, if required.  This consists of
  551:          VAR=VALUE strings juxtaposed (with one null character between each
  552:          pair) and an additional null at the end.  */
  553:       if (env_size > 0)
  554:         {
  555:           int var;
  556:           int total_size = 1; /* 1 is for the final null.  */
  557:           char *bufptr;
  558:     
  559:           /* Windows needs the members of the block to be sorted by variable
  560:              name.  */
  561:           env_copy = (char **) alloca (sizeof (char *) * env_size);
  562:           memcpy (env_copy, env, sizeof (char *) * env_size);
  563:           qsort (env_copy, env_size, sizeof (char *), env_compare);
  564:     
  565:           for (var = 0; var < env_size;