blob: 3af421edd040d4b2f10ee235ac59537d9a205118 [file] [log] [blame]
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifdef __linux__
#include <sys/statvfs.h>
#include <sys/vfs.h>
#else
#include <sys/param.h>
#include <sys/mount.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <debug.h>
#include "fcalls.h"
#include "main.h"
#include "util.h"
void FsTest (void)
{
#ifdef __linux__
struct statfs s1;
struct statfs s2;
struct statvfs v1;
struct statvfs v2;
int fd = open(".", O_RDONLY, 0);
statfs(".", &s1);
fstatfs(fd, &s2);
statvfs(".", &v1);
fstatvfs(fd, &v2);
if (Local_option.flaky) {
/* Can't be sure file system values won't change between calls */
CheckEq(&s1, &s2, sizeof(s1));
CheckEq(&v1, &v2, sizeof(v1));
Check(s1.f_bsize == v1.f_bsize);
Check(s1.f_blocks == v1.f_blocks);
Check(s1.f_bfree == v1.f_bfree);
Check(s1.f_bavail == v1.f_bavail);
Check(s1.f_files == v1.f_files);
Check(s1.f_ffree == v1.f_ffree);
Check(s1.f_namelen == v1.f_namemax);
}
close(fd);
#endif
}
void StatTest (void)
{
enum { FILE_SZ = 1759,
FILE_TRUNC = 17,
FILE_GROW = 10937,
USER_A = 12345,
GROUP_A = 23456,
USER_B = 65431,
GROUP_B = 76543 };
struct stat s1;
struct stat s2;
char *name = RndName();
CrFile(name, FILE_SZ);
stat(name, &s1);
int fd = open(name, O_RDONLY, 0);
fstat(fd, &s2);
CheckEq(&s1, &s2, sizeof(s1));
Check(s1.st_size == FILE_SZ);
close(fd);
if (Local_option.is_root) {
chown(name, USER_A, GROUP_A);
stat(name, &s1);
Check(s1.st_uid == USER_A);
Check(s1.st_gid == GROUP_A);
fd = open(name, O_RDWR, 0);
fchown(fd, USER_B, GROUP_B);
fstat(fd, &s1);
Check(s1.st_uid == USER_B);
Check(s1.st_gid == GROUP_B);
close(fd);
}
/* Truncate can both shrink and grow a file */
truncate(name, FILE_TRUNC);
stat(name, &s1);
Check(s1.st_size == FILE_TRUNC);
truncate(name, FILE_GROW);
stat(name, &s1);
Check(s1.st_size == FILE_GROW);
fd = open(name, O_RDWR, 0);
ftruncate(fd, FILE_TRUNC);
fstat(fd, &s1);
Check(s1.st_size == FILE_TRUNC);
ftruncate(fd, FILE_GROW);
fstat(fd, &s1);
Check(s1.st_size == FILE_GROW);
close(fd);
fd = open(name, O_RDONLY, 0);
ftruncateErr(EINVAL, fd, FILE_TRUNC);
fstat(fd, &s1);
Check(s1.st_size == FILE_GROW);
close(fd);
/* Dup - fds share seek pointer */
int fd1 = open(name, O_RDWR | O_TRUNC, 0);
int fd2 = dup(fd1);
char b[10];
write(fd1, "abc", 3);
lseek(fd1, 0, 0);
read(fd1, b, 1);
Check(b[0] == 'a');
read(fd2, b, 1);
Check(b[0] == 'b');
close(fd1);
close(fd2);
fd2 = dupErr(EBADF, fd1);
/* Dup2 - like dup but can pick fd number */
/* TODO(taysom) add more tests */
fd1 = open(name, O_RDWR | O_TRUNC, 0);
fd2 = open(name, O_RDONLY, 0);
fd2 = dup2(fd1, fd2);
write(fd1, "abc", 3);
lseek(fd1, 0, 0);
read(fd1, b, 1);
Check(b[0] == 'a');
read(fd2, b, 1);
Check(b[0] == 'b');
close(fd1);
close(fd2);
/* Link */
char *name2 = RndName();
link(name, name2);
stat(name, &s1);
Check(s1.st_nlink == 2);
unlink(name2);
free(name2);
stat(name, &s1);
Check(s1.st_nlink == 1);
/* TODO(taysom): need to try 64K links */
unlink(name);
free(name);
}