(root)/
gettext-0.22.4/
gettext-tools/
gnulib-tests/
test-pipe2.c
       1  /* Test of pipe2.
       2     Copyright (C) 2009-2023 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  
      26  #if defined _WIN32 && ! defined __CYGWIN__
      27  /* Get declarations of the native Windows API functions.  */
      28  # define WIN32_LEAN_AND_MEAN
      29  # include <windows.h>
      30  /* Get _get_osfhandle.  */
      31  # if GNULIB_MSVC_NOTHROW
      32  #  include "msvc-nothrow.h"
      33  # else
      34  #  include <io.h>
      35  # endif
      36  #endif
      37  
      38  #include "binary-io.h"
      39  #include "macros.h"
      40  #if GNULIB_NONBLOCKING
      41  # include "nonblocking.h"
      42  #endif
      43  
      44  /* Return true if FD is open.  */
      45  static bool
      46  is_open (int fd)
      47  {
      48  #if defined _WIN32 && ! defined __CYGWIN__
      49    /* On native Windows, the initial state of unassigned standard file
      50       descriptors is that they are open but point to an
      51       INVALID_HANDLE_VALUE, and there is no fcntl.  */
      52    return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
      53  #else
      54  # ifndef F_GETFL
      55  #  error Please port fcntl to your platform
      56  # endif
      57    return 0 <= fcntl (fd, F_GETFL);
      58  #endif
      59  }
      60  
      61  /* Return true if FD is not inherited to child processes.  */
      62  static bool
      63  is_cloexec (int fd)
      64  {
      65  #if defined _WIN32 && ! defined __CYGWIN__
      66    HANDLE h = (HANDLE) _get_osfhandle (fd);
      67    DWORD flags;
      68    ASSERT (GetHandleInformation (h, &flags));
      69    return (flags & HANDLE_FLAG_INHERIT) == 0;
      70  #else
      71    int flags;
      72    ASSERT ((flags = fcntl (fd, F_GETFD)) >= 0);
      73    return (flags & FD_CLOEXEC) != 0;
      74  #endif
      75  }
      76  
      77  #if ! GNULIB_NONBLOCKING
      78  static int
      79  get_nonblocking_flag (int fd)
      80  {
      81  # if defined _WIN32 && ! defined __CYGWIN__
      82    return 0;
      83  # else
      84  #  ifndef F_GETFL
      85  #   error Please port fcntl to your platform
      86  #  endif
      87    int flags;
      88    ASSERT ((flags = fcntl (fd, F_GETFL)) >= 0);
      89    return (flags & O_NONBLOCK) != 0;
      90  # endif
      91  }
      92  #endif
      93  
      94  int
      95  main ()
      96  {
      97    int use_nonblocking;
      98    int use_cloexec;
      99  
     100    for (use_nonblocking = 0; use_nonblocking <= !!O_NONBLOCK; use_nonblocking++)
     101      for (use_cloexec = 0; use_cloexec <= !!O_CLOEXEC; use_cloexec++)
     102        {
     103          int o_flags;
     104          int fd[2];
     105  
     106          o_flags = 0;
     107          if (use_nonblocking)
     108            o_flags |= O_NONBLOCK;
     109          if (use_cloexec)
     110            o_flags |= O_CLOEXEC;
     111  
     112          fd[0] = -1;
     113          fd[1] = -1;
     114          ASSERT (pipe2 (fd, o_flags) >= 0);
     115          ASSERT (fd[0] >= 0);
     116          ASSERT (fd[1] >= 0);
     117          ASSERT (fd[0] != fd[1]);
     118          ASSERT (is_open (fd[0]));
     119          ASSERT (is_open (fd[1]));
     120          if (use_cloexec)
     121            {
     122              ASSERT (is_cloexec (fd[0]));
     123              ASSERT (is_cloexec (fd[1]));
     124            }
     125          else
     126            {
     127              ASSERT (!is_cloexec (fd[0]));
     128              ASSERT (!is_cloexec (fd[1]));
     129            }
     130          if (use_nonblocking)
     131            {
     132              ASSERT (get_nonblocking_flag (fd[0]) == 1);
     133              ASSERT (get_nonblocking_flag (fd[1]) == 1);
     134            }
     135          else
     136            {
     137              ASSERT (get_nonblocking_flag (fd[0]) == 0);
     138              ASSERT (get_nonblocking_flag (fd[1]) == 0);
     139            }
     140  
     141          ASSERT (close (fd[0]) == 0);
     142          ASSERT (close (fd[1]) == 0);
     143        }
     144  
     145    return 0;
     146  }