769 lines
25 KiB
C
769 lines
25 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 fstestfat.c
|
||
|
*
|
||
|
* File-system tests
|
||
|
*/
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
int fd, len;
|
||
|
char buff[256];
|
||
|
|
||
|
bochs_printf("Hi from fstest FAT\n");
|
||
|
|
||
|
ls("/", 1, 0);
|
||
|
ls(".", 1, 0);
|
||
|
ls("", 1, 0);
|
||
|
ls(0, 1, 0);
|
||
|
|
||
|
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, 0);
|
||
|
|
||
|
TEST_EXPECT_CONDITION(fd = open("tutu.txt", O_RDWR | O_CREAT,
|
||
|
S_IRUSR | S_IWUSR),
|
||
|
RETVAL == OPEN_BASE_FD + 6);
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
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, 0);
|
||
|
|
||
|
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, 0);
|
||
|
#if 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);
|
||
|
#endif
|
||
|
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, 0);
|
||
|
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, 0);
|
||
|
|
||
|
/*
|
||
|
* ioctl / fcntl
|
||
|
*/
|
||
|
|
||
|
TEST_EXPECT_CONDITION(fcntl(fd, 2, 3), RETVAL < 0); /* Not supported
|
||
|
by FAT */
|
||
|
TEST_EXPECT_CONDITION(ioctl(fd, 2, 3), RETVAL < 0); /* Not supported
|
||
|
by FAT */
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
/*
|
||
|
* 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*/
|
||
|
/* Hard link not supported by FAT */
|
||
|
TEST_EXPECT_CONDITION(link("toto4.txt", "toto5.txt"), RETVAL < 0); /*ENOSUP*/
|
||
|
ls(".", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(chmod("toto4.txt", S_IRUSR | S_IWUSR), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
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); /* ENOENT */
|
||
|
TEST_EXPECT_CONDITION(creat("toto4.txt", S_IRWXALL), RETVAL < 0); /*EEXIST*/
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
/* Change symlinks */
|
||
|
/* Symlink not supported by FAT */
|
||
|
TEST_EXPECT_CONDITION(symlink("toto4.txt", "toto5.txt"), RETVAL < 0); /*ENOSUP*/
|
||
|
TEST_EXPECT_CONDITION(symlink("toto4.txt", "toto.txt"), RETVAL < 0); /*EEXIST*/
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
/* 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, 0);
|
||
|
|
||
|
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, 0);
|
||
|
|
||
|
TEST_EXPECT_CONDITION(mkdir("yoplait1", S_IRWXALL), RETVAL == 0);
|
||
|
/* FAT not supported rename because SOS' rename implementation use link
|
||
|
* and link is not by FAT FS */
|
||
|
TEST_EXPECT_CONDITION(rename("yoplait1", "mouf1"), RETVAL < 0); /*ENOSUP*/
|
||
|
TEST_EXPECT_CONDITION(fd = open("yoplait1/a", O_RDWR | O_CREAT, S_IRWXALL),
|
||
|
RETVAL == OPEN_BASE_FD + 14);
|
||
|
TEST_EXPECT_CONDITION(unlink("yoplait1/a"), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(rmdir("yoplait1"), RETVAL == 0);
|
||
|
|
||
|
TEST_EXPECT_CONDITION(mkdir("yoplait2", S_IRWXALL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(rename("yoplait2", "mouf2"), RETVAL < 0); /*ENOSUP*/
|
||
|
TEST_EXPECT_CONDITION(fd = open("yoplait2/a", O_RDWR | O_CREAT, S_IRWXALL),
|
||
|
RETVAL == OPEN_BASE_FD + 15);
|
||
|
TEST_EXPECT_CONDITION(rmdir("yoplait2"), RETVAL < 0);
|
||
|
|
||
|
TEST_EXPECT_CONDITION(mkdir("yoplait3", S_IRWXALL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(rename("yoplait3", "mouf3"), RETVAL < 0); /*ENOSUP*/
|
||
|
TEST_EXPECT_CONDITION(creat("yoplait3/a", S_IRWXALL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(unlink("yoplait3/a"), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(rmdir("yoplait3"), RETVAL == 0);
|
||
|
|
||
|
TEST_EXPECT_CONDITION(mkdir("yoplait4", S_IRWXALL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(rename("yoplait4", "mouf4"), RETVAL < 0); /*ENOSUP*/
|
||
|
TEST_EXPECT_CONDITION(creat("yoplait4/a", S_IRWXALL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(rmdir("yoplait4"), RETVAL < 0);
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
/* Not supported by FAT */
|
||
|
TEST_EXPECT_CONDITION(mknod("dev1", S_IRWXALL, S_IFCHR, 420, 268),
|
||
|
RETVAL < 0); /*ENOSUP*/
|
||
|
/* Make sure the device cannot be opened (no device should be
|
||
|
associated to it */
|
||
|
TEST_EXPECT_CONDITION(open("dev1", O_RDONLY), RETVAL < 0); /*EEXIST*/
|
||
|
TEST_EXPECT_CONDITION(unlink("dev1"), RETVAL < 0); /*EEXIST*/
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
ls("..", 1, 0);
|
||
|
ls("../", 1, 0);
|
||
|
ls("/..", 1, 0);
|
||
|
|
||
|
/* 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, 0);
|
||
|
ls("yo1", 1, 0);
|
||
|
|
||
|
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 + 16);
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
ls("yo1", 1, 0);
|
||
|
|
||
|
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, 0);
|
||
|
|
||
|
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 + 17);
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
TEST_EXPECT_CONDITION(mkdir("yo4", S_IWUSR), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(fd = open("yo4/titi1.txt", O_RDONLY), RETVAL < 0);
|
||
|
/* FAT FS is always executable, then yo4 is S_IWUSR | S_IXUSR */
|
||
|
TEST_EXPECT_CONDITION(fd = open("yo4/titi1.txt", O_RDONLY | O_CREAT,
|
||
|
S_IRUSR), RETVAL == OPEN_BASE_FD + 18);
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
TEST_EXPECT_CONDITION(chdir("nowhere"), RETVAL < 0);
|
||
|
TEST_EXPECT_CONDITION(chdir("yo1"), RETVAL == 0);
|
||
|
|
||
|
ls(".", 1, 0);
|
||
|
ls("/", 1, 0);
|
||
|
ls("..", 1, 0);
|
||
|
ls("../../../../", 1, 0);
|
||
|
ls("/../../../../", 1, 0);
|
||
|
|
||
|
/* Test chroot */
|
||
|
|
||
|
TEST_EXPECT_CONDITION(chroot("nowhere"), RETVAL < 0);
|
||
|
TEST_EXPECT_CONDITION(chroot("."), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
ls("/", 1, 0);
|
||
|
ls("..", 1, 0);
|
||
|
ls("../../../../", 1, 0);
|
||
|
ls("/../../../../", 1, 0);
|
||
|
|
||
|
/* 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, 0);
|
||
|
ls("mnt", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(mount(NULL, "mnt", "virtfs", 0, NULL), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
ls("mnt", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(mkdir("mnt/dir_mnt", S_IRWXALL), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
ls("mnt", 1, 0);
|
||
|
|
||
|
/* Make sure we cannot umount if the FS is in use */
|
||
|
TEST_EXPECT_CONDITION(fd = open("mnt/dir_mnt", O_DIRECTORY),
|
||
|
RETVAL == OPEN_BASE_FD + 19);
|
||
|
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, 0);
|
||
|
ls("mnt", 1, 0);
|
||
|
|
||
|
/* 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("dir_mnt", O_DIRECTORY),
|
||
|
RETVAL == OPEN_BASE_FD + 19);
|
||
|
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, 0);
|
||
|
ls("mnt", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(umount("mnt"), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
ls("mnt", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(umount("mnt"), RETVAL < 0);
|
||
|
|
||
|
/*
|
||
|
* Mountchain exploration
|
||
|
*/
|
||
|
TEST_EXPECT_CONDITION(mkdir("mnt2", S_IRWXALL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(mkdir("mnt2/nothing", S_IRWXALL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(mount(NULL, "mnt2", "virtfs", 0, NULL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(mkdir("mnt2/mntpt-1", S_IRWXALL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(mount(NULL, "mnt2", "virtfs", 0, NULL), RETVAL == 0);
|
||
|
TEST_EXPECT_CONDITION(mkdir("mnt2/mntpt-2", S_IRWXALL), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
ls("mnt2", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(umount("mnt2"), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
ls("mnt2", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(umount("mnt2"), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
ls("mnt2", 1, 0);
|
||
|
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 + 19);
|
||
|
ls(".", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(unlink("toto8.txt"), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
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, 0);
|
||
|
|
||
|
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, 0);
|
||
|
|
||
|
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 + 20);
|
||
|
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, 0);
|
||
|
|
||
|
/* Invalid char space in the name */
|
||
|
TEST_EXPECT_CONDITION(mkdir("this is ", S_IRWXALL), RETVAL < 0); /*EINVAL*/
|
||
|
/* Name too long */
|
||
|
TEST_EXPECT_CONDITION(mkdir("nametoolongwithoutspacechar", S_IRWXALL), RETVAL < 0); /*ENAMETOOLONG*/
|
||
|
/* Invalid char space in the name and name too long */
|
||
|
TEST_EXPECT_CONDITION(mkdir("this is / a long path", S_IRWXALL), RETVAL < 0); /*ENAMETOOLONG*/
|
||
|
/* Invalid char space in the name and name too long */
|
||
|
TEST_EXPECT_CONDITION(rmdir("this is / a long path"), RETVAL < 0); /*EEXIST*/
|
||
|
/* Name too long */
|
||
|
TEST_EXPECT_CONDITION(rmdir("nametoolongwithoutspacechar"), RETVAL < 0); /*EEXIST*/
|
||
|
/* Invalid char space in the name */
|
||
|
TEST_EXPECT_CONDITION(rmdir("this is "), RETVAL < 0); /*EEXIST*/
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
/*
|
||
|
* 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 + 20);
|
||
|
ls(".", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(link("toto8.txt", "toto9.txt"), RETVAL < 0); /*ENOSUP*/
|
||
|
TEST_EXPECT_CONDITION(unlink("toto8.txt"), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
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);
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
/*
|
||
|
* 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 + 21);
|
||
|
ls(".", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(rename("toto8.txt", "toto9.txt"), RETVAL < 0); /*ENOSUP*/
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
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 == OPEN_BASE_FD + 21);
|
||
|
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
|
||
|
|
||
|
/* Rename */
|
||
|
ls(".", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(rename("/mnt/subdir0", "subdir42"), RETVAL < 0); /*ENOSUP*/
|
||
|
ls(".", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(rename("titi1.txt", "subdir42"), RETVAL < 0); /*ENOSUP*/
|
||
|
ls(".", 1, 0);
|
||
|
TEST_EXPECT_CONDITION(rename("titi1.txt", "subdir42/titi.txt"), RETVAL < 0); /*ENOSUP*/
|
||
|
|
||
|
/*
|
||
|
* 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 + 21);
|
||
|
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, 0);
|
||
|
TEST_EXPECT_CONDITION(unlink("mmap.txt"), RETVAL == 0);
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
/* 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 + 22);
|
||
|
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, 0);
|
||
|
|
||
|
/* 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 + 23);
|
||
|
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 + 23);
|
||
|
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, 0);
|
||
|
|
||
|
bochs_printf("Bye from fstest FAT\n");
|
||
|
ls(".", 1, 0);
|
||
|
|
||
|
return 0;
|
||
|
}
|