(root)/
coreutils-9.4/
lib/
freadptr.c
       1  /* Retrieve information about a FILE stream.
       2     Copyright (C) 2007-2023 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 "freadptr.h"
      21  
      22  #include <stdlib.h>
      23  
      24  #include "stdio-impl.h"
      25  
      26  /* This file is not used on systems that have the __freadptr function,
      27     namely musl libc.  */
      28  
      29  const char *
      30  freadptr (FILE *fp, size_t *sizep)
      31  {
      32    size_t size;
      33  
      34    /* Keep this code in sync with freadahead!  */
      35  #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
      36    /* GNU libc, BeOS, Haiku, Linux libc5 */
      37    if (fp->_IO_write_ptr > fp->_IO_write_base)
      38      return NULL;
      39    size = fp->_IO_read_end - fp->_IO_read_ptr;
      40    if (size == 0)
      41      return NULL;
      42    *sizep = size;
      43    return (const char *) fp->_IO_read_ptr;
      44  #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
      45    /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
      46    if ((fp_->_flags & __SWR) != 0 || fp_->_r < 0)
      47      return NULL;
      48    size = fp_->_r;
      49    if (size == 0)
      50      return NULL;
      51    *sizep = size;
      52    return (const char *) fp_->_p;
      53  #elif defined __EMX__               /* emx+gcc */
      54    if ((fp->_flags & _IOWRT) != 0)
      55      return NULL;
      56    /* Note: fp->_ungetc_count > 0 implies fp->_rcount <= 0,
      57             fp->_ungetc_count = 0 implies fp->_rcount >= 0.  */
      58    if (fp->_rcount <= 0)
      59      return NULL;
      60    if (!(fp->_ungetc_count == 0))
      61      abort ();
      62    *sizep = fp->_rcount;
      63    return fp->_ptr;
      64  #elif defined __minix               /* Minix */
      65    if ((fp_->_flags & _IOWRITING) != 0)
      66      return NULL;
      67    size = fp_->_count;
      68    if (size == 0)
      69      return NULL;
      70    *sizep = size;
      71    return (const char *) fp_->_ptr;
      72  #elif defined _IOERR                /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */
      73    if ((fp_->_flag & _IOWRT) != 0)
      74      return NULL;
      75    size = fp_->_cnt;
      76    if (size == 0)
      77      return NULL;
      78    *sizep = size;
      79    return (const char *) fp_->_ptr;
      80  #elif defined __UCLIBC__            /* uClibc */
      81  # ifdef __STDIO_BUFFERS
      82    if (fp->__modeflags & __FLAG_WRITING)
      83      return NULL;
      84    if (fp->__modeflags & __FLAG_UNGOT)
      85      return NULL;
      86    size = fp->__bufread - fp->__bufpos;
      87    if (size == 0)
      88      return NULL;
      89    *sizep = size;
      90    return (const char *) fp->__bufpos;
      91  # else
      92    return NULL;
      93  # endif
      94  #elif defined __QNX__               /* QNX */
      95    if ((fp->_Mode & 0x2000 /* _MWRITE */) != 0)
      96      return NULL;
      97    /* fp->_Buf <= fp->_Next <= fp->_Rend */
      98    size = fp->_Rend - fp->_Next;
      99    if (size == 0)
     100      return NULL;
     101    *sizep = size;
     102    return (const char *) fp->_Next;
     103  #elif defined __MINT__              /* Atari FreeMiNT */
     104    if (!fp->__mode.__read)
     105      return NULL;
     106    size = fp->__get_limit - fp->__bufp;
     107    if (size == 0)
     108      return NULL;
     109    *sizep = size;
     110    return fp->__bufp;
     111  #elif defined EPLAN9                /* Plan9 */
     112    if (fp->state == 4 /* WR */)
     113      return NULL;
     114    if (fp->rp >= fp->wp)
     115      return NULL;
     116    *sizep = fp->wp - fp->rp;
     117    return fp->rp;
     118  #elif defined SLOW_BUT_NO_HACKS     /* users can define this */
     119    /* This implementation is correct on any ANSI C platform.  It is just
     120       awfully slow.  */
     121    return NULL;
     122  #else
     123   #error "Please port gnulib freadptr.c to your platform! Look at the definition of fflush, fread, getc, getc_unlocked on your system, then report this to bug-gnulib."
     124  #endif
     125  }