Add regression tests
This commit is contained in:
parent
eaeba41f5e
commit
25beca462d
|
|
@ -48,7 +48,10 @@ pub trait FileLike: Pollable + Send + Sync + Any {
|
|||
}
|
||||
|
||||
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
|
||||
return_errno_with_message!(Errno::EINVAL, "ioctl is not supported");
|
||||
// `ENOTTY` means that "The specified operation does not apply to the kind of object that
|
||||
// the file descriptor references".
|
||||
// Reference: <https://man7.org/linux/man-pages/man2/ioctl.2.html>.
|
||||
return_errno_with_message!(Errno::ENOTTY, "ioctl is not supported");
|
||||
}
|
||||
|
||||
/// Obtains the mappable object to map this file into the user address space.
|
||||
|
|
@ -56,7 +59,10 @@ pub trait FileLike: Pollable + Send + Sync + Any {
|
|||
/// If this file has a corresponding mappable object of [`Mappable`],
|
||||
/// then it can be either an inode or an MMIO region.
|
||||
fn mappable(&self) -> Result<Mappable> {
|
||||
return_errno_with_message!(Errno::EINVAL, "the file is not mappable");
|
||||
// `ENODEV` means that "The underlying filesystem of the specified file does not support
|
||||
// memory mapping".
|
||||
// Reference: <https://man7.org/linux/man-pages/man2/mmap.2.html>.
|
||||
return_errno_with_message!(Errno::ENODEV, "the file is not mappable");
|
||||
}
|
||||
|
||||
fn resize(&self, new_size: usize) -> Result<()> {
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ impl InodeHandle_ {
|
|||
// return the file-specific mappable object.
|
||||
file_io.mappable()
|
||||
} else {
|
||||
return_errno_with_message!(Errno::EINVAL, "the file is not mappable");
|
||||
return_errno_with_message!(Errno::ENODEV, "the file is not mappable");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +329,7 @@ pub trait FileIo: Pollable + Send + Sync + 'static {
|
|||
}
|
||||
|
||||
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
|
||||
return_errno_with_message!(Errno::EINVAL, "ioctl is not supported");
|
||||
return_errno_with_message!(Errno::ENOTTY, "ioctl is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -500,12 +500,7 @@ impl OverlayInode {
|
|||
|
||||
pub fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
|
||||
self.upper().map_or_else(
|
||||
|| {
|
||||
Err(Error::with_message(
|
||||
Errno::EOPNOTSUPP,
|
||||
"ioctl is not supported",
|
||||
))
|
||||
},
|
||||
|| Err(Error::with_message(Errno::ENOTTY, "ioctl is not supported")),
|
||||
|upper| upper.ioctl(cmd, arg),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1204,7 +1204,7 @@ impl Inode for RamInode {
|
|||
if let Some(device) = self.inner.as_device() {
|
||||
return device.ioctl(cmd, arg);
|
||||
}
|
||||
return_errno_with_message!(Errno::EINVAL, "ioctl is not supported");
|
||||
return_errno_with_message!(Errno::ENOTTY, "ioctl is not supported");
|
||||
}
|
||||
|
||||
fn is_seekable(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,239 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/file.h>
|
||||
|
||||
#include "../test.h"
|
||||
|
||||
#define FILENAME "/tmp/testfile"
|
||||
#define DIRNAME "/tmp"
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
static struct flock f_rdlck = {
|
||||
.l_type = F_RDLCK,
|
||||
.l_whence = SEEK_SET,
|
||||
.l_start = 0,
|
||||
.l_len = 1024,
|
||||
};
|
||||
static struct flock f_wrlck = {
|
||||
.l_type = F_WRLCK,
|
||||
.l_whence = SEEK_SET,
|
||||
.l_start = 0,
|
||||
.l_len = 1024,
|
||||
};
|
||||
static struct flock f_unlck = {
|
||||
.l_type = F_UNLCK,
|
||||
.l_whence = SEEK_SET,
|
||||
.l_start = 0,
|
||||
.l_len = 1024,
|
||||
};
|
||||
|
||||
FN_SETUP(create)
|
||||
{
|
||||
CHECK(creat(FILENAME, 0666));
|
||||
}
|
||||
END_SETUP()
|
||||
|
||||
FN_TEST(readable)
|
||||
{
|
||||
int fd;
|
||||
char buf[1];
|
||||
void *addr;
|
||||
|
||||
// Test 1: Normal file
|
||||
|
||||
fd = TEST_SUCC(open(FILENAME, O_RDONLY));
|
||||
|
||||
TEST_SUCC(read(fd, buf, sizeof(buf)));
|
||||
TEST_ERRNO(write(fd, buf, sizeof(buf)), EBADF);
|
||||
TEST_SUCC(lseek(fd, 0, SEEK_SET));
|
||||
TEST_ERRNO(ioctl(fd, TCGETS), ENOTTY);
|
||||
TEST_ERRNO(ftruncate(fd, 1), EINVAL);
|
||||
TEST_ERRNO(fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, 1), EBADF);
|
||||
|
||||
addr = TEST_SUCC(mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0));
|
||||
TEST_SUCC(munmap(addr, PAGE_SIZE));
|
||||
TEST_ERRNO(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
|
||||
0),
|
||||
EACCES);
|
||||
|
||||
TEST_SUCC(flock(fd, LOCK_SH));
|
||||
TEST_SUCC(flock(fd, LOCK_UN));
|
||||
TEST_SUCC(flock(fd, LOCK_EX));
|
||||
TEST_SUCC(flock(fd, LOCK_UN));
|
||||
|
||||
TEST_SUCC(fcntl(fd, F_SETLK, &f_rdlck));
|
||||
TEST_SUCC(fcntl(fd, F_SETLK, &f_unlck));
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_wrlck), EBADF);
|
||||
TEST_SUCC(fcntl(fd, F_SETLK, &f_unlck));
|
||||
|
||||
TEST_RES(fcntl(fd, F_GETLK, &f_rdlck), f_rdlck.l_type == F_UNLCK);
|
||||
TEST_RES(fcntl(fd, F_GETLK, &f_wrlck), f_wrlck.l_type == F_UNLCK);
|
||||
f_rdlck.l_type = F_RDLCK;
|
||||
f_wrlck.l_type = F_WRLCK;
|
||||
|
||||
TEST_SUCC(close(fd));
|
||||
|
||||
// Test 2: Directory
|
||||
|
||||
fd = TEST_SUCC(open(DIRNAME, O_RDONLY));
|
||||
|
||||
TEST_ERRNO(read(fd, buf, sizeof(buf)), EISDIR);
|
||||
TEST_ERRNO(write(fd, buf, sizeof(buf)), EBADF);
|
||||
TEST_SUCC(lseek(fd, 0, SEEK_SET));
|
||||
TEST_ERRNO(ioctl(fd, TCGETS), ENOTTY);
|
||||
TEST_ERRNO(ftruncate(fd, 1), EINVAL);
|
||||
TEST_ERRNO(fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, 1), EBADF);
|
||||
|
||||
TEST_ERRNO(mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0), ENODEV);
|
||||
TEST_ERRNO(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
|
||||
0),
|
||||
EACCES);
|
||||
|
||||
TEST_SUCC(flock(fd, LOCK_SH));
|
||||
TEST_SUCC(flock(fd, LOCK_UN));
|
||||
TEST_SUCC(flock(fd, LOCK_EX));
|
||||
TEST_SUCC(flock(fd, LOCK_UN));
|
||||
|
||||
TEST_SUCC(fcntl(fd, F_SETLK, &f_rdlck));
|
||||
TEST_SUCC(fcntl(fd, F_SETLK, &f_unlck));
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_wrlck), EBADF);
|
||||
TEST_SUCC(fcntl(fd, F_SETLK, &f_unlck));
|
||||
|
||||
TEST_RES(fcntl(fd, F_GETLK, &f_rdlck), f_rdlck.l_type == F_UNLCK);
|
||||
TEST_RES(fcntl(fd, F_GETLK, &f_wrlck), f_wrlck.l_type == F_UNLCK);
|
||||
f_rdlck.l_type = F_RDLCK;
|
||||
f_wrlck.l_type = F_WRLCK;
|
||||
|
||||
TEST_SUCC(close(fd));
|
||||
}
|
||||
END_TEST()
|
||||
|
||||
FN_TEST(writeable)
|
||||
{
|
||||
int fd;
|
||||
char buf[1];
|
||||
void *addr;
|
||||
|
||||
// Test 1: Normal file
|
||||
|
||||
fd = TEST_SUCC(open(FILENAME, O_WRONLY));
|
||||
|
||||
TEST_ERRNO(read(fd, buf, sizeof(buf)), EBADF);
|
||||
TEST_SUCC(write(fd, buf, sizeof(buf)));
|
||||
TEST_SUCC(lseek(fd, 0, SEEK_SET));
|
||||
TEST_ERRNO(ioctl(fd, TCGETS), ENOTTY);
|
||||
TEST_SUCC(ftruncate(fd, 1));
|
||||
TEST_SUCC(fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, 1));
|
||||
|
||||
TEST_ERRNO(mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0), EACCES);
|
||||
TEST_ERRNO(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
|
||||
0),
|
||||
EACCES);
|
||||
|
||||
TEST_SUCC(flock(fd, LOCK_SH));
|
||||
TEST_SUCC(flock(fd, LOCK_UN));
|
||||
TEST_SUCC(flock(fd, LOCK_EX));
|
||||
TEST_SUCC(flock(fd, LOCK_UN));
|
||||
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_rdlck), EBADF);
|
||||
TEST_SUCC(fcntl(fd, F_SETLK, &f_unlck));
|
||||
TEST_SUCC(fcntl(fd, F_SETLK, &f_wrlck));
|
||||
TEST_SUCC(fcntl(fd, F_SETLK, &f_unlck));
|
||||
|
||||
TEST_RES(fcntl(fd, F_GETLK, &f_rdlck), f_rdlck.l_type == F_UNLCK);
|
||||
TEST_RES(fcntl(fd, F_GETLK, &f_wrlck), f_wrlck.l_type == F_UNLCK);
|
||||
f_rdlck.l_type = F_RDLCK;
|
||||
f_wrlck.l_type = F_WRLCK;
|
||||
|
||||
TEST_SUCC(close(fd));
|
||||
|
||||
// Test 2: Directory
|
||||
|
||||
TEST_ERRNO(open(DIRNAME, O_WRONLY), EISDIR);
|
||||
TEST_ERRNO(open(DIRNAME, O_RDWR), EISDIR);
|
||||
}
|
||||
END_TEST()
|
||||
|
||||
FN_TEST(path)
|
||||
{
|
||||
int fd;
|
||||
char buf[1];
|
||||
void *addr;
|
||||
|
||||
// Test 1: Normal file
|
||||
|
||||
fd = TEST_SUCC(open(FILENAME, O_RDWR | O_PATH));
|
||||
|
||||
TEST_ERRNO(read(fd, buf, sizeof(buf)), EBADF);
|
||||
TEST_ERRNO(write(fd, buf, sizeof(buf)), EBADF);
|
||||
TEST_ERRNO(lseek(fd, 0, SEEK_SET), EBADF);
|
||||
TEST_ERRNO(ioctl(fd, TCGETS), EBADF);
|
||||
TEST_ERRNO(ftruncate(fd, 1), EBADF);
|
||||
TEST_ERRNO(fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, 1), EBADF);
|
||||
|
||||
TEST_ERRNO(mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0), EBADF);
|
||||
// FIXME: Asterinas reports `EACCES` because it performs the permission check first.
|
||||
// TEST_ERRNO(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
|
||||
// 0),
|
||||
// EBADF);
|
||||
|
||||
TEST_ERRNO(flock(fd, LOCK_SH), EBADF);
|
||||
TEST_ERRNO(flock(fd, LOCK_UN), EBADF);
|
||||
TEST_ERRNO(flock(fd, LOCK_EX), EBADF);
|
||||
TEST_ERRNO(flock(fd, LOCK_UN), EBADF);
|
||||
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_rdlck), EBADF);
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_unlck), EBADF);
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_wrlck), EBADF);
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_unlck), EBADF);
|
||||
|
||||
TEST_ERRNO(fcntl(fd, F_GETLK, &f_rdlck), EBADF);
|
||||
TEST_ERRNO(fcntl(fd, F_GETLK, &f_wrlck), EBADF);
|
||||
|
||||
TEST_SUCC(close(fd));
|
||||
|
||||
// Test 2: Directory
|
||||
|
||||
fd = TEST_SUCC(open(DIRNAME, O_RDWR | O_PATH));
|
||||
|
||||
TEST_ERRNO(read(fd, buf, sizeof(buf)), EBADF);
|
||||
TEST_ERRNO(write(fd, buf, sizeof(buf)), EBADF);
|
||||
TEST_ERRNO(lseek(fd, 0, SEEK_SET), EBADF);
|
||||
TEST_ERRNO(ioctl(fd, TCGETS), EBADF);
|
||||
TEST_ERRNO(ftruncate(fd, 1), EBADF);
|
||||
TEST_ERRNO(fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, 1), EBADF);
|
||||
|
||||
TEST_ERRNO(mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0), EBADF);
|
||||
// FIXME: Asterinas reports `EACCES` because it performs the permission check first.
|
||||
// TEST_ERRNO(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
|
||||
// 0),
|
||||
// EBADF);
|
||||
|
||||
TEST_ERRNO(flock(fd, LOCK_SH), EBADF);
|
||||
TEST_ERRNO(flock(fd, LOCK_UN), EBADF);
|
||||
TEST_ERRNO(flock(fd, LOCK_EX), EBADF);
|
||||
TEST_ERRNO(flock(fd, LOCK_UN), EBADF);
|
||||
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_rdlck), EBADF);
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_unlck), EBADF);
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_wrlck), EBADF);
|
||||
TEST_ERRNO(fcntl(fd, F_SETLK, &f_unlck), EBADF);
|
||||
|
||||
TEST_ERRNO(fcntl(fd, F_GETLK, &f_rdlck), EBADF);
|
||||
TEST_ERRNO(fcntl(fd, F_GETLK, &f_wrlck), EBADF);
|
||||
|
||||
TEST_SUCC(close(fd));
|
||||
}
|
||||
END_TEST()
|
||||
|
||||
FN_SETUP(unlink)
|
||||
{
|
||||
CHECK(unlink(FILENAME));
|
||||
}
|
||||
END_SETUP()
|
||||
|
|
@ -102,6 +102,7 @@ pipe/pipe_err
|
|||
pipe/short_rw
|
||||
epoll/epoll_err
|
||||
epoll/poll_err
|
||||
file_io/access_err
|
||||
file_io/iovec_err
|
||||
devfs/full
|
||||
devfs/random
|
||||
|
|
|
|||
Loading…
Reference in New Issue