Home | History | Annotate | Download | only in bionic
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <unistd.h>
     30 
     31 #include <errno.h>
     32 #include <limits.h>
     33 #include <sys/vfs.h>
     34 
     35 static long __filesizebits(const struct statfs& s) {
     36   switch (s.f_type) {
     37     case JFFS2_SUPER_MAGIC:
     38     case MSDOS_SUPER_MAGIC:
     39     case NCP_SUPER_MAGIC:
     40       return 32;
     41   }
     42   // There won't be any new 32-bit file systems.
     43   return 64;
     44 }
     45 
     46 static long __link_max(const struct statfs& s) {
     47   // These constant values were taken from kernel headers.
     48   // They're not available in uapi headers.
     49   switch (s.f_type) {
     50     case EXT2_SUPER_MAGIC:
     51       return 32000;
     52     case MINIX_SUPER_MAGIC:
     53       return 250;
     54     case MINIX2_SUPER_MAGIC:
     55       return 65530;
     56     case REISERFS_SUPER_MAGIC:
     57       return 0xffff - 1000;
     58     case UFS_MAGIC:
     59       return 32000;
     60   }
     61   return LINK_MAX;
     62 }
     63 
     64 static long __2_symlinks(const struct statfs& s) {
     65   switch (s.f_type) {
     66     case ADFS_SUPER_MAGIC:
     67     case BFS_MAGIC:
     68     case CRAMFS_MAGIC:
     69     case EFS_SUPER_MAGIC:
     70     case MSDOS_SUPER_MAGIC:
     71     case QNX4_SUPER_MAGIC:
     72       return 0;
     73   }
     74   return 1;
     75 }
     76 
     77 static long __pathconf(const struct statfs& s, int name) {
     78   switch (name) {
     79     case _PC_FILESIZEBITS:
     80       return __filesizebits(s);
     81 
     82     case _PC_LINK_MAX:
     83       return __link_max(s);
     84 
     85     case _PC_MAX_CANON:
     86       return MAX_CANON;
     87 
     88     case _PC_MAX_INPUT:
     89       return MAX_INPUT;
     90 
     91     case _PC_NAME_MAX:
     92       return s.f_namelen;
     93 
     94     case _PC_PATH_MAX:
     95       return PATH_MAX;
     96 
     97     case _PC_PIPE_BUF:
     98       return PIPE_BUF;
     99 
    100     case _PC_2_SYMLINKS:
    101       return __2_symlinks(s);
    102 
    103     case _PC_ALLOC_SIZE_MIN:  /* fall through */
    104     case _PC_REC_XFER_ALIGN:
    105       return s.f_frsize;
    106 
    107     case _PC_REC_MIN_XFER_SIZE:
    108       return s.f_bsize;
    109 
    110 #if 0
    111     case _PC_REC_INCR_XFER_SIZE:
    112     case _PC_REC_MAX_XFER_SIZE:
    113 #endif
    114 
    115     case _PC_SYMLINK_MAX:
    116       return -1; /* no limit */
    117 
    118     case _PC_CHOWN_RESTRICTED:
    119       return _POSIX_CHOWN_RESTRICTED;
    120 
    121     case _PC_NO_TRUNC:
    122       return _POSIX_NO_TRUNC;
    123 
    124     case _PC_VDISABLE:
    125       return _POSIX_VDISABLE;
    126 
    127     case _PC_ASYNC_IO:
    128       return -1;
    129 
    130     case _PC_PRIO_IO:
    131       return -1;
    132 
    133     case _PC_SYNC_IO:
    134       return -1;
    135 
    136     default:
    137       errno = EINVAL;
    138       return -1;
    139   }
    140 }
    141 
    142 long pathconf(const char* path, int name) {
    143   struct statfs sb;
    144   if (statfs(path, &sb) == -1) {
    145     return -1;
    146   }
    147   return __pathconf(sb, name);
    148 }
    149 
    150 long fpathconf(int fd, int name) {
    151   struct statfs sb;
    152   if (fstatfs(fd, &sb) == -1) {
    153     return -1;
    154   }
    155   return __pathconf(sb, name);
    156 }
    157