root/maint/gnulib/lib/nonblocking.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_nonblocking_flag
  2. set_nonblocking_flag
  3. get_nonblocking_flag
  4. set_nonblocking_flag

   1 /* Non-blocking I/O for pipe or socket descriptors.
   2    Copyright (C) 2011-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU Lesser General Public License as
   6    published by the Free Software Foundation; either version 2.1 of the
   7    License, or (at your option) any later version.
   8 
   9    This file 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 Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 #include <config.h>
  18 
  19 /* Specification.  */
  20 #include "nonblocking.h"
  21 
  22 #include <errno.h>
  23 
  24 #if defined _WIN32 && ! defined __CYGWIN__
  25 /* Native Windows API.  */
  26 
  27 # include <sys/ioctl.h>
  28 # include <sys/socket.h>
  29 # include <unistd.h>
  30 
  31 /* Get declarations of the native Windows API functions.  */
  32 # define WIN32_LEAN_AND_MEAN
  33 # include <windows.h>
  34 
  35 # if GNULIB_MSVC_NOTHROW
  36 #  include "msvc-nothrow.h"
  37 # else
  38 #  include <io.h>
  39 # endif
  40 
  41 /* Don't assume that UNICODE is not defined.  */
  42 # undef GetNamedPipeHandleState
  43 # define GetNamedPipeHandleState GetNamedPipeHandleStateA
  44 
  45 int
  46 get_nonblocking_flag (int desc)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48   HANDLE h = (HANDLE) _get_osfhandle (desc);
  49   if (h == INVALID_HANDLE_VALUE)
  50     {
  51       errno = EBADF;
  52       return -1;
  53     }
  54   if (GetFileType (h) == FILE_TYPE_PIPE)
  55     {
  56       /* h is a pipe or socket.  */
  57       DWORD state;
  58       if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0))
  59         /* h is a pipe.  */
  60         return (state & PIPE_NOWAIT) != 0;
  61       else
  62         /* h is a socket.  */
  63         errno = ENOSYS;
  64         return -1;
  65     }
  66   else
  67     /* The native Windows API does not support non-blocking on regular
  68        files.  */
  69     return 0;
  70 }
  71 
  72 int
  73 set_nonblocking_flag (int desc, bool value)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75   HANDLE h = (HANDLE) _get_osfhandle (desc);
  76   if (h == INVALID_HANDLE_VALUE)
  77     {
  78       errno = EBADF;
  79       return -1;
  80     }
  81   if (GetFileType (h) == FILE_TYPE_PIPE)
  82     {
  83       /* h is a pipe or socket.  */
  84       DWORD state;
  85       if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0))
  86         {
  87           /* h is a pipe.  */
  88           if ((state & PIPE_NOWAIT) != 0)
  89             {
  90               if (value)
  91                 return 0;
  92               state &= ~PIPE_NOWAIT;
  93             }
  94           else
  95             {
  96               if (!value)
  97                 return 0;
  98               state |= PIPE_NOWAIT;
  99             }
 100           if (SetNamedPipeHandleState (h, &state, NULL, NULL))
 101             return 0;
 102           errno = EINVAL;
 103           return -1;
 104         }
 105       else
 106         {
 107           /* h is a socket.  */
 108           int v = value;
 109           return ioctl (desc, FIONBIO, &v);
 110         }
 111     }
 112   else
 113     {
 114       /* The native Windows API does not support non-blocking on regular
 115          files.  */
 116       if (!value)
 117         return 0;
 118       errno = ENOTSUP;
 119       return -1;
 120     }
 121 }
 122 
 123 #else
 124 /* Unix API.  */
 125 
 126 # include <fcntl.h>
 127 
 128 # if GNULIB_defined_O_NONBLOCK
 129 #  error Please port nonblocking to your platform
 130 # endif
 131 
 132 /* We don't need the gnulib replacement of fcntl() here.  */
 133 # undef fcntl
 134 
 135 int
 136 get_nonblocking_flag (int desc)
     /* [previous][next][first][last][top][bottom][index][help] */
 137 {
 138   int fcntl_flags;
 139 
 140   fcntl_flags = fcntl (desc, F_GETFL, 0);
 141   if (fcntl_flags < 0)
 142     return -1;
 143   return (fcntl_flags & O_NONBLOCK) != 0;
 144 }
 145 
 146 int
 147 set_nonblocking_flag (int desc, bool value)
     /* [previous][next][first][last][top][bottom][index][help] */
 148 {
 149   int fcntl_flags;
 150 
 151   fcntl_flags = fcntl (desc, F_GETFL, 0);
 152   if (fcntl_flags < 0)
 153     return -1;
 154   if (((fcntl_flags & O_NONBLOCK) != 0) == value)
 155     return 0;
 156   if (value)
 157     fcntl_flags |= O_NONBLOCK;
 158   else
 159     fcntl_flags &= ~O_NONBLOCK;
 160   return fcntl (desc, F_SETFL, fcntl_flags);
 161 }
 162 
 163 #endif

/* [previous][next][first][last][top][bottom][index][help] */