199836Swollman/*
299836Swollman * Copyright 2002 Massachusetts Institute of Technology
399836Swollman *
499836Swollman * Permission to use, copy, modify, and distribute this software and
599836Swollman * its documentation for any purpose and without fee is hereby
699836Swollman * granted, provided that both the above copyright notice and this
799836Swollman * permission notice appear in all copies, that both the above
899836Swollman * copyright notice and this permission notice appear in all
999836Swollman * supporting documentation, and that the name of M.I.T. not be used
1099836Swollman * in advertising or publicity pertaining to distribution of the
1199836Swollman * software without specific, written prior permission.  M.I.T. makes
1299836Swollman * no representations about the suitability of this software for any
1399836Swollman * purpose.  It is provided "as is" without express or implied
1499836Swollman * warranty.
1599836Swollman *
1699836Swollman * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
1799836Swollman * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
1899836Swollman * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1999836Swollman * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
2099836Swollman * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2199836Swollman * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2299836Swollman * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2399836Swollman * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2499836Swollman * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2599836Swollman * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2699836Swollman * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2799836Swollman * SUCH DAMAGE.
2899836Swollman */
2999836Swollman
3099836Swollman#include <sys/cdefs.h>
3199836Swollman__FBSDID("$FreeBSD$");
3299836Swollman
3399836Swollman#include "namespace.h"
3499836Swollman#include <sys/param.h>
3599836Swollman#include <sys/mount.h>
3699836Swollman#include <sys/statvfs.h>
3799836Swollman
3899836Swollman#include <errno.h>
3999836Swollman#include <limits.h>
4099836Swollman#include <unistd.h>
4199836Swollman#include "un-namespace.h"
4299836Swollman
4399836Swollmanstatic int	sfs2svfs(const struct statfs *from, struct statvfs *to);
4499836Swollman
4599836Swollmanint
4699836Swollmanfstatvfs(int fd, struct statvfs *result)
4799836Swollman{
4899836Swollman	struct statfs sfs;
4999836Swollman	int rv;
5099836Swollman	long pcval;
5199836Swollman
5299836Swollman	rv = _fstatfs(fd, &sfs);
5399836Swollman	if (rv != 0)
5499836Swollman		return (rv);
5599836Swollman
5699836Swollman	rv = sfs2svfs(&sfs, result);
5799836Swollman	if (rv != 0)
5899836Swollman		return (rv);
5999836Swollman
6099836Swollman	/*
6199836Swollman	 * Whether pathconf's -1 return means error or unlimited does not
6299836Swollman	 * make any difference in this best-effort implementation.
6399836Swollman	 */
6499836Swollman	pcval = _fpathconf(fd, _PC_NAME_MAX);
6599836Swollman	if (pcval == -1)
6699836Swollman		result->f_namemax = ~0UL;
6799836Swollman	else
6899836Swollman		result->f_namemax = (unsigned long)pcval;
6999836Swollman	return (0);
7099836Swollman}
7199836Swollman
7299836Swollmanint
73103012Stjrstatvfs(const char * __restrict path, struct statvfs * __restrict result)
7499836Swollman{
7599836Swollman	struct statfs sfs;
7699836Swollman	int rv;
7799836Swollman	long pcval;
7899836Swollman
7999836Swollman	rv = statfs(path, &sfs);
8099836Swollman	if (rv != 0)
8199836Swollman		return (rv);
8299836Swollman
8399836Swollman	sfs2svfs(&sfs, result);
8499836Swollman
8599836Swollman	/*
8699836Swollman	 * Whether pathconf's -1 return means error or unlimited does not
8799836Swollman	 * make any difference in this best-effort implementation.
8899836Swollman	 */
8999836Swollman	pcval = pathconf(path, _PC_NAME_MAX);
9099836Swollman	if (pcval == -1)
9199836Swollman		result->f_namemax = ~0UL;
9299836Swollman	else
9399836Swollman		result->f_namemax = (unsigned long)pcval;
9499836Swollman	return (0);
9599836Swollman}
9699836Swollman
9799836Swollmanstatic int
9899836Swollmansfs2svfs(const struct statfs *from, struct statvfs *to)
9999836Swollman{
10099836Swollman	static const struct statvfs zvfs;
10199836Swollman
10299836Swollman	*to = zvfs;
10399836Swollman
10499836Swollman	if (from->f_flags & MNT_RDONLY)
10599836Swollman		to->f_flag |= ST_RDONLY;
10699836Swollman	if (from->f_flags & MNT_NOSUID)
10799836Swollman		to->f_flag |= ST_NOSUID;
10899836Swollman
10999836Swollman	/* XXX should we clamp negative values? */
11099836Swollman#define COPY(field) \
11199836Swollman	do { \
11299836Swollman		to->field = from->field; \
11399836Swollman		if (from->field != to->field) { \
11499836Swollman			errno = EOVERFLOW; \
11599836Swollman			return (-1); \
11699836Swollman		} \
11799836Swollman	} while(0)
11899836Swollman
11999836Swollman	COPY(f_bavail);
12099836Swollman	COPY(f_bfree);
12199836Swollman	COPY(f_blocks);
12299836Swollman	COPY(f_ffree);
12399836Swollman	COPY(f_files);
12499836Swollman	to->f_bsize = from->f_iosize;
12599836Swollman	to->f_frsize = from->f_bsize;
12699836Swollman	to->f_favail = to->f_ffree;
12799836Swollman	return (0);
12899836Swollman}
12999836Swollman
13099836Swollman#ifdef MAIN
13199836Swollman#include <err.h>
13299836Swollman#include <stdint.h>
13399836Swollman#include <stdio.h>
13499836Swollman
13599836Swollmanint
13699836Swollmanmain(int argc, char **argv)
13799836Swollman{
13899836Swollman	struct statvfs buf;
13999836Swollman
14099836Swollman	if (statvfs(argv[1], &buf) < 0)
14199836Swollman		err(1, "statvfs");
14299836Swollman
14399836Swollman#define SHOW(field) \
14499836Swollman	printf(#field ": %ju\n", (uintmax_t)buf.field)
14599836Swollman
14699836Swollman	SHOW(f_bavail);
14799836Swollman	SHOW(f_bfree);
14899836Swollman	SHOW(f_blocks);
14999836Swollman	SHOW(f_favail);
15099836Swollman	SHOW(f_ffree);
15199836Swollman	SHOW(f_files);
15299836Swollman	SHOW(f_bsize);
15399836Swollman	SHOW(f_frsize);
15499836Swollman	SHOW(f_namemax);
15599836Swollman	printf("f_flag: %lx\n", (unsigned long)buf.f_flag);
15699836Swollman
15799836Swollman	return 0;
15899836Swollman}
15999836Swollman
16099836Swollman#endif /* MAIN */
161