(root)/
make-4.4/
src/
posixos.c
       1  /* POSIX-based operating system interface for GNU Make.
       2  Copyright (C) 2016-2022 Free Software Foundation, Inc.
       3  This file is part of GNU Make.
       4  
       5  GNU Make is free software; you can redistribute it and/or modify it under the
       6  terms of the GNU General Public License as published by the Free Software
       7  Foundation; either version 3 of the License, or (at your option) any later
       8  version.
       9  
      10  GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
      11  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      12  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      13  
      14  You should have received a copy of the GNU General Public License along with
      15  this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  #include "makeint.h"
      18  
      19  #include <stdio.h>
      20  
      21  #ifdef HAVE_FCNTL_H
      22  # include <fcntl.h>
      23  # define FD_OK(_f) (fcntl ((_f), F_GETFD) != -1)
      24  #elif defined(HAVE_SYS_FILE_H)
      25  # include <sys/file.h>
      26  #endif
      27  
      28  #if !defined(FD_OK)
      29  # define FD_OK(_f) 1
      30  #endif
      31  
      32  #if defined(HAVE_PSELECT) && defined(HAVE_SYS_SELECT_H)
      33  # include <sys/select.h>
      34  #endif
      35  
      36  #include "debug.h"
      37  #include "job.h"
      38  #include "os.h"
      39  
      40  #define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
      41  
      42  unsigned int
      43  check_io_state ()
      44  {
      45    static unsigned int state = IO_UNKNOWN;
      46  
      47    /* We only need to compute this once per process.  */
      48    if (state != IO_UNKNOWN)
      49      return state;
      50  
      51    if (STREAM_OK (stdin))
      52      state |= IO_STDIN_OK;
      53    if (STREAM_OK (stdout))
      54      state |= IO_STDOUT_OK;
      55    if (STREAM_OK (stderr))
      56      state |= IO_STDERR_OK;
      57  
      58    if (ALL_SET (state, IO_STDOUT_OK|IO_STDERR_OK))
      59      {
      60        struct stat stbuf_o, stbuf_e;
      61  
      62        if (fstat (fileno (stdout), &stbuf_o) == 0
      63            && fstat (fileno (stderr), &stbuf_e) == 0
      64            && stbuf_o.st_dev == stbuf_e.st_dev
      65            && stbuf_o.st_ino == stbuf_e.st_ino)
      66          state |= IO_COMBINED_OUTERR;
      67      }
      68  
      69    return state;
      70  }
      71  
      72  #if defined(MAKE_JOBSERVER)
      73  
      74  #define FIFO_PREFIX    "fifo:"
      75  
      76  /* This section provides OS-specific functions to support the jobserver.  */
      77  
      78  /* True if this is the root make instance.  */
      79  static unsigned char job_root = 0;
      80  
      81  /* These track the state of the jobserver pipe.  Passed to child instances.  */
      82  static int job_fds[2] = { -1, -1 };
      83  
      84  /* Used to signal read() that a SIGCHLD happened.  Always CLOEXEC.
      85     If we use pselect() this will never be created and always -1.
      86   */
      87  static int job_rfd = -1;
      88  
      89  /* Token written to the pipe (could be any character...)  */
      90  static char token = '+';
      91  
      92  /* The type of jobserver we're using.  */
      93  enum js_type
      94    {
      95      js_none = 0,        /* No jobserver.  */
      96      js_pipe,            /* Use a simple pipe as the jobserver.  */
      97      js_fifo             /* Use a named pipe as the jobserver.  */
      98    };
      99  
     100  static enum js_type js_type = js_none;
     101  
     102  /* The name of the named pipe (if used).  */
     103  static char *fifo_name = NULL;
     104  
     105  static int
     106  make_job_rfd ()
     107  {
     108  #ifdef HAVE_PSELECT
     109    /* Pretend we succeeded.  */
     110    return 0;
     111  #else
     112    EINTRLOOP (job_rfd, dup (job_fds[0]));
     113    if (job_rfd >= 0)
     114      fd_noinherit (job_rfd);
     115  
     116    return job_rfd;
     117  #endif
     118  }
     119  
     120  static void
     121  set_blocking (int fd, int blocking)
     122  {
     123    /* If we're not using pselect() don't change the blocking.  */
     124  #ifdef HAVE_PSELECT
     125    int flags;
     126    EINTRLOOP (flags, fcntl (fd, F_GETFL));
     127    if (flags >= 0)
     128      {
     129        int r;
     130        flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
     131        EINTRLOOP (r, fcntl (fd, F_SETFL, flags));
     132        if (r < 0)
     133          pfatal_with_name ("fcntl(O_NONBLOCK)");
     134      }
     135  #endif
     136  }
     137  
     138  unsigned int
     139  jobserver_setup (int slots, const char *style)
     140  {
     141    int r;
     142  
     143  #if HAVE_MKFIFO
     144    if (style == NULL || strcmp (style, "fifo") == 0)
     145      {
     146    /* Unfortunately glibc warns about uses of mktemp even though we aren't
     147       using it in dangerous way here.  So avoid this by generating our own
     148       temporary file name.  */
     149  # define  FNAME_PREFIX "GMfifo"
     150        const char *tmpdir = get_tmpdir ();
     151  
     152        fifo_name = xmalloc (strlen (tmpdir) + CSTRLEN (FNAME_PREFIX)
     153                             + INTSTR_LENGTH + 2);
     154        sprintf (fifo_name, "%s/" FNAME_PREFIX "%" MK_PRI64_PREFIX "d",
     155                 tmpdir, (long long)make_pid ());
     156  
     157        EINTRLOOP (r, mkfifo (fifo_name, 0600));
     158        if (r < 0)
     159          {
     160            perror_with_name("jobserver mkfifo: ", fifo_name);
     161            free (fifo_name);
     162            fifo_name = NULL;
     163          }
     164        else
     165          {
     166            /* We have to open the read side in non-blocking mode, else it will
     167               hang until the write side is open.  */
     168            EINTRLOOP (job_fds[0], open (fifo_name, O_RDONLY|O_NONBLOCK));
     169            if (job_fds[0] < 0)
     170              OSS (fatal, NILF, _("Cannot open jobserver %s: %s"),
     171                   fifo_name, strerror (errno));
     172  
     173            EINTRLOOP (job_fds[1], open (fifo_name, O_WRONLY));
     174            if (job_fds[0] < 0)
     175              OSS (fatal, NILF, _("Cannot open jobserver %s: %s"),
     176                   fifo_name, strerror (errno));
     177  
     178            js_type = js_fifo;
     179          }
     180      }
     181  #endif
     182  
     183    if (js_type == js_none)
     184      {
     185        if (style && strcmp (style, "pipe") != 0)
     186          OS (fatal, NILF, _("Unknown jobserver auth style '%s'"), style);
     187  
     188        EINTRLOOP (r, pipe (job_fds));
     189        if (r < 0)
     190          pfatal_with_name (_("creating jobs pipe"));
     191  
     192        js_type = js_pipe;
     193      }
     194  
     195    /* By default we don't send the job pipe FDs to our children.
     196       See jobserver_pre_child() and jobserver_post_child().  */
     197    fd_noinherit (job_fds[0]);
     198    fd_noinherit (job_fds[1]);
     199  
     200    if (make_job_rfd () < 0)
     201      pfatal_with_name (_("duping jobs pipe"));
     202  
     203    while (slots--)
     204      {
     205        EINTRLOOP (r, write (job_fds[1], &token, 1));
     206        if (r != 1)
     207          pfatal_with_name (_("init jobserver pipe"));
     208      }
     209  
     210    /* When using pselect() we want the read to be non-blocking.  */
     211    set_blocking (job_fds[0], 0);
     212  
     213    job_root = 1;
     214  
     215    return 1;
     216  }
     217  
     218  unsigned int
     219  jobserver_parse_auth (const char *auth)
     220  {
     221    int rfd, wfd;
     222  
     223    /* Given the command-line parameter, parse it.  */
     224  
     225    /* First see if we're using a named pipe.  */
     226    if (strncmp (auth, FIFO_PREFIX, CSTRLEN (FIFO_PREFIX)) == 0)
     227      {
     228        fifo_name = xstrdup (auth + CSTRLEN (FIFO_PREFIX));
     229  
     230        EINTRLOOP (job_fds[0], open (fifo_name, O_RDONLY));
     231        if (job_fds[0] < 0)
     232          OSS (fatal, NILF,
     233               _("Cannot open jobserver %s: %s"), fifo_name, strerror (errno));
     234  
     235        EINTRLOOP (job_fds[1], open (fifo_name, O_WRONLY));
     236        if (job_fds[0] < 0)
     237          OSS (fatal, NILF,
     238               _("Cannot open jobserver %s: %s"), fifo_name, strerror (errno));
     239  
     240        js_type = js_fifo;
     241      }
     242    /* If not, it must be a simple pipe.  */
     243    else if (sscanf (auth, "%d,%d", &rfd, &wfd) == 2)
     244      {
     245        /* The parent overrode our FDs because we aren't a recursive make.  */
     246        if (rfd == -2 || wfd == -2)
     247          return 0;
     248  
     249        /* Make sure our pipeline is valid.  */
     250        if (!FD_OK (rfd) || !FD_OK (wfd))
     251          return 0;
     252  
     253        job_fds[0] = rfd;
     254        job_fds[1] = wfd;
     255  
     256        js_type = js_pipe;
     257      }
     258    /* Who knows what it is?  */
     259    else
     260      {
     261        OS (error, NILF, _("invalid --jobserver-auth string '%s'"), auth);
     262        return 0;
     263      }
     264  
     265    /* Create a duplicate pipe, if needed, that will be closed in the SIGCHLD
     266       handler.  If this fails with EBADF, the parent closed the pipe on us as
     267       it didn't think we were a submake.  If so, warn and default to -j1.  */
     268  
     269    if (make_job_rfd () < 0)
     270      {
     271        if (errno != EBADF)
     272          pfatal_with_name ("jobserver readfd");
     273  
     274        jobserver_clear ();
     275  
     276        return 0;
     277      }
     278  
     279    /* When using pselect() we want the read to be non-blocking.  */
     280    set_blocking (job_fds[0], 0);
     281  
     282    /* By default we don't send the job pipe FDs to our children.
     283       See jobserver_pre_child() and jobserver_post_child().  */
     284    fd_noinherit (job_fds[0]);
     285    fd_noinherit (job_fds[1]);
     286  
     287    return 1;
     288  }
     289  
     290  char *
     291  jobserver_get_auth ()
     292  {
     293    char *auth;
     294  
     295    if (js_type == js_fifo) {
     296      auth = xmalloc (strlen (fifo_name) + CSTRLEN (FIFO_PREFIX) + 1);
     297      sprintf (auth, FIFO_PREFIX "%s", fifo_name);
     298    } else {
     299      auth = xmalloc ((INTSTR_LENGTH * 2) + 2);
     300      sprintf (auth, "%d,%d", job_fds[0], job_fds[1]);
     301    }
     302  
     303    return auth;
     304  }
     305  
     306  const char *
     307  jobserver_get_invalid_auth ()
     308  {
     309    /* If we're using a named pipe we don't need to invalidate the jobserver.  */
     310    if (js_type == js_fifo) {
     311      return NULL;
     312    }
     313  
     314    /* It's not really great that we are assuming the command line option
     315       here but other alternatives are also gross.  */
     316    return " --" JOBSERVER_AUTH_OPT "=-2,-2";
     317  }
     318  
     319  unsigned int
     320  jobserver_enabled ()
     321  {
     322    return js_type != js_none;
     323  }
     324  
     325  void
     326  jobserver_clear ()
     327  {
     328    if (job_fds[0] >= 0)
     329      close (job_fds[0]);
     330    if (job_fds[1] >= 0)
     331      close (job_fds[1]);
     332    if (job_rfd >= 0)
     333      close (job_rfd);
     334  
     335    job_fds[0] = job_fds[1] = job_rfd = -1;
     336  
     337    if (fifo_name)
     338      {
     339        if (job_root)
     340          {
     341            int r;
     342            EINTRLOOP (r, unlink (fifo_name));
     343          }
     344  
     345        if (!handling_fatal_signal)
     346          {
     347            free (fifo_name);
     348            fifo_name = NULL;
     349          }
     350      }
     351  
     352    js_type = js_none;
     353  }
     354  
     355  void
     356  jobserver_release (int is_fatal)
     357  {
     358    int r;
     359    EINTRLOOP (r, write (job_fds[1], &token, 1));
     360    if (r != 1)
     361      {
     362        if (is_fatal)
     363          pfatal_with_name (_("write jobserver"));
     364        perror_with_name ("write", "");
     365      }
     366  }
     367  
     368  unsigned int
     369  jobserver_acquire_all ()
     370  {
     371    int r;
     372    unsigned int tokens = 0;
     373  
     374    /* Use blocking reads to wait for all outstanding jobs.  */
     375    set_blocking (job_fds[0], 1);
     376  
     377    /* Close the write side, so the read() won't hang forever.  */
     378    close (job_fds[1]);
     379    job_fds[1] = -1;
     380  
     381    while (1)
     382      {
     383        char intake;
     384        EINTRLOOP (r, read (job_fds[0], &intake, 1));
     385        if (r != 1)
     386          break;
     387        ++tokens;
     388      }
     389  
     390    DB (DB_JOBS, ("Acquired all %u jobserver tokens.\n", tokens));
     391  
     392    jobserver_clear ();
     393  
     394    return tokens;
     395  }
     396  
     397  /* Prepare the jobserver to start a child process.  */
     398  void
     399  jobserver_pre_child (int recursive)
     400  {
     401    if (recursive && js_type == js_pipe)
     402      {
     403        fd_inherit (job_fds[0]);
     404        fd_inherit (job_fds[1]);
     405      }
     406  }
     407  
     408  /* Reconfigure the jobserver after starting a child process.  */
     409  void
     410  jobserver_post_child (int recursive)
     411  {
     412    if (recursive && js_type == js_pipe)
     413      {
     414        fd_noinherit (job_fds[0]);
     415        fd_noinherit (job_fds[1]);
     416      }
     417  }
     418  
     419  void
     420  jobserver_signal ()
     421  {
     422    if (job_rfd >= 0)
     423      {
     424        close (job_rfd);
     425        job_rfd = -1;
     426      }
     427  }
     428  
     429  void
     430  jobserver_pre_acquire ()
     431  {
     432    /* Make sure we have a dup'd FD.  */
     433    if (job_rfd < 0 && job_fds[0] >= 0 && make_job_rfd () < 0)
     434      pfatal_with_name (_("duping jobs pipe"));
     435  }
     436  
     437  #ifdef HAVE_PSELECT
     438  
     439  /* Use pselect() to atomically wait for both a signal and a file descriptor.
     440     It also provides a timeout facility so we don't need to use SIGALRM.
     441  
     442     This method relies on the fact that SIGCHLD will be blocked everywhere,
     443     and only unblocked (atomically) within the pselect() call, so we can
     444     never miss a SIGCHLD.
     445   */
     446  unsigned int
     447  jobserver_acquire (int timeout)
     448  {
     449    struct timespec spec;
     450    struct timespec *specp = NULL;
     451    sigset_t empty;
     452  
     453    sigemptyset (&empty);
     454  
     455    if (timeout)
     456      {
     457        /* Alarm after one second (is this too granular?)  */
     458        spec.tv_sec = 1;
     459        spec.tv_nsec = 0;
     460        specp = &spec;
     461      }
     462  
     463    while (1)
     464      {
     465        fd_set readfds;
     466        int r;
     467        char intake;
     468  
     469        FD_ZERO (&readfds);
     470        FD_SET (job_fds[0], &readfds);
     471  
     472        r = pselect (job_fds[0]+1, &readfds, NULL, NULL, specp, &empty);
     473        if (r < 0)
     474          switch (errno)
     475            {
     476            case EINTR:
     477              /* SIGCHLD will show up as an EINTR.  */
     478              return 0;
     479  
     480            case EBADF:
     481              /* Someone closed the jobs pipe.
     482                 That shouldn't happen but if it does we're done.  */
     483              O (fatal, NILF, _("job server shut down"));
     484  
     485            default:
     486              pfatal_with_name (_("pselect jobs pipe"));
     487            }
     488  
     489        if (r == 0)
     490          /* Timeout.  */
     491          return 0;
     492  
     493        /* The read FD is ready: read it!  This is non-blocking.  */
     494        EINTRLOOP (r, read (job_fds[0], &intake, 1));
     495  
     496        if (r < 0)
     497          {
     498            /* Someone sniped our token!  Try again.  */
     499            if (errno == EAGAIN)
     500              continue;
     501  
     502            pfatal_with_name (_("read jobs pipe"));
     503          }
     504  
     505        /* read() should never return 0: only the parent make can reap all the
     506           tokens and close the write side...??  */
     507        return r > 0;
     508      }
     509  }
     510  
     511  #else
     512  
     513  /* This method uses a "traditional" UNIX model for waiting on both a signal
     514     and a file descriptor.  However, it's complex and since we have a SIGCHLD
     515     handler installed we need to check ALL system calls for EINTR: painful!
     516  
     517     Read a token.  As long as there's no token available we'll block.  We
     518     enable interruptible system calls before the read(2) so that if we get a
     519     SIGCHLD while we're waiting, we'll return with EINTR and we can process the
     520     death(s) and return tokens to the free pool.
     521  
     522     Once we return from the read, we immediately reinstate restartable system
     523     calls.  This allows us to not worry about checking for EINTR on all the
     524     other system calls in the program.
     525  
     526     There is one other twist: there is a span between the time reap_children()
     527     does its last check for dead children and the time the read(2) call is
     528     entered, below, where if a child dies we won't notice.  This is extremely
     529     serious as it could cause us to deadlock, given the right set of events.
     530  
     531     To avoid this, we do the following: before we reap_children(), we dup(2)
     532     the read FD on the jobserver pipe.  The read(2) call below uses that new
     533     FD.  In the signal handler, we close that FD.  That way, if a child dies
     534     during the section mentioned above, the read(2) will be invoked with an
     535     invalid FD and will return immediately with EBADF.  */
     536  
     537  static void
     538  job_noop (int sig UNUSED)
     539  {
     540  }
     541  
     542  /* Set the child handler action flags to FLAGS.  */
     543  static void
     544  set_child_handler_action_flags (int set_handler, int set_alarm)
     545  {
     546    struct sigaction sa;
     547  
     548  #ifdef __EMX__
     549    /* The child handler must be turned off here.  */
     550    signal (SIGCHLD, SIG_DFL);
     551  #endif
     552  
     553    memset (&sa, '\0', sizeof sa);
     554    sa.sa_handler = child_handler;
     555    sa.sa_flags = set_handler ? 0 : SA_RESTART;
     556  
     557  #if defined SIGCHLD
     558    if (sigaction (SIGCHLD, &sa, NULL) < 0)
     559      pfatal_with_name ("sigaction: SIGCHLD");
     560  #endif
     561  
     562  #if defined SIGCLD && SIGCLD != SIGCHLD
     563    if (sigaction (SIGCLD, &sa, NULL) < 0)
     564      pfatal_with_name ("sigaction: SIGCLD");
     565  #endif
     566  
     567  #if defined SIGALRM
     568    if (set_alarm)
     569      {
     570        /* If we're about to enter the read(), set an alarm to wake up in a
     571           second so we can check if the load has dropped and we can start more
     572           work.  On the way out, turn off the alarm and set SIG_DFL.  */
     573        if (set_handler)
     574          {
     575            sa.sa_handler = job_noop;
     576            sa.sa_flags = 0;
     577            if (sigaction (SIGALRM, &sa, NULL) < 0)
     578              pfatal_with_name ("sigaction: SIGALRM");
     579            alarm (1);
     580          }
     581        else
     582          {
     583            alarm (0);
     584            sa.sa_handler = SIG_DFL;
     585            sa.sa_flags = 0;
     586            if (sigaction (SIGALRM, &sa, NULL) < 0)
     587              pfatal_with_name ("sigaction: SIGALRM");
     588          }
     589      }
     590  #endif
     591  }
     592  
     593  unsigned int
     594  jobserver_acquire (int timeout)
     595  {
     596    char intake;
     597    int got_token;
     598    int saved_errno;
     599  
     600    /* Set interruptible system calls, and read() for a job token.  */
     601    set_child_handler_action_flags (1, timeout);
     602  
     603    EINTRLOOP (got_token, read (job_rfd, &intake, 1));
     604    saved_errno = errno;
     605  
     606    set_child_handler_action_flags (0, timeout);
     607  
     608    if (got_token == 1)
     609      return 1;
     610  
     611    /* If the error _wasn't_ expected (EINTR or EBADF), fatal.  Otherwise,
     612       go back and reap_children(), and try again.  */
     613    errno = saved_errno;
     614  
     615    if (errno != EINTR && errno != EBADF)
     616      pfatal_with_name (_("read jobs pipe"));
     617  
     618    if (errno == EBADF)
     619      DB (DB_JOBS, ("Read returned EBADF.\n"));
     620  
     621    return 0;
     622  }
     623  
     624  #endif /* HAVE_PSELECT */
     625  
     626  #endif /* MAKE_JOBSERVER */
     627  
     628  #if !defined(NO_OUTPUT_SYNC)
     629  
     630  #define MUTEX_PREFIX    "fnm:"
     631  
     632  static int osync_handle = -1;
     633  
     634  static char *osync_tmpfile = NULL;
     635  
     636  static unsigned int sync_root = 0;
     637  
     638  unsigned int
     639  osync_enabled ()
     640  {
     641    return osync_handle >= 0;
     642  }
     643  
     644  void
     645  osync_setup ()
     646  {
     647    osync_handle = get_tmpfd (&osync_tmpfile);
     648    fd_noinherit (osync_handle);
     649    sync_root = 1;
     650  }
     651  
     652  char *
     653  osync_get_mutex ()
     654  {
     655    char *mutex = NULL;
     656  
     657    if (osync_enabled ())
     658      {
     659        /* Prepare the mutex handle string for our children.  */
     660        mutex = xmalloc (strlen (osync_tmpfile) + CSTRLEN (MUTEX_PREFIX) + 1);
     661        sprintf (mutex, MUTEX_PREFIX "%s", osync_tmpfile);
     662      }
     663  
     664    return mutex;
     665  }
     666  
     667  unsigned int
     668  osync_parse_mutex (const char *mutex)
     669  {
     670    if (strncmp (mutex, MUTEX_PREFIX, CSTRLEN (MUTEX_PREFIX)) != 0)
     671      {
     672        OS (error, NILF, _("invalid --sync-mutex string '%s'"), mutex);
     673        return 0;
     674      }
     675  
     676    free (osync_tmpfile);
     677    osync_tmpfile = xstrdup (mutex + CSTRLEN (MUTEX_PREFIX));
     678  
     679    EINTRLOOP (osync_handle, open (osync_tmpfile, O_WRONLY));
     680    if (osync_handle < 0)
     681      OSS (fatal, NILF, _("cannot open output sync mutex %s: %s"),
     682           osync_tmpfile, strerror (errno));
     683  
     684    fd_noinherit (osync_handle);
     685  
     686    return 1;
     687  }
     688  
     689  void
     690  osync_clear ()
     691  {
     692    if (osync_handle >= 0)
     693      {
     694        close (osync_handle);
     695        osync_handle = -1;
     696      }
     697  
     698    if (sync_root && osync_tmpfile)
     699      {
     700        int r;
     701  
     702        EINTRLOOP (r, unlink (osync_tmpfile));
     703        free (osync_tmpfile);
     704        osync_tmpfile = NULL;
     705      }
     706  }
     707  
     708  unsigned int
     709  osync_acquire ()
     710  {
     711    if (osync_enabled())
     712      {
     713        struct flock fl;
     714  
     715        fl.l_type = F_WRLCK;
     716        fl.l_whence = SEEK_SET;
     717        fl.l_start = 0;
     718        fl.l_len = 1;
     719        /* We don't want to keep waiting on EINTR.  */
     720        if (fcntl (osync_handle, F_SETLKW, &fl) == -1)
     721          {
     722            perror ("fcntl()");
     723            return 0;
     724          }
     725      }
     726  
     727    return 1;
     728  }
     729  
     730  void
     731  osync_release ()
     732  {
     733    if (osync_enabled())
     734      {
     735        struct flock fl;
     736  
     737        fl.l_type = F_UNLCK;
     738        fl.l_whence = SEEK_SET;
     739        fl.l_start = 0;
     740        fl.l_len = 1;
     741        /* We don't want to keep waiting on EINTR.  */
     742        if (fcntl (osync_handle, F_SETLKW, &fl) == -1)
     743          perror ("fcntl()");
     744      }
     745  }
     746  
     747  #endif
     748  
     749  /* Create a "bad" file descriptor for stdin when parallel jobs are run.  */
     750  int
     751  get_bad_stdin ()
     752  {
     753    static int bad_stdin = -1;
     754  
     755    /* Set up a bad standard input that reads from a broken pipe.  */
     756  
     757    if (bad_stdin == -1)
     758      {
     759        /* Make a file descriptor that is the read end of a broken pipe.
     760           This will be used for some children's standard inputs.  */
     761        int pd[2];
     762        if (pipe (pd) == 0)
     763          {
     764            /* Close the write side.  */
     765            close (pd[1]);
     766            /* Save the read side.  */
     767            bad_stdin = pd[0];
     768  
     769            /* Set the descriptor to close on exec, so it does not litter any
     770               child's descriptor table.  When it is dup2'd onto descriptor 0,
     771               that descriptor will not close on exec.  */
     772            fd_noinherit (bad_stdin);
     773          }
     774      }
     775  
     776    return bad_stdin;
     777  }
     778  
     779  /* Set file descriptors to be inherited / not inherited by subprocesses.  */
     780  
     781  #if !defined(F_SETFD) || !defined(F_GETFD)
     782  void fd_inherit (int fd) {}
     783  void fd_noinherit (int fd) {}
     784  
     785  #else
     786  
     787  # ifndef FD_CLOEXEC
     788  #  define FD_CLOEXEC 1
     789  # endif
     790  
     791  void
     792  fd_inherit (int fd)
     793  {
     794    int flags;
     795    EINTRLOOP (flags, fcntl (fd, F_GETFD));
     796    if (flags >= 0)
     797      {
     798        int r;
     799        flags &= ~FD_CLOEXEC;
     800        EINTRLOOP (r, fcntl (fd, F_SETFD, flags));
     801      }
     802  }
     803  
     804  void
     805  fd_noinherit (int fd)
     806  {
     807      int flags;
     808      EINTRLOOP (flags, fcntl(fd, F_GETFD));
     809      if (flags >= 0)
     810        {
     811          int r;
     812          flags |= FD_CLOEXEC;
     813          EINTRLOOP (r, fcntl(fd, F_SETFD, flags));
     814        }
     815  }
     816  #endif
     817  
     818  /* Set a file descriptor referring to a regular file to be in O_APPEND mode.
     819     If it fails, just ignore it.  */
     820  
     821  void
     822  fd_set_append (int fd)
     823  {
     824  #if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND)
     825    struct stat stbuf;
     826    int flags;
     827    if (fstat (fd, &stbuf) == 0 && S_ISREG (stbuf.st_mode))
     828      {
     829        flags = fcntl (fd, F_GETFL, 0);
     830        if (flags >= 0)
     831          {
     832            int r;
     833            EINTRLOOP(r, fcntl (fd, F_SETFL, flags | O_APPEND));
     834          }
     835      }
     836  #endif
     837  }
     838  
     839  /* Return a file descriptor for a new anonymous temp file, or -1.  */
     840  int
     841  os_anontmp ()
     842  {
     843    const char *tdir = get_tmpdir ();
     844    int fd = -1;
     845  
     846  #ifdef O_TMPFILE
     847    static unsigned int tmpfile_works = 1;
     848  
     849    if (tmpfile_works)
     850      {
     851        EINTRLOOP (fd, open (tdir, O_RDWR | O_TMPFILE | O_EXCL, 0600));
     852        if (fd >= 0)
     853          return fd;
     854  
     855        DB (DB_BASIC, (_("Cannot open '%s' with O_TMPFILE: %s.\n"),
     856                       tdir, strerror (errno)));
     857        tmpfile_works = 0;
     858      }
     859  #endif
     860  
     861  #if HAVE_DUP
     862    /* If we can dup and we are creating temp files in the default location then
     863       try tmpfile() + dup() + fclose() to avoid ever having a named file.  */
     864    if (streq (tdir, DEFAULT_TMPDIR))
     865      {
     866        mode_t mask = umask (0077);
     867        FILE *tfile;
     868        ENULLLOOP (tfile, tmpfile ());
     869        if (!tfile)
     870          pfatal_with_name ("tmpfile");
     871        umask (mask);
     872  
     873        EINTRLOOP (fd, dup (fileno (tfile)));
     874        if (fd < 0)
     875          pfatal_with_name ("dup");
     876        fclose (tfile);
     877      }
     878  #endif
     879  
     880    return fd;
     881  }