sos-code-article10/userland/fstest.c

848 lines
28 KiB
C

/* Copyright (C) 2005 David Decotigny
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
*/
#include <crt.h>
#include <libc.h>
#include <stdarg.h>
#include <string.h>
#include <debug.h>
#include "fstest_utils.h"
static const int OPEN_BASE_FD = 3;
/**
* @file fstest.c
*
* File-system tests
*/
int main(void)
{
int fd, len;
char buff[256];
bochs_printf("Hi from fstest\n");
ls("/", 1, 1);
ls(".", 1, 1);
ls("", 1, 1);
ls(0, 1, 1);
TEST_EXPECT_CONDITION(fd = open("", 0),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open(0, 0),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("/", O_RDWR),
RETVAL == OPEN_BASE_FD + 0);
TEST_EXPECT_CONDITION(fd = open("/", O_RDONLY),
RETVAL == OPEN_BASE_FD + 1);
TEST_EXPECT_CONDITION(fd = open("/", O_WRONLY),
RETVAL == OPEN_BASE_FD + 2);
TEST_EXPECT_CONDITION(close(OPEN_BASE_FD + 1),
RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("/", O_WRONLY),
RETVAL == OPEN_BASE_FD + 1);
TEST_EXPECT_CONDITION(fd = open("//", O_WRONLY),
RETVAL == OPEN_BASE_FD + 3);
TEST_EXPECT_CONDITION(fd = open("////////", O_WRONLY),
RETVAL == OPEN_BASE_FD + 4);
TEST_EXPECT_CONDITION(fd = open("/does not exist", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("////does not exist", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("/does not exist/", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("////does not exist/", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("/does not exist////", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("////does not exist/////", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("does not exist", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("does not exist/", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("does not exist////", O_WRONLY),
RETVAL);
TEST_EXPECT_CONDITION(fd = open("/does not exist/ab c d", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("////does not exist/ab c d", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("/does not exist////ab c d", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("////does not exist/////ab c d", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("does not exist", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("does not exist/ab c d", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("does not exist////ab c d", O_WRONLY),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("/", O_RDWR),
RETVAL == OPEN_BASE_FD + 5);
TEST_EXPECT_CONDITION(fd = open("/tutu.txt", O_RDWR),
RETVAL < 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(fd = open("/tutu.txt", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 6);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(fd = open("tutu.txt", O_RDWR | O_CREAT),
RETVAL == OPEN_BASE_FD + 7);
/* O_EXCL with an already-existing file */
TEST_EXPECT_CONDITION(fd = open("tutu.txt", O_RDWR | O_CREAT | O_EXCL),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("/toto.txt", O_RDWR | O_CREAT | O_EXCL,
S_IRWXALL),
RETVAL == OPEN_BASE_FD + 8);
/* O_EXCL with an already-existing file */
TEST_EXPECT_CONDITION(fd = open("toto.txt", O_RDWR | O_CREAT | O_EXCL),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("toto.txt", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 9);
/* Trailing slash on non-dir entries */
TEST_EXPECT_CONDITION(fd = open("toto.txt/", O_RDWR), RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("notdir/", O_RDWR | O_CREAT, S_IRWXALL),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("notdir/", O_RDWR), RETVAL < 0);
/* Substring match */
TEST_EXPECT_CONDITION(fd = open("toto1.txt", O_RDWR),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("toto1.tx", O_RDWR | O_CREAT, S_IWUSR),
RETVAL == OPEN_BASE_FD + 10);
/* Substring match */
TEST_EXPECT_CONDITION(fd = open("toto.tx", O_RDWR),
RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("toto.tx", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 11);
/*
* read/write/seek
*/
TEST_EXPECT_CONDITION(len = read(fd, buff, 256),
RETVAL == 0);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET),
RETVAL == 0);
strzcpy(buff, "Bonjour !", 256);
TEST_EXPECT_CONDITION(len = write(fd, buff, 10),
RETVAL == 10);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET),
RETVAL == 0);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256),
RETVAL == 10);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(strcmp("Bonjour !", buff), RETVAL ==0);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_CUR), RETVAL == 10);
/*
* truncate
*/
TEST_EXPECT_CONDITION(ftruncate(fd, 3), RETVAL == 0);
/* The current position should not have changed */
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_CUR), RETVAL == 10);
/* Make sure we cannot read anything because we get past the end of
the file */
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 0);
/* Now get back at the begining of the file */
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
/* Make sure that we can read something with the correct first 3
characters */
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 3);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(strncmp("Bon", buff, len), RETVAL == 0);
/*
* open mode
*/
ls("/", 1, 1);
/* Open r/w, create read-only */
TEST_EXPECT_CONDITION(fd = open("toto2.txt", O_RDWR | O_CREAT, S_IRUSR),
RETVAL == OPEN_BASE_FD + 12);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256),
RETVAL == 0);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Permission denied", 256);
TEST_EXPECT_CONDITION(len = write(fd, buff, 10),
RETVAL < 0); /* Permission denied ! */
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 0);
/* Open read-only, create r/w */
TEST_EXPECT_CONDITION(fd = open("toto3.txt", O_RDONLY | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 13);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 0);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Permission denied 2", 256);
TEST_EXPECT_CONDITION(len = write(fd, buff, 10),
RETVAL < 0); /* Permission denied ! */
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 0);
/* Create another process that chdirs in it */
if (fork() == 0)
{
bochs_printf("Hello from child\n");
TEST_EXPECT_CONDITION(fd = open("shrd.txt", O_RDWR | O_CREAT, S_IRWXALL),
RETVAL == OPEN_BASE_FD + 14);
strzcpy(buff, "Hello from child !", 256);
TEST_EXPECT_CONDITION(len = write(fd, buff, 19),
RETVAL == 19);
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
bochs_printf("Bye from child\n");
return 0;
}
bochs_printf("Father sleeping\n");
nanosleep(1, 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(fd = open("shrd.txt", O_RDONLY),
RETVAL == OPEN_BASE_FD + 14);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256),
RETVAL == 19);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(strncmp("Hello from child !", buff, len),
RETVAL == 0);
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
TEST_EXPECT_CONDITION(unlink("shrd.txt"), RETVAL == 0);
ls("/", 1, 1);
/*
* ioctl / fcntl
*/
TEST_EXPECT_CONDITION(fcntl(fd, 2, 3), RETVAL < 0); /* Not supported
by virtfs */
TEST_EXPECT_CONDITION(ioctl(fd, 2, 3), RETVAL < 0); /* Not supported
by virtfs */
ls("/", 1, 1);
/*
* creat/link/unlink/symlink
*/
TEST_EXPECT_CONDITION(creat("toto4.txt", S_IRUSR), RETVAL == 0);
TEST_EXPECT_CONDITION(creat("toto4.txt", S_IRWXALL), RETVAL < 0); /*EEXIST*/
TEST_EXPECT_CONDITION(link("toto4.txt", "toto5.txt"), RETVAL == 0);
TEST_EXPECT_CONDITION(link("toto4.txt", "toto5.txt"), RETVAL < 0); /*EEXIST*/
TEST_EXPECT_CONDITION(link("toto4.txt", "toto.txt"), RETVAL < 0); /*EEXIST*/
ls("/", 1, 1);
TEST_EXPECT_CONDITION(chmod("toto5.txt", S_IRUSR | S_IWUSR), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(fd = open("toto5.txt", O_RDWR),
RETVAL == OPEN_BASE_FD + 14);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 0);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Hello world from toto5", 256);
TEST_EXPECT_CONDITION(len = write(fd, buff, 24), RETVAL == 24);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 24);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(fd = open("toto4.txt", O_RDWR),
RETVAL == OPEN_BASE_FD + 15);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 24);
bochs_printf("read s='%s'\n", buff);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(link("dangling", "toto42.txt"), RETVAL < 0); /*ENOENT*/
TEST_EXPECT_CONDITION(unlink("toto4.txt"), RETVAL == 0);
TEST_EXPECT_CONDITION(unlink("toto42.txt"), RETVAL < 0); /* ENOENT */
TEST_EXPECT_CONDITION(unlink("toto4.txt"), RETVAL < 0); /* ENOENT */
TEST_EXPECT_CONDITION(creat("toto4.txt", S_IWUSR | S_IRUSR), RETVAL == 0);
TEST_EXPECT_CONDITION(unlink("toto5.txt/"), RETVAL < 0); /* EISDIR ? */
TEST_EXPECT_CONDITION(rmdir("toto5.txt/"), RETVAL < 0); /* ENOTDIR ? */
TEST_EXPECT_CONDITION(rmdir("toto5.txt"), RETVAL < 0); /* ENOTDIR ? */
TEST_EXPECT_CONDITION(unlink("toto5.txt"), RETVAL == 0);
TEST_EXPECT_CONDITION(unlink("toto5.txt"), RETVAL < 0); /* ENOENT */
TEST_EXPECT_CONDITION(creat("toto4.txt", S_IRWXALL), RETVAL < 0); /*EEXIST*/
ls("/", 1, 1);
/* Change symlinks */
TEST_EXPECT_CONDITION(symlink("toto4.txt", "toto5.txt"), RETVAL == 0);
TEST_EXPECT_CONDITION(symlink("toto4.txt", "toto5.txt"), RETVAL < 0); /*EEXIST*/
TEST_EXPECT_CONDITION(symlink("toto4.txt", "toto.txt"), RETVAL < 0); /*EEXIST*/
ls("/", 1, 1);
TEST_EXPECT_CONDITION(fd = open("toto5.txt", O_RDWR),
RETVAL == OPEN_BASE_FD + 16);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 0);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Hello world from toto5", 256);
TEST_EXPECT_CONDITION(len = write(fd, buff, 24), RETVAL == 24);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 24);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(strcmp(buff, "Hello world from toto5"), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("toto4.txt", O_RDWR),
RETVAL == OPEN_BASE_FD + 17);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 24);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(strcmp(buff, "Hello world from toto5"), RETVAL == 0);
TEST_EXPECT_CONDITION(symlink("dangling", "toto6.txt"), RETVAL == 0);
TEST_EXPECT_CONDITION(symlink("dangling", "toto6.txt"), RETVAL < 0); /*EEXIST*/
TEST_EXPECT_CONDITION(fd = open("toto6.txt", O_RDWR), RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("toto6.txt", O_RDWR | O_NOFOLLOW),
RETVAL == OPEN_BASE_FD + 18);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 8);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(strncmp(buff, "dangling", len), RETVAL == 0);
ls("/", 1, 1);
/* mkdir/rmdir */
TEST_EXPECT_CONDITION(mkdir("yo1", S_IRUSR | S_IXUSR), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("yo1", S_IRWXALL), RETVAL < 0); /*EEXIST*/
ls("/", 1, 1);
TEST_EXPECT_CONDITION(unlink("yo1"), RETVAL < 0); /*EISDIR*/
TEST_EXPECT_CONDITION(unlink("yo1/"), RETVAL < 0); /*EISDIR*/
TEST_EXPECT_CONDITION(rmdir("yo1"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("yo1"), RETVAL < 0); /*ENOENT*/
TEST_EXPECT_CONDITION(rmdir("yoda"), RETVAL < 0); /*ENOENT*/
ls("/", 1, 1);
TEST_EXPECT_CONDITION(mkdir("yoplait1", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(rename("yoplait1", "mouf1"), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("mouf1/a", O_RDWR | O_CREAT, S_IRWXALL),
RETVAL == OPEN_BASE_FD + 19);
TEST_EXPECT_CONDITION(unlink("mouf1/a"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("mouf1"), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("yoplait2", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(rename("yoplait2", "mouf2"), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("mouf2/a", O_RDWR | O_CREAT, S_IRWXALL),
RETVAL == OPEN_BASE_FD + 20);
TEST_EXPECT_CONDITION(rmdir("mouf2"), RETVAL < 0);
TEST_EXPECT_CONDITION(mkdir("yoplait3", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(rename("yoplait3", "mouf3"), RETVAL == 0);
TEST_EXPECT_CONDITION(creat("mouf3/a", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(unlink("mouf3/a"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("mouf3"), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("yoplait4", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(rename("yoplait4", "mouf4"), RETVAL == 0);
TEST_EXPECT_CONDITION(creat("mouf4/a", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("mouf4"), RETVAL < 0);
ls("/", 1, 1);
/* Not supported by virtfs */
TEST_EXPECT_CONDITION(mknod("dev1", S_IRWXALL, S_IFCHR, 420, 268),
RETVAL == 0);
/* Make sure the device cannot be opened (no device should be
associated to it */
TEST_EXPECT_CONDITION(open("dev1", O_RDONLY), RETVAL < 0);
TEST_EXPECT_CONDITION(unlink("dev1"), RETVAL == 0);
ls("/", 1, 1);
ls("..", 1, 1);
ls("../", 1, 1);
ls("/..", 1, 1);
/* subdirs */
TEST_EXPECT_CONDITION(fd = open("yo1/titi1.txt", O_RDONLY), RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("yo1/titi1.txt", O_RDONLY | O_CREAT,
S_IRUSR), RETVAL < 0);
ls("/", 1, 1);
ls("/yo1", 1, 1);
TEST_EXPECT_CONDITION(mkdir("yo1", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("yo1/titi1.txt", O_RDONLY), RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("yo1/titi1.txt", O_RDONLY | O_CREAT,
S_IRUSR), RETVAL == OPEN_BASE_FD + 21);
ls("/", 1, 1);
ls("/yo1", 1, 1);
TEST_EXPECT_CONDITION(mkdir("yo2", S_IRUSR | S_IXUSR), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("yo2/titi1.txt", O_RDONLY), RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("yo2/titi1.txt", O_RDONLY | O_CREAT,
S_IRUSR), RETVAL < 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(mkdir("yo3", S_IWUSR | S_IXUSR), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("yo3/titi1.txt", O_RDONLY), RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("yo3/titi1.txt", O_RDONLY | O_CREAT,
S_IRUSR), RETVAL == OPEN_BASE_FD + 22);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(mkdir("yo4", S_IWUSR), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("yo4/titi1.txt", O_RDONLY), RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("yo4/titi1.txt", O_RDONLY | O_CREAT,
S_IRUSR), RETVAL < 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(chdir("nowhere"), RETVAL < 0);
TEST_EXPECT_CONDITION(chdir("yo1"), RETVAL == 0);
ls(".", 1, 1);
ls("/", 1, 1);
ls("..", 1, 1);
ls("../../../../", 1, 1);
ls("/../../../../", 1, 1);
/* Test chroot */
TEST_EXPECT_CONDITION(chroot("nowhere"), RETVAL < 0);
TEST_EXPECT_CONDITION(chroot("."), RETVAL == 0);
ls(".", 1, 1);
ls("/", 1, 1);
ls("..", 1, 1);
ls("../../../../", 1, 1);
ls("/../../../../", 1, 1);
/* mount */
TEST_EXPECT_CONDITION(mount(NULL, "nowhere", NULL, 0, NULL), RETVAL < 0);
TEST_EXPECT_CONDITION(mount(NULL, "nowhere", "yoplait", 0, NULL), RETVAL < 0);
TEST_EXPECT_CONDITION(mount(NULL, "nowhere", "virtfs", 0, NULL), RETVAL < 0);
TEST_EXPECT_CONDITION(mkdir("mnt", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("mnt/subdir0", S_IRWXALL), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(mount(NULL, "mnt", "virtfs", 0, NULL), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(mkdir("mnt/subdir_mounted", S_IRWXALL), RETVAL == 0);
ls("/", 1, 1);
/* Make sure we cannot umount if the FS is in use */
TEST_EXPECT_CONDITION(fd = open("mnt/subdir_mounted", O_DIRECTORY),
RETVAL == OPEN_BASE_FD + 23);
TEST_EXPECT_CONDITION(umount("mnt"), RETVAL < 0);
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
/* Make sure we cannot umount if the FS is in use */
TEST_EXPECT_CONDITION(chdir("mnt"), RETVAL == 0);
TEST_EXPECT_CONDITION(umount("/mnt"), RETVAL < 0);
TEST_EXPECT_CONDITION(chdir(".."), RETVAL == 0);
ls(".", 1, 1);
/* Create another process that chdirs in it */
if (fork() == 0)
{
bochs_printf("Hello from child\n");
TEST_EXPECT_CONDITION(chdir("mnt"), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("subdir_mounted", O_DIRECTORY),
RETVAL == OPEN_BASE_FD + 23);
bochs_printf("Child sleeping...\n");
nanosleep(2, 0);
bochs_printf("Bye from child\n");
return 0;
}
else
{
bochs_printf("Father sleeping\n");
nanosleep(1, 0);
bochs_printf("Father trying to umount, should fail (a process chdir'ed in it)\n");
TEST_EXPECT_CONDITION(umount("mnt"), RETVAL < 0);
bochs_printf("Father Resuming normal operation in 3s...\n");
nanosleep(3, 0);
}
TEST_EXPECT_CONDITION(umount(NULL), RETVAL < 0);
TEST_EXPECT_CONDITION(umount("nowhere"), RETVAL < 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(umount("mnt"), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(umount("mnt"), RETVAL < 0);
/*
* Mountchain exploration
*/
TEST_EXPECT_CONDITION(mkdir("/mnt2", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("/mnt2/nothing-mounted", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(mount(NULL, "mnt2", "virtfs", 0, NULL), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("/mnt2/mountpoint-1", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(mount(NULL, "mnt2", "virtfs", 0, NULL), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("/mnt2/mountpoint-2", S_IRWXALL), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(umount("mnt2"), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(umount("mnt2"), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(umount("mnt2"), RETVAL < 0);
/*
* Erasing files while they are in use
*/
TEST_EXPECT_CONDITION(fd = open("toto8.txt", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 23);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(unlink("toto8.txt"), RETVAL == 0);
ls("/", 1, 1);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 0);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Hello world from toto8", 256);
TEST_EXPECT_CONDITION(len = write(fd, buff, 24), RETVAL == 24);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 24);
bochs_printf("read s='%s'\n", buff);
/*
* rmdir on still used dirs
*/
TEST_EXPECT_CONDITION(mkdir("plotch", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(chdir("plotch"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("../plotch"), RETVAL < 0);
TEST_EXPECT_CONDITION(chdir(".."), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("plotch"), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(mkdir("plotch", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(creat("plotch/a", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("plotch"), RETVAL < 0);
TEST_EXPECT_CONDITION(unlink("plotch/a"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("plotch"), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(mkdir("plotch", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("plotch/a", O_RDWR | O_CREAT, S_IRWXALL),
RETVAL == OPEN_BASE_FD + 24);
TEST_EXPECT_CONDITION(rmdir("plotch"), RETVAL < 0);
TEST_EXPECT_CONDITION(unlink("plotch/a"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("plotch"), RETVAL == 0);
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(mkdir("this is ", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("this is / a long path", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("this is / a long path/tothe", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("this is / a long path/tothe/destination ", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(mkdir("this is / a long path/tothe/destination / directory", S_IRWXALL), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("this is / a long path/tothe/destination / directory/a", O_RDWR | O_CREAT, S_IRWXALL),
RETVAL == OPEN_BASE_FD + 24);
TEST_EXPECT_CONDITION(rmdir("this is / a long path/tothe/destination / directory"), RETVAL < 0);
TEST_EXPECT_CONDITION(unlink("this is / a long path/tothe/destination / directory/a"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("this is / a long path/tothe/destination / directory"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("this is / a long path/tothe/destination / directory/"), RETVAL < 0);
TEST_EXPECT_CONDITION(rmdir("this is / a long path/tothe/destination "), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("this is / a long path/tothe/"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("this is / a long path"), RETVAL == 0);
TEST_EXPECT_CONDITION(rmdir("this is "), RETVAL == 0);
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
ls("/", 1, 1);
/*
* Unlink/link files while they are in use
*/
TEST_EXPECT_CONDITION(fd = open("toto8.txt", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 24);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(link("toto8.txt", "toto9.txt"), RETVAL == 0);
TEST_EXPECT_CONDITION(unlink("toto8.txt"), RETVAL == 0);
ls("/", 1, 1);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 0);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Hello world from toto8", 256);
TEST_EXPECT_CONDITION(len = write(fd, buff, 24), RETVAL == 24);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 24);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(fd = open("toto8.txt", O_RDWR), RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("toto9.txt", O_RDWR),
RETVAL == OPEN_BASE_FD + 25);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 24);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(unlink("toto9.txt"), RETVAL == 0);
ls("/", 1, 1);
/*
* Rename files while they are in use
*/
TEST_EXPECT_CONDITION(fd = open("toto8.txt", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 26);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(rename("toto8.txt", "toto9.txt"), RETVAL == 0);
ls("/", 1, 1);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 0);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Hello world from toto8", 256);
TEST_EXPECT_CONDITION(len = write(fd, buff, 24), RETVAL == 24);
TEST_EXPECT_CONDITION(lseek(fd, 0, SEEK_SET), RETVAL == 0);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 24);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
TEST_EXPECT_CONDITION(fd = open("toto8.txt", O_RDWR), RETVAL < 0);
TEST_EXPECT_CONDITION(fd = open("toto9.txt", O_RDWR),
RETVAL == OPEN_BASE_FD + 26);
strzcpy(buff, "Garbage garbage garbage", 256);
TEST_EXPECT_CONDITION(len = read(fd, buff, 256), RETVAL == 24);
bochs_printf("read s='%s'\n", buff);
TEST_EXPECT_CONDITION(unlink("toto9.txt"), RETVAL == 0);
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
/* Rename */
ls("/", 1, 1);
TEST_EXPECT_CONDITION(rename("/mnt/subdir0", "subdir42"), RETVAL == 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(rename("titi1.txt", "subdir42"), RETVAL < 0);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(rename("titi1.txt", "subdir42/titi.txt"), RETVAL == 0);
/* Rename a dir being used */
TEST_EXPECT_CONDITION(chdir("subdir42"), RETVAL == 0);
ls(".", 1, 1);
ls("..", 1, 1);
ls("/", 1, 1);
TEST_EXPECT_CONDITION(rename("../subdir42", "../subdir000"), RETVAL == 0);
ls(".", 1, 1);
ls("/", 1, 1);
ls("..", 1, 1);
/*
* test mmap
*/
/* Common use: shared file suppressed as soon as possible */
TEST_EXPECT_CONDITION(fd = open("mmap.txt", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 26);
if (fork() == 0)
{
char *shrd;
TEST_EXPECT_CONDITION(shrd = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 4096),
shrd != NULL);
nanosleep(1, 0);
strzcpy(shrd, "Hello1 from the child (shared mapping) !", 4096);
return 0;
}
else
{
char *shrd;
TEST_EXPECT_CONDITION(shrd = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 4096),
shrd != NULL);
strzcpy(shrd, "Garbage garbage garbage", 256);
nanosleep(2, 0);
bochs_printf("Father woken up\n");
bochs_printf("Read string from child: '%s'\n", shrd);
TEST_EXPECT_CONDITION(strcmp(shrd, "Hello1 from the child (shared mapping) !"),
RETVAL == 0);
munmap(shrd, 8192);
}
ls("/", 1, 1);
TEST_EXPECT_CONDITION(unlink("mmap.txt"), RETVAL == 0);
ls("/", 1, 1);
/* Common use: shared file suppressed as soon as possible */
TEST_EXPECT_CONDITION(fd = open("mmap.txt", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 27);
TEST_EXPECT_CONDITION(unlink("mmap.txt"), RETVAL == 0);
if (fork() == 0)
{
char *shrd;
TEST_EXPECT_CONDITION(shrd = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 4096),
shrd != NULL);
nanosleep(1, 0);
strzcpy(shrd, "Hello2 from the child (shared mapping) !", 4096);
return 0;
}
else
{
char *shrd;
TEST_EXPECT_CONDITION(shrd = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 4096),
shrd != NULL);
strzcpy(shrd, "Garbage garbage garbage", 256);
nanosleep(2, 0);
bochs_printf("Father woken up\n");
bochs_printf("Read string from child: '%s'\n", shrd);
TEST_EXPECT_CONDITION(strcmp(shrd, "Hello2 from the child (shared mapping) !"),
RETVAL == 0);
}
ls("/", 1, 1);
/* Basic use */
TEST_EXPECT_CONDITION(creat("mmap.txt", S_IRUSR | S_IWUSR), RETVAL == 0);
if (fork() == 0)
{
char *shrd;
TEST_EXPECT_CONDITION(fd = open("mmap.txt", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 28);
TEST_EXPECT_CONDITION(shrd = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 4096),
shrd != NULL);
nanosleep(1, 0);
strzcpy(shrd, "Hello3 from the child (shared mapping) !", 4096);
return 0;
}
else
{
char *shrd;
TEST_EXPECT_CONDITION(fd = open("mmap.txt", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR),
RETVAL == OPEN_BASE_FD + 28);
TEST_EXPECT_CONDITION(shrd = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 4096),
shrd != NULL);
strzcpy(shrd, "Garbage garbage garbage", 256);
nanosleep(2, 0);
bochs_printf("Father woken up\n");
bochs_printf("Read string from child: '%s'\n", shrd);
TEST_EXPECT_CONDITION(strcmp(shrd, "Hello3 from the child (shared mapping) !"),
RETVAL == 0);
}
ls("/", 1, 1);
bochs_printf("Bye from fstest\n");
ls("/", 1, 1);
return 0;
}