Changeset 503 for trunk/src/gmake/job.c


Ignore:
Timestamp:
Sep 15, 2006, 7:09:38 AM (19 years ago)
Author:
bird
Message:

Untested merge with GNU Make v3.81 (vendor/gnumake/2005-05-16 -> vendor/gnumake/current).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gmake/job.c

    r382 r503  
    11/* Job execution and handling for GNU Make.
    2 Copyright (C) 1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1999,
    3 2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
     2Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
     31998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
     4Foundation, Inc.
    45This file is part of GNU Make.
    56
    6 GNU Make is free software; you can redistribute it and/or modify
    7 it under the terms of the GNU General Public License as published by
    8 the Free Software Foundation; either version 2, or (at your option)
    9 any later version.
    10 
    11 GNU Make is distributed in the hope that it will be useful,
    12 but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 GNU General Public License for more details.
    15 
    16 You should have received a copy of the GNU General Public License
    17 along with GNU Make; see the file COPYING.  If not, write to
    18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    19 Boston, MA 02111-1307, USA.  */
     7GNU Make is free software; you can redistribute it and/or modify it under the
     8terms of the GNU General Public License as published by the Free Software
     9Foundation; either version 2, or (at your option) any later version.
     10
     11GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
     12WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     13A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     14
     15You should have received a copy of the GNU General Public License along with
     16GNU Make; see the file COPYING.  If not, write to the Free Software
     17Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */
    2018
    2119#include "make.h"
     
    4240/* Default shell to use.  */
    4341#ifdef WINDOWS32
     42#include <windows.h>
    4443
    4544char *default_shell = "sh.exe";
    4645int no_default_sh_exe = 1;
    4746int batch_mode_shell = 1;
     47HANDLE main_thread;
    4848
    4949#elif defined (_AMIGA)
     
    107107# include <starlet.h>
    108108# include <lib$routines.h>
     109static void vmsWaitForChildren PARAMS ((int *));
    109110#endif
    110111
     
    253254}
    254255
    255 /* This function creates a temporary file name with the given extension
    256  * the unixy param controls both the extension and the path separator
    257  * return an xmalloc'ed string of a newly created temp file or die.  */
     256/* This function creates a temporary file name with an extension specified
     257 * by the unixy arg.
     258 * Return an xmalloc'ed string of a newly created temp file and its
     259 * file descriptor, or die.  */
    258260static char *
    259 create_batch_filename(char const *base, int unixy)
     261create_batch_file (char const *base, int unixy, int *fd)
    260262{
    261263  const char *const ext = unixy ? "sh" : "bat";
     
    315317          char *const path = (char *) xmalloc (final_size);
    316318          memcpy (path, temp_path, final_size);
    317           CloseHandle (h);
     319          *fd = _open_osfhandle ((long)h, 0);
    318320          if (unixy)
    319321            {
     
    328330    }
    329331
     332  *fd = -1;
    330333  if (error == NULL)
    331334    error = _("Cannot create a temporary file\n");
     
    459462reap_children (int block, int err)
    460463{
     464#ifndef WINDOWS32
    461465  WAIT_T status;
    462466  /* Initially, assume we have some.  */
    463467  int reap_more = 1;
     468#endif
    464469
    465470#ifdef WAIT_NOHANG
     
    486491      int child_failed;
    487492      int any_remote, any_local;
     493      int dontcare;
    488494#if defined(CONFIG_WITH_KMK_BUILTIN) || defined(MAKE_DLLSHELL)
    489495      struct child *completed_child = 0;
     
    492498      if (err && block)
    493499        {
    494           /* We might block for a while, so let the user know why.  */
     500          static int printed = 0;
     501
     502          /* We might block for a while, so let the user know why.
     503             Only print this message once no matter how many jobs are left.  */
    495504          fflush (stdout);
    496           error (NILF, _("*** Waiting for unfinished jobs...."));
     505          if (!printed)
     506            error (NILF, _("*** Waiting for unfinished jobs...."));
     507          printed = 1;
    497508        }
    498509
     
    565576            {
    566577#ifdef VMS
    567               static void vmsWaitForChildren PARAMS ((int *));
    568578              vmsWaitForChildren (&status);
    569579              pid = c->pid;
     
    640650          {
    641651            HANDLE hPID;
    642             int err;
     652            int werr;
     653            HANDLE hcTID, hcPID;
    643654            exit_code = 0;
    644655            exit_sig = 0;
    645656            coredump = 0;
     657
     658            /* Record the thread ID of the main process, so that we
     659               could suspend it in the signal handler.  */
     660            if (!main_thread)
     661              {
     662                hcTID = GetCurrentThread ();
     663                hcPID = GetCurrentProcess ();
     664                if (!DuplicateHandle (hcPID, hcTID, hcPID, &main_thread, 0,
     665                                      FALSE, DUPLICATE_SAME_ACCESS))
     666                  {
     667                    DWORD e = GetLastError ();
     668                    fprintf (stderr,
     669                             "Determine main thread ID (Error %ld: %s)\n",
     670                             e, map_windows32_error_to_string(e));
     671                  }
     672                else
     673                  DB (DB_VERBOSE, ("Main thread handle = 0x%08lx\n",
     674                                   (unsigned long)main_thread));
     675              }
    646676
    647677            /* wait for anything to finish */
     
    651681
    652682                /* was an error found on this process? */
    653                 err = process_last_err(hPID);
     683                werr = process_last_err(hPID);
    654684
    655685                /* get exit data */
    656686                exit_code = process_exit_code(hPID);
    657687
    658                 if (err)
     688                if (werr)
    659689                  fprintf(stderr, "make (e=%d): %s",
    660690                          exit_code, map_windows32_error_to_string(exit_code));
     
    719749        good_stdin_used = 0;
    720750
     751      dontcare = c->dontcare;
     752
    721753      if (child_failed && !c->noerror && !ignore_errors_flag)
    722754        {
     
    724756             delete non-precious targets, and abort.  */
    725757          static int delete_on_error = -1;
    726           child_error (c->file->name, exit_code, exit_sig, coredump, 0);
     758
     759          if (!dontcare)
     760            child_error (c->file->name, exit_code, exit_sig, coredump, 0);
     761
    727762          c->file->update_status = 2;
    728763          if (delete_on_error == -1)
     
    824859      /* If the job failed, and the -k flag was not given, die,
    825860         unless we are already in the process of dying.  */
    826       if (!err && child_failed && !keep_going_flag &&
     861      if (!err && child_failed && !dontcare && !keep_going_flag &&
    827862          /* fatal_error_signal will die with the right signal.  */
    828863          !handling_fatal_signal)
     
    9661001start_job_command (struct child *child)
    9671002{
    968 #ifndef _AMIGA
     1003#if !defined(_AMIGA) && !defined(WINDOWS32)
    9691004  static int bad_stdin = -1;
    9701005#endif
     
    9871022
    9881023  p = child->command_ptr;
    989   child->noerror = flags & COMMANDS_NOERROR;
     1024  child->noerror = ((flags & COMMANDS_NOERROR) != 0);
    9901025
    9911026  while (*p != '\0')
     
    14241459        unblock_sigs();
    14251460        fprintf(stderr,
    1426           _("process_easy() failed failed to launch process (e=%d)\n"),
    1427           process_last_err(hPID));
    1428                for (i = 0; argv[i]; i++)
    1429                  fprintf(stderr, "%s ", argv[i]);
    1430                fprintf(stderr, _("\nCounted %d args in failed launch\n"), i);
     1461                _("process_easy() failed to launch process (e=%ld)\n"),
     1462                process_last_err(hPID));
     1463        for (i = 0; argv[i]; i++)
     1464          fprintf(stderr, "%s ", argv[i]);
     1465        fprintf(stderr, _("\nCounted %d args in failed launch\n"), i);
     1466        goto error;
    14311467      }
    14321468  }
     
    14741510  /* If we are running at least one job already and the load average
    14751511     is too high, make this one wait.  */
    1476   if (!c->remote && job_slots_used > 0 &&
    1477       (not_parallel || (c->file->command_flags & COMMANDS_NOTPARALLEL) || load_too_high ()))
     1512  if (!c->remote
     1513      && ((job_slots_used > 0 && (not_parallel || (c->file->command_flags & COMMANDS_NOTPARALLEL) || load_too_high ()))
     1514#ifdef WINDOWS32
     1515          || (process_used_slots () >= MAXIMUM_WAIT_OBJECTS)
     1516#endif
     1517          ))
    14781518    {
    14791519      /* Put this child on the chain of children waiting for the load average
     
    16671707  c->command_lines = lines;
    16681708  c->sh_batch_file = NULL;
     1709
     1710  /* Cache dontcare flag because file->dontcare can be changed once we
     1711     return. Check dontcare inheritance mechanism for details.  */
     1712  c->dontcare = file->dontcare;
    16691713
    16701714  /* Fetch the first command line to be run.  */
     
    18641908  time_t now;
    18651909
     1910#ifdef WINDOWS32
     1911  /* sub_proc.c cannot wait for more than MAXIMUM_WAIT_OBJECTS children */
     1912  if (process_used_slots () >= MAXIMUM_WAIT_OBJECTS)
     1913    return 1;
     1914#endif
     1915
    18661916  if (max_load_average < 0)
    18671917    return 0;
     
    20112061}
    20122062
    2013 #elif !defined (_AMIGA) && !defined (__MSDOS__)
     2063#elif !defined (_AMIGA) && !defined (__MSDOS__) && !defined (VMS)
    20142064
    20152065/* UNIX:
     
    20322082  exec_command (argv, envp);
    20332083}
    2034 #endif /* !AMIGA && !__MSDOS__ */
     2084#endif /* !AMIGA && !__MSDOS__ && !VMS */
    20352085#endif /* !WINDOWS32 */
    20362086
     
    21952245      int i;
    21962246      fprintf(stderr,
    2197               _("process_easy() failed failed to launch process (e=%d)\n"),
     2247              _("process_easy() failed failed to launch process (e=%ld)\n"),
    21982248              process_last_err(hPID));
    21992249      for (i = 0; argv[i]; i++)
     
    22252275      else
    22262276          fprintf(stderr,
    2227                   _("make reaped child pid %d, still waiting for pid %d\n"),
    2228                   hWaitPID, hPID);
     2277                  _("make reaped child pid %ld, still waiting for pid %ld\n"),
     2278                  (DWORD)hWaitPID, (DWORD)hPID);
    22292279    }
    22302280
     
    24972547  int instring, word_has_equals, seen_nonequals, last_argument_was_empty;
    24982548  char **new_argv = 0;
     2549  char *argstr = 0;
    24992550#ifdef WINDOWS32
    25002551  int slow_flag = 0;
    25012552
    2502   if (no_default_sh_exe) {
     2553  if (!unixy_shell) {
    25032554    sh_cmds = sh_cmds_dos;
    25042555    sh_chars = sh_chars_dos;
     
    25892640
    25902641  /* All the args can fit in a buffer as big as LINE is.   */
    2591   ap = new_argv[0] = (char *) xmalloc (i);
     2642  ap = new_argv[0] = argstr = (char *) xmalloc (i);
    25922643  end = ap + i;
    25932644
     
    25972648  for (p = line; *p != '\0'; ++p)
    25982649    {
    2599       if (ap > end)
    2600         abort ();
     2650      assert (ap <= end);
    26012651
    26022652      if (instring)
    26032653        {
    2604         string_char:
    26052654          /* Inside a string, just copy any char except a closing quote
    26062655             or a backslash-newline combination.  */
     
    26122661            }
    26132662          else if (*p == '\\' && p[1] == '\n')
    2614             goto swallow_escaped_newline;
     2663            {
     2664              /* Backslash-newline is handled differently depending on what
     2665                 kind of string we're in: inside single-quoted strings you
     2666                 keep them; in double-quoted strings they disappear.
     2667                 For DOS/Windows/OS2, if we don't have a POSIX shell,
     2668                 we keep the pre-POSIX behavior of removing the
     2669                 backslash-newline.  */
     2670              if (instring == '"'
     2671#if defined (__MSDOS__) || defined (__EMX__) || defined (WINDOWS32)
     2672                  || !unixy_shell
     2673#endif
     2674                  )
     2675                ++p;
     2676              else
     2677                {
     2678                  *(ap++) = *(p++);
     2679                  *(ap++) = *p;
     2680                }
     2681              /* If there's a TAB here, skip it.  */
     2682              if (p[1] == '\t')
     2683                ++p;
     2684            }
    26152685          else if (*p == '\n' && restp != NULL)
    26162686            {
     
    26522722
    26532723          case '\\':
    2654             /* Backslash-newline combinations are eaten.  */
     2724            /* Backslash-newline has special case handling, ref POSIX.
     2725               We're in the fastpath, so emulate what the shell would do.  */
    26552726            if (p[1] == '\n')
    26562727              {
    2657               swallow_escaped_newline:
    2658 
    2659                 /* Eat the backslash, the newline, and following whitespace,
    2660                    replacing it all with a single space.  */
    2661                 p += 2;
    2662 
    2663                 /* If there is a tab after a backslash-newline,
    2664                    remove it from the source line which will be echoed,
    2665                    since it was most likely used to line
    2666                    up the continued line with the previous one.  */
    2667                 if (*p == '\t')
    2668                   /* Note these overlap and strcpy() is undefined for
    2669                      overlapping objects in ANSI C.  The strlen() _IS_ right,
    2670                      since we need to copy the nul byte too.  */
    2671                   bcopy (p + 1, p, strlen (p));
    2672 
    2673                 if (instring)
    2674                   goto string_char;
    2675                 else
    2676                   {
    2677                     if (ap != new_argv[i])
    2678                       /* Treat this as a space, ending the arg.
    2679                          But if it's at the beginning of the arg, it should
    2680                          just get eaten, rather than becoming an empty arg. */
    2681                       goto end_of_arg;
    2682                     else
    2683                       p = next_token (p) - 1;
    2684                   }
     2728                /* Throw out the backslash and newline.  */
     2729                ++p;
     2730
     2731                /* If there is a tab after a backslash-newline, remove it.  */
     2732                if (p[1] == '\t')
     2733                  ++p;
     2734
     2735                /* If there's nothing in this argument yet, skip any
     2736                   whitespace before the start of the next word.  */
     2737                if (ap == new_argv[i])
     2738                  p = next_token (p + 1) - 1;
    26852739              }
    26862740            else if (p[1] != '\0')
    26872741              {
    26882742#ifdef HAVE_DOS_PATHS
    2689                 /* Only remove backslashes before characters special
    2690                    to Unixy shells.  All other backslashes are copied
    2691                    verbatim, since they are probably DOS-style
    2692                    directory separators.  This still leaves a small
    2693                    window for problems, but at least it should work
    2694                    for the vast majority of naive users.  */
     2743                /* Only remove backslashes before characters special to Unixy
     2744                   shells.  All other backslashes are copied verbatim, since
     2745                   they are probably DOS-style directory separators.  This
     2746                   still leaves a small window for problems, but at least it
     2747                   should work for the vast majority of naive users.  */
    26952748
    26962749#ifdef __MSDOS__
     
    27072760                  if (p[1] != '\\' && p[1] != '\''
    27082761                      && !isspace ((unsigned char)p[1])
    2709                       && (strchr (sh_chars_sh, p[1]) == 0))
     2762                      && strchr (sh_chars_sh, p[1]) == 0)
    27102763                    /* back up one notch, to copy the backslash */
    27112764                    --p;
     
    27362789          case ' ':
    27372790          case '\t':
    2738           end_of_arg:
    27392791            /* We have the end of an argument.
    27402792               Terminate the text of the argument.  */
     
    27722824
    27732825            /* Ignore multiple whitespace chars.  */
    2774             p = next_token (p);
    2775             /* Next iteration should examine the first nonwhite char.  */
    2776             --p;
     2826            p = next_token (p) - 1;
    27772827            break;
    27782828
     
    28042854
    28052855  if (new_argv[0] == 0)
    2806     /* Line was empty.  */
    2807     return 0;
     2856    {
     2857      /* Line was empty.  */
     2858      free (argstr);
     2859      free ((char *)new_argv);
     2860      return 0;
     2861    }
    28082862
    28092863  return new_argv;
     
    28152869    {
    28162870      /* Free the old argument list we were working on.  */
    2817       free (new_argv[0]);
    2818       free ((void *)new_argv);
     2871      free (argstr);
     2872      free ((char *)new_argv);
    28192873    }
    28202874
     
    29062960        else if (*p == '\\' && p[1] == '\n')
    29072961          {
    2908             /* Eat the backslash, the newline, and following whitespace,
    2909                replacing it all with a single space (which is escaped
    2910                from the shell).  */
    2911             p += 2;
    2912 
    2913             /* If there is a tab after a backslash-newline,
    2914                remove it from the source line which will be echoed,
    2915                since it was most likely used to line
    2916                up the continued line with the previous one.  */
    2917             if (*p == '\t')
    2918               bcopy (p + 1, p, strlen (p));
    2919 
    2920             p = next_token (p);
    2921             --p;
    2922             if (unixy_shell && !batch_mode_shell)
    2923               *ap++ = '\\';
    2924             *ap++ = ' ';
     2962            /* POSIX says we keep the backslash-newline, but throw out
     2963               the next char if it's a TAB.  If we don't have a POSIX
     2964               shell on DOS/Windows/OS2, mimic the pre-POSIX behavior
     2965               and remove the backslash/newline.  */
     2966#if defined (__MSDOS__) || defined (__EMX__) || defined (WINDOWS32)
     2967# define PRESERVE_BSNL  unixy_shell
     2968#else
     2969# define PRESERVE_BSNL  1
     2970#endif
     2971            if (PRESERVE_BSNL)
     2972              {
     2973                *(ap++) = '\\';
     2974                *(ap++) = '\\';
     2975                *(ap++) = '\n';
     2976              }
     2977
     2978            ++p;
     2979            if (p[1] == '\t')
     2980              ++p;
     2981
    29252982            continue;
    29262983          }
     
    29523009       command line (e.g. Cygnus GNUWIN32 sh.exe on WIN32 systems).  In these
    29533010       cases, run commands via a script file.  */
    2954     if ((no_default_sh_exe || batch_mode_shell) && batch_filename_ptr) {
     3011    if (just_print_flag) {
     3012      /* Need to allocate new_argv, although it's unused, because
     3013        start_job_command will want to free it and its 0'th element.  */
     3014      new_argv = (char **) xmalloc(2 * sizeof (char *));
     3015      new_argv[0] = xstrdup ("");
     3016      new_argv[1] = NULL;
     3017    } else if ((no_default_sh_exe || batch_mode_shell) && batch_filename_ptr) {
     3018      int temp_fd;
    29553019      FILE* batch = NULL;
    29563020      int id = GetCurrentProcessId();
     
    29593023      /* create a file name */
    29603024      sprintf(fbuf, "make%d", id);
    2961       *batch_filename_ptr = create_batch_filename (fbuf, unixy_shell);
     3025      *batch_filename_ptr = create_batch_file (fbuf, unixy_shell, &temp_fd);
    29623026
    29633027      DB (DB_JOBS, (_("Creating temporary batch file %s\n"),
    29643028                    *batch_filename_ptr));
    29653029
    2966       /* create batch file to execute command */
    2967       batch = fopen (*batch_filename_ptr, "w");
     3030      /* Create a FILE object for the batch file, and write to it the
     3031         commands to be executed.  Put the batch file in TEXT mode.  */
     3032      _setmode (temp_fd, _O_TEXT);
     3033      batch = _fdopen (temp_fd, "wt");
    29683034      if (!unixy_shell)
    29693035        fputs ("@echo off\n", batch);
Note: See TracChangeset for help on using the changeset viewer.