Blame sysdeps/posix/pathconf.c

Packit 6c4009
/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <stddef.h>
Packit 6c4009
#include <unistd.h>
Packit 6c4009
#include <limits.h>
Packit 6c4009
#include <fcntl.h>
Packit 6c4009
#include <sys/stat.h>
Packit 6c4009
#include <sys/statfs.h>
Packit 6c4009
#include <sys/statvfs.h>
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Get file-specific information about PATH.  */
Packit 6c4009
long int
Packit 6c4009
__pathconf (const char *path, int name)
Packit 6c4009
{
Packit 6c4009
  if (path[0] == '\0')
Packit 6c4009
    {
Packit 6c4009
      __set_errno (ENOENT);
Packit 6c4009
      return -1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  switch (name)
Packit 6c4009
    {
Packit 6c4009
    default:
Packit 6c4009
      __set_errno (EINVAL);
Packit 6c4009
      return -1;
Packit 6c4009
Packit 6c4009
    case _PC_LINK_MAX:
Packit 6c4009
#ifdef	LINK_MAX
Packit 6c4009
      return LINK_MAX;
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_MAX_CANON:
Packit 6c4009
#ifdef	MAX_CANON
Packit 6c4009
      return MAX_CANON;
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_MAX_INPUT:
Packit 6c4009
#ifdef	MAX_INPUT
Packit 6c4009
      return MAX_INPUT;
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_NAME_MAX:
Packit 6c4009
#ifdef	NAME_MAX
Packit 6c4009
      {
Packit 6c4009
	struct statvfs64 sv;
Packit 6c4009
	int save_errno = errno;
Packit 6c4009
Packit 6c4009
	if (__statvfs64 (path, &sv) < 0)
Packit 6c4009
	  {
Packit 6c4009
	    if (errno == ENOSYS)
Packit 6c4009
	      {
Packit 6c4009
		errno = save_errno;
Packit 6c4009
		return NAME_MAX;
Packit 6c4009
	      }
Packit 6c4009
	    return -1;
Packit 6c4009
	  }
Packit 6c4009
	else
Packit 6c4009
	  {
Packit 6c4009
	    return sv.f_namemax;
Packit 6c4009
	  }
Packit 6c4009
      }
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_PATH_MAX:
Packit 6c4009
#ifdef	PATH_MAX
Packit 6c4009
      return PATH_MAX;
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_PIPE_BUF:
Packit 6c4009
#ifdef	PIPE_BUF
Packit 6c4009
      return PIPE_BUF;
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_CHOWN_RESTRICTED:
Packit 6c4009
#if _POSIX_CHOWN_RESTRICTED == -1
Packit 6c4009
# error "Invalid value for _POSIX_CHOWN_RESTRICTED"
Packit 6c4009
#endif
Packit 6c4009
      return _POSIX_CHOWN_RESTRICTED;
Packit 6c4009
Packit 6c4009
    case _PC_NO_TRUNC:
Packit 6c4009
#if _POSIX_NO_TRUNC == -1
Packit 6c4009
# error "Invalid value for _POSIX_NO_TRUNC"
Packit 6c4009
#endif
Packit 6c4009
      return _POSIX_NO_TRUNC;
Packit 6c4009
Packit 6c4009
    case _PC_VDISABLE:
Packit 6c4009
#if _POSIX_VDISABLE == -1
Packit 6c4009
# error "Invalid value for _POSIX_VDISABLE"
Packit 6c4009
#endif
Packit 6c4009
      return _POSIX_VDISABLE;
Packit 6c4009
Packit 6c4009
    case _PC_SYNC_IO:
Packit 6c4009
#ifdef	_POSIX_SYNC_IO
Packit 6c4009
      return _POSIX_SYNC_IO;
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_ASYNC_IO:
Packit 6c4009
#ifdef	_POSIX_ASYNC_IO
Packit 6c4009
      {
Packit 6c4009
	/* AIO is only allowed on regular files and block devices.  */
Packit 6c4009
	struct stat64 st;
Packit 6c4009
Packit 6c4009
	if (__xstat64 (_STAT_VER, path, &st) < 0
Packit 6c4009
	    || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode)))
Packit 6c4009
	  return -1;
Packit 6c4009
	else
Packit 6c4009
	  return 1;
Packit 6c4009
      }
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_PRIO_IO:
Packit 6c4009
#ifdef	_POSIX_PRIO_IO
Packit 6c4009
      return _POSIX_PRIO_IO;
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_SOCK_MAXBUF:
Packit 6c4009
#ifdef	SOCK_MAXBUF
Packit 6c4009
      return SOCK_MAXBUF;
Packit 6c4009
#else
Packit 6c4009
      return -1;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_FILESIZEBITS:
Packit 6c4009
#ifdef FILESIZEBITS
Packit 6c4009
      return FILESIZEBITS;
Packit 6c4009
#else
Packit 6c4009
      /* We let platforms with larger file sizes overwrite this value.  */
Packit 6c4009
      return 32;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    case _PC_REC_INCR_XFER_SIZE:
Packit 6c4009
      /* XXX It is not entirely clear what the limit is supposed to do.
Packit 6c4009
	 What is incremented?  */
Packit 6c4009
      return -1;
Packit 6c4009
Packit 6c4009
    case _PC_REC_MAX_XFER_SIZE:
Packit 6c4009
      /* XXX It is not entirely clear what the limit is supposed to do.
Packit 6c4009
	 In general there is no top limit of the number of bytes which
Packit 6c4009
	 case be transported at once.  */
Packit 6c4009
      return -1;
Packit 6c4009
Packit 6c4009
    case _PC_REC_MIN_XFER_SIZE:
Packit 6c4009
      {
Packit 6c4009
	/* XXX It is not entirely clear what the limit is supposed to do.
Packit 6c4009
	   I assume this is the block size of the filesystem.  */
Packit 6c4009
	struct statvfs64 sv;
Packit 6c4009
Packit 6c4009
	if (__statvfs64 (path, &sv) < 0)
Packit 6c4009
	  return -1;
Packit 6c4009
	return sv.f_bsize;
Packit 6c4009
      }
Packit 6c4009
Packit 6c4009
    case _PC_REC_XFER_ALIGN:
Packit 6c4009
      {
Packit 6c4009
	/* XXX It is not entirely clear what the limit is supposed to do.
Packit 6c4009
	   I assume that the number should reflect the minimal block
Packit 6c4009
	   alignment.  */
Packit 6c4009
	struct statvfs64 sv;
Packit 6c4009
Packit 6c4009
	if (__statvfs64 (path, &sv) < 0)
Packit 6c4009
	  return -1;
Packit 6c4009
	return sv.f_frsize;
Packit 6c4009
      }
Packit 6c4009
Packit 6c4009
    case _PC_ALLOC_SIZE_MIN:
Packit 6c4009
      {
Packit 6c4009
	/* XXX It is not entirely clear what the limit is supposed to do.
Packit 6c4009
	   I assume that the number should reflect the minimal block
Packit 6c4009
	   alignment.  */
Packit 6c4009
	struct statvfs64 sv;
Packit 6c4009
Packit 6c4009
	if (__statvfs64 (path, &sv) < 0)
Packit 6c4009
	  return -1;
Packit 6c4009
	return sv.f_frsize;
Packit 6c4009
      }
Packit 6c4009
Packit 6c4009
    case _PC_SYMLINK_MAX:
Packit 6c4009
      /* In general there are no limits.  If a system has one it should
Packit 6c4009
	 overwrite this case.  */
Packit 6c4009
      return -1;
Packit 6c4009
Packit 6c4009
    case _PC_2_SYMLINKS:
Packit 6c4009
      /* Unix systems generally have symlinks.  */
Packit 6c4009
      return 1;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#undef __pathconf
Packit 6c4009
weak_alias (__pathconf, pathconf)