(root)/
m4-1.4.19/
tests/
test-pipe2.c
       1  /* Test of pipe2.
       2     Copyright (C) 2009-2021 Free Software Foundation, Inc.
       3  
       4     This program is free software; you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation; either version 3, or (at your option)
       7     any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program; if not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  #include <config.h>
      18  
      19  #include <unistd.h>
      20  
      21  #include "signature.h"
      22  SIGNATURE_CHECK (pipe2, int, (int[2], int));
      23  
      24  #include <fcntl.h>
      25  #include <stdbool.h>
      26  
      27  #if defined _WIN32 && ! defined __CYGWIN__
      28  /* Get declarations of the native Windows API functions.  */
      29  # define WIN32_LEAN_AND_MEAN
      30  # include <windows.h>
      31  /* Get _get_osfhandle.  */
      32  # if GNULIB_MSVC_NOTHROW
      33  #  include "msvc-nothrow.h"
      34  # else
      35  #  include <io.h>
      36  # endif
      37  #endif
      38  
      39  #include "binary-io.h"
      40  #include "macros.h"
      41  #if GNULIB_NONBLOCKING
      42  # include "nonblocking.h"
      43  #endif
      44  
      45  /* Return true if FD is open.  */
      46  static bool
      47  is_open (int fd)
      48  {
      49  #if defined _WIN32 && ! defined __CYGWIN__
      50    /* On native Windows, the initial state of unassigned standard file
      51       descriptors is that they are open but point to an
      52       INVALID_HANDLE_VALUE, and there is no fcntl.  */
      53    return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
      54  #else
      55  # ifndef F_GETFL
      56  #  error Please port fcntl to your platform
      57  # endif
      58    return 0 <= fcntl (fd, F_GETFL);
      59  #endif
      60  }
      61  
      62  /* Return true if FD is not inherited to child processes.  */
      63  static bool
      64  is_cloexec (int fd)
      65  {
      66  #if defined _WIN32 && ! defined __CYGWIN__
      67    HANDLE h = (HANDLE) _get_osfhandle (fd);
      68    DWORD flags;
      69    ASSERT (GetHandleInformation (h, &flags));
      70    return (flags & HANDLE_FLAG_INHERIT) == 0;
      71  #else
      72    int flags;
      73    ASSERT ((flags = fcntl (fd, F_GETFD)) >= 0);
      74    return (flags & FD_CLOEXEC) != 0;
      75  #endif
      76  }
      77  
      78  #if ! GNULIB_NONBLOCKING
      79  static int
      80  get_nonblocking_flag (int fd)
      81  {
      82  # if defined _WIN32 && ! defined __CYGWIN__
      83    return 0;
      84  # else
      85  #  ifndef F_GETFL
      86  #   error Please port fcntl to your platform
      87  #  endif
      88    int flags;
      89    ASSERT ((flags = fcntl (fd, F_GETFL)) >= 0);
      90    return (flags & O_NONBLOCK) != 0;
      91  # endif
      92  }
      93  #endif
      94  
      95  int
      96  main ()
      97  {
      98    int use_nonblocking;
      99    int use_cloexec;
     100  
     101    for (use_nonblocking = 0; use_nonblocking <= !!O_NONBLOCK; use_nonblocking++)
     102      for (use_cloexec = 0; use_cloexec <= !!O_CLOEXEC; use_cloexec++)
     103        {
     104          int o_flags;
     105          int fd[2];
     106  
     107          o_flags = 0;
     108          if (use_nonblocking)
     109            o_flags |= O_NONBLOCK;
     110          if (use_cloexec)
     111            o_flags |= O_CLOEXEC;
     112  
     113          fd[0] = -1;
     114          fd[1] = -1;
     115          ASSERT (pipe2 (fd, o_flags) >= 0);
     116          ASSERT (fd[0] >= 0);
     117          ASSERT (fd[1] >= 0);
     118          ASSERT (fd[0] != fd[1]);
     119          ASSERT (is_open (fd[0]));
     120          ASSERT (is_open (fd[1]));
     121          if (use_cloexec)
     122            {
     123              ASSERT (is_cloexec (fd[0]));
     124              ASSERT (is_cloexec (fd[1]));
     125            }
     126          else
     127            {
     128              ASSERT (!is_cloexec (fd[0]));
     129              ASSERT (!is_cloexec (fd[1]));
     130            }
     131          if (use_nonblocking)
     132            {
     133              ASSERT (get_nonblocking_flag (fd[0]) == 1);
     134              ASSERT (get_nonblocking_flag (fd[1]) == 1);
     135            }
     136          else
     137            {
     138              ASSERT (get_nonblocking_flag (fd[0]) == 0);
     139              ASSERT (get_nonblocking_flag (fd[1]) == 0);
     140            }
     141  
     142          ASSERT (close (fd[0]) == 0);
     143          ASSERT (close (fd[1]) == 0);
     144        }
     145  
     146    return 0;
     147  }