/* POSIX compatible FILE stream read function.
   Copyright (C) 2008-2022 Free Software Foundation, Inc.
   Written by Bruno Haible <bruno@clisp.org>, 2011.

   This file is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation; either version 2.1 of the
   License, or (at your option) any later version.

   This file is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <stdio.h>

/* Replace these functions only if module 'nonblocking' is requested.  */
#if GNULIB_NONBLOCKING

/* On native Windows platforms, when read() is called on a non-blocking pipe
   with an empty buffer, ReadFile() fails with error GetLastError() =
   ERROR_NO_DATA, and read() in consequence fails with error EINVAL.  This
   read() function is at the basis of the function which fills the buffer of
   a FILE stream.  */

# if defined _WIN32 && ! defined __CYGWIN__

#  include <errno.h>
#  include <io.h>

#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
#  include <windows.h>

#  if GNULIB_MSVC_NOTHROW
#   include "msvc-nothrow.h"
#  else
#   include <io.h>
#  endif

/* Don't assume that UNICODE is not defined.  */
#  undef GetNamedPipeHandleState
#  define GetNamedPipeHandleState GetNamedPipeHandleStateA

#  define CALL_WITH_ERRNO_FIX(RETTYPE, EXPRESSION, FAILED) \
  if (ferror (stream))                                                        \
    return (EXPRESSION);                                                      \
  else                                                                        \
    {                                                                         \
      RETTYPE ret;                                                            \
      SetLastError (0);                                                       \
      ret = (EXPRESSION);                                                     \
      if (FAILED)                                                             \
        {                                                                     \
          if (GetLastError () == ERROR_NO_DATA && ferror (stream))            \
            {                                                                 \
              int fd = fileno (stream);                                       \
              if (fd >= 0)                                                    \
                {                                                             \
                  HANDLE h = (HANDLE) _get_osfhandle (fd);                    \
                  if (GetFileType (h) == FILE_TYPE_PIPE)                      \
                    {                                                         \
                      /* h is a pipe or socket.  */                           \
                      DWORD state;                                            \
                      if (GetNamedPipeHandleState (h, &state, NULL, NULL,     \
                                                   NULL, NULL, 0)             \
                          && (state & PIPE_NOWAIT) != 0)                      \
                        /* h is a pipe in non-blocking mode.                  \
                           Change errno from EINVAL to EAGAIN.  */            \
                        errno = EAGAIN;                                       \
                    }                                                         \
                }                                                             \
            }                                                                 \
        }                                                                     \
      return ret;                                                             \
    }

/* Enable this function definition only if gnulib's <stdio.h> has prepared it.
   Otherwise we get a function definition conflict with mingw64's <stdio.h>.  */
#  if GNULIB_SCANF
int
scanf (const char *format, ...)
{
  int retval;
  va_list args;

  va_start (args, format);
  retval = vfscanf (stdin, format, args);
  va_end (args);

  return retval;
}
#  endif

/* Enable this function definition only if gnulib's <stdio.h> has prepared it.
   Otherwise we get a function definition conflict with mingw64's <stdio.h>.  */
#  if GNULIB_FSCANF
int
fscanf (FILE *stream, const char *format, ...)
{
  int retval;
  va_list args;

  va_start (args, format);
  retval = vfscanf (stream, format, args);
  va_end (args);

  return retval;
}
#  endif

/* Enable this function definition only if gnulib's <stdio.h> has prepared it.
   Otherwise we get a function definition conflict with mingw64's <stdio.h>.  */
#  if GNULIB_VSCANF
int
vscanf (const char *format, va_list args)
{
  return vfscanf (stdin, format, args);
}
#  endif

/* Enable this function definition only if gnulib's <stdio.h> has prepared it.
   Otherwise we get a function definition conflict with mingw64's <stdio.h>.  */
#  if GNULIB_VFSCANF
int
vfscanf (FILE *stream, const char *format, va_list args)
#undef vfscanf
{
  CALL_WITH_ERRNO_FIX (int, vfscanf (stream, format, args), ret == EOF)
}
#  endif

int
getchar (void)
{
  return fgetc (stdin);
}

int
fgetc (FILE *stream)
#undef fgetc
{
  CALL_WITH_ERRNO_FIX (int, fgetc (stream), ret == EOF)
}

char *
fgets (char *s, int n, FILE *stream)
#undef fgets
{
  CALL_WITH_ERRNO_FIX (char *, fgets (s, n, stream), ret == NULL)
}

/* We intentionally don't bother to fix gets.  */

size_t
fread (void *ptr, size_t s, size_t n, FILE *stream)
#undef fread
{
  CALL_WITH_ERRNO_FIX (size_t, fread (ptr, s, n, stream), ret < n)
}

# endif
#endif
