~ubuntu-branches/ubuntu/utopic/coreutils/utopic-proposed

« back to all changes in this revision

Viewing changes to lib/fsusage.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2012-11-28 03:03:42 UTC
  • mfrom: (8.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20121128030342-21zanj8354gas5gr
Tags: 8.20-3ubuntu1
* Resynchronise with Debian.  Remaining changes:
  - Make 'uname -i -p' return the real processor/hardware, instead of
    unknown.
  - Build-depend on gettext:any instead of on gettext, so that apt-get can
    properly resolve build-dependencies on the tool when cross-building.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* fsusage.c -- return space usage of mounted file systems
2
2
 
3
 
   Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2011 Free Software
 
3
   Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2012 Free Software
4
4
   Foundation, Inc.
5
5
 
6
6
   This program is free software: you can redistribute it and/or modify
31
31
# include <fcntl.h>
32
32
# include <unistd.h>
33
33
# include <sys/stat.h>
34
 
# if HAVE_SYS_PARAM_H
35
 
#  include <sys/param.h>
36
 
# endif
37
 
# if HAVE_SYS_MOUNT_H
38
 
#  include <sys/mount.h>
39
 
# endif
40
 
# if HAVE_SYS_VFS_H
41
 
#  include <sys/vfs.h>
42
 
# endif
 
34
#if HAVE_SYS_PARAM_H
 
35
# include <sys/param.h>
 
36
#endif
 
37
#if HAVE_SYS_MOUNT_H
 
38
# include <sys/mount.h>
 
39
#endif
 
40
#if HAVE_SYS_VFS_H
 
41
# include <sys/vfs.h>
 
42
#endif
43
43
# if HAVE_SYS_FS_S5PARAM_H      /* Fujitsu UXP/V */
44
44
#  include <sys/fs/s5param.h>
45
45
# endif
84
84
   otherwise, use PROPAGATE_ALL_ONES.  */
85
85
#define PROPAGATE_TOP_BIT(x) ((x) | ~ (EXTRACT_TOP_BIT (x) - 1))
86
86
 
 
87
#ifdef STAT_STATVFS
 
88
/* Return true if statvfs works.  This is false for statvfs on systems
 
89
   with GNU libc on Linux kernels before 2.6.36, which stats all
 
90
   preceding entries in /proc/mounts; that makes df hang if even one
 
91
   of the corresponding file systems is hard-mounted but not available.  */
 
92
# if ! (__linux__ && (__GLIBC__ || __UCLIBC__))
 
93
/* The FRSIZE fallback is not required in this case.  */
 
94
#  undef STAT_STATFS2_FRSIZE
 
95
static int statvfs_works (void) { return 1; }
 
96
# else
 
97
#  include <string.h> /* for strverscmp */
 
98
#  include <sys/utsname.h>
 
99
#  include <sys/statfs.h>
 
100
#  define STAT_STATFS2_BSIZE 1
 
101
 
 
102
static int
 
103
statvfs_works (void)
 
104
{
 
105
  static int statvfs_works_cache = -1;
 
106
  struct utsname name;
 
107
  if (statvfs_works_cache < 0)
 
108
    statvfs_works_cache = (uname (&name) == 0
 
109
                           && 0 <= strverscmp (name.release, "2.6.36"));
 
110
  return statvfs_works_cache;
 
111
}
 
112
# endif
 
113
#endif
 
114
 
 
115
 
87
116
/* Fill in the fields of FSP with information about space usage for
88
117
   the file system on which FILE resides.
89
118
   DISK is the device on which FILE is mounted, for space-getting
94
123
int
95
124
get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
96
125
{
97
 
#if defined STAT_STATVFS                /* POSIX, except glibc/Linux */
98
 
 
99
 
  struct statvfs fsd;
100
 
 
101
 
  if (statvfs (file, &fsd) < 0)
102
 
    return -1;
103
 
 
104
 
  /* f_frsize isn't guaranteed to be supported.  */
105
 
  fsp->fsu_blocksize = (fsd.f_frsize
106
 
                        ? PROPAGATE_ALL_ONES (fsd.f_frsize)
107
 
                        : PROPAGATE_ALL_ONES (fsd.f_bsize));
108
 
 
109
 
#elif defined STAT_STATVFS64            /* AIX */
 
126
#ifdef STAT_STATVFS     /* POSIX, except pre-2.6.36 glibc/Linux */
 
127
 
 
128
  if (statvfs_works ())
 
129
    {
 
130
      struct statvfs vfsd;
 
131
 
 
132
      if (statvfs (file, &vfsd) < 0)
 
133
        return -1;
 
134
 
 
135
      /* f_frsize isn't guaranteed to be supported.  */
 
136
      fsp->fsu_blocksize = (vfsd.f_frsize
 
137
                            ? PROPAGATE_ALL_ONES (vfsd.f_frsize)
 
138
                            : PROPAGATE_ALL_ONES (vfsd.f_bsize));
 
139
 
 
140
      fsp->fsu_blocks = PROPAGATE_ALL_ONES (vfsd.f_blocks);
 
141
      fsp->fsu_bfree = PROPAGATE_ALL_ONES (vfsd.f_bfree);
 
142
      fsp->fsu_bavail = PROPAGATE_TOP_BIT (vfsd.f_bavail);
 
143
      fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (vfsd.f_bavail) != 0;
 
144
      fsp->fsu_files = PROPAGATE_ALL_ONES (vfsd.f_files);
 
145
      fsp->fsu_ffree = PROPAGATE_ALL_ONES (vfsd.f_ffree);
 
146
      return 0;
 
147
    }
 
148
 
 
149
#endif
 
150
 
 
151
#if defined STAT_STATVFS64            /* AIX */
110
152
 
111
153
  struct statvfs64 fsd;
112
154
 
177
219
 
178
220
  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);
179
221
 
180
 
#elif defined STAT_STATFS2_BSIZE        /* glibc/Linux, 4.3BSD, SunOS 4, \
181
 
                                           MacOS X < 10.4, FreeBSD < 5.0, \
 
222
#elif defined STAT_STATFS2_FRSIZE        /* 2.6 < glibc/Linux < 2.6.36 */
 
223
 
 
224
  struct statfs fsd;
 
225
 
 
226
  if (statfs (file, &fsd) < 0)
 
227
    return -1;
 
228
 
 
229
  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_frsize);
 
230
 
 
231
#elif defined STAT_STATFS2_BSIZE        /* glibc/Linux < 2.6, 4.3BSD, SunOS 4, \
 
232
                                           Mac OS X < 10.4, FreeBSD < 5.0, \
182
233
                                           NetBSD < 3.0, OpenBSD < 4.4 */
183
234
 
184
235
  struct statfs fsd;
235
286
 
236
287
#endif
237
288
 
238
 
#if (defined STAT_STATVFS || defined STAT_STATVFS64 \
239
 
     || (!defined STAT_STATFS2_FS_DATA && !defined STAT_READ_FILSYS))
 
289
#if (defined STAT_STATVFS64 || defined STAT_STATFS3_OSF1                \
 
290
     || defined STAT_STATFS2_FRSIZE || defined STAT_STATFS2_BSIZE       \
 
291
     || defined STAT_STATFS2_FSIZE || defined STAT_STATFS4)
240
292
 
241
293
  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks);
242
294
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.f_bfree);