(root)/
glibc-2.38/
sysdeps/
posix/
fpathconf.c
       1  /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library 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 GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <stddef.h>
      20  #include <unistd.h>
      21  #include <limits.h>
      22  #include <sys/stat.h>
      23  #include <sys/statfs.h>
      24  #include <sys/statvfs.h>
      25  
      26  
      27  /* Get file-specific information about descriptor FD.  */
      28  long int
      29  __fpathconf (int fd, int name)
      30  {
      31    if (fd < 0)
      32      {
      33        __set_errno (EBADF);
      34        return -1;
      35      }
      36  
      37    switch (name)
      38      {
      39      default:
      40        __set_errno (EINVAL);
      41        return -1;
      42  
      43      case _PC_LINK_MAX:
      44  #ifdef	LINK_MAX
      45        return LINK_MAX;
      46  #else
      47        return -1;
      48  #endif
      49  
      50      case _PC_MAX_CANON:
      51  #ifdef	MAX_CANON
      52        return MAX_CANON;
      53  #else
      54        return -1;
      55  #endif
      56  
      57      case _PC_MAX_INPUT:
      58  #ifdef	MAX_INPUT
      59        return MAX_INPUT;
      60  #else
      61        return -1;
      62  #endif
      63  
      64      case _PC_NAME_MAX:
      65  #ifdef	NAME_MAX
      66        {
      67  	struct statvfs64 sv;
      68  	int save_errno = errno;
      69  
      70  	if (__fstatvfs64 (fd, &sv) < 0)
      71  	  {
      72  	    if (errno == ENOSYS)
      73  	      {
      74  		__set_errno (save_errno);
      75  		return NAME_MAX;
      76  	      }
      77  	    else if (errno == ENODEV)
      78  	      __set_errno (EINVAL);
      79  
      80  	    return -1;
      81  	  }
      82  	else
      83  	  {
      84  	    return sv.f_namemax;
      85  	  }
      86        }
      87  #else
      88        return -1;
      89  #endif
      90  
      91      case _PC_PATH_MAX:
      92  #ifdef	PATH_MAX
      93        return PATH_MAX;
      94  #else
      95        return -1;
      96  #endif
      97  
      98      case _PC_PIPE_BUF:
      99  #ifdef	PIPE_BUF
     100        return PIPE_BUF;
     101  #else
     102        return -1;
     103  #endif
     104  
     105      case _PC_CHOWN_RESTRICTED:
     106  #if _POSIX_CHOWN_RESTRICTED == -1
     107  # error "Invalid value for _POSIX_CHOWN_RESTRICTED"
     108  #endif
     109        return _POSIX_CHOWN_RESTRICTED;
     110  
     111      case _PC_NO_TRUNC:
     112  #if _POSIX_NO_TRUNC == -1
     113  # error "Invalid value for _POSIX_NO_TRUNC"
     114  #endif
     115        return _POSIX_NO_TRUNC;
     116  
     117      case _PC_VDISABLE:
     118  #if _POSIX_VDISABLE == -1
     119  # error "Invalid value for _POSIX_VDISABLE"
     120  #endif
     121        return _POSIX_VDISABLE;
     122  
     123      case _PC_SYNC_IO:
     124  #ifdef	_POSIX_SYNC_IO
     125        return _POSIX_SYNC_IO;
     126  #else
     127        return -1;
     128  #endif
     129  
     130      case _PC_ASYNC_IO:
     131  #ifdef	_POSIX_ASYNC_IO
     132        {
     133  	/* AIO is only allowed on regular files and block devices.  */
     134  	struct __stat64_t64 st;
     135  
     136  	if (__fstat64_time64 (fd, &st) < 0
     137  	    || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode)))
     138  	  return -1;
     139  	else
     140  	  return 1;
     141        }
     142  #else
     143        return -1;
     144  #endif
     145  
     146      case _PC_PRIO_IO:
     147  #ifdef	_POSIX_PRIO_IO
     148        return _POSIX_PRIO_IO;
     149  #else
     150        return -1;
     151  #endif
     152  
     153      case _PC_SOCK_MAXBUF:
     154  #ifdef	SOCK_MAXBUF
     155        return SOCK_MAXBUF;
     156  #else
     157        return -1;
     158  #endif
     159  
     160      case _PC_FILESIZEBITS:
     161  #ifdef FILESIZEBITS
     162        return FILESIZEBITS;
     163  #else
     164        /* We let platforms with larger file sizes overwrite this value.  */
     165        return 32;
     166  #endif
     167  
     168      case _PC_REC_INCR_XFER_SIZE:
     169        /* XXX It is not entirely clear what the limit is supposed to do.
     170  	 What is incremented?  */
     171        return -1;
     172  
     173      case _PC_REC_MAX_XFER_SIZE:
     174        /* XXX It is not entirely clear what the limit is supposed to do.
     175  	 In general there is no top limit of the number of bytes which
     176  	 case be transported at once.  */
     177        return -1;
     178  
     179      case _PC_REC_MIN_XFER_SIZE:
     180        {
     181  	/* XXX It is not entirely clear what the limit is supposed to do.
     182  	   I assume this is the block size of the filesystem.  */
     183  	struct statvfs64 sv;
     184  
     185  	if (__fstatvfs64 (fd, &sv) < 0)
     186  	  return -1;
     187  	return sv.f_bsize;
     188        }
     189  
     190      case _PC_REC_XFER_ALIGN:
     191        {
     192  	/* XXX It is not entirely clear what the limit is supposed to do.
     193  	   I assume that the number should reflect the minimal block
     194  	   alignment.  */
     195  	struct statvfs64 sv;
     196  
     197  	if (__fstatvfs64 (fd, &sv) < 0)
     198  	  return -1;
     199  	return sv.f_frsize;
     200        }
     201  
     202      case _PC_ALLOC_SIZE_MIN:
     203        {
     204  	/* XXX It is not entirely clear what the limit is supposed to do.
     205  	   I assume that the number should reflect the minimal block
     206  	   alignment.  */
     207  	struct statvfs64 sv;
     208  
     209  	if (__fstatvfs64 (fd, &sv) < 0)
     210  	  return -1;
     211  	return sv.f_frsize;
     212        }
     213  
     214      case _PC_SYMLINK_MAX:
     215        /* In general there are no limits.  If a system has one it should
     216  	 overwrite this case.  */
     217        return -1;
     218  
     219      case _PC_2_SYMLINKS:
     220        /* Unix systems generally have symlinks.  */
     221        return 1;
     222      }
     223  }
     224  
     225  #undef __fpathconf
     226  weak_alias (__fpathconf, fpathconf)