Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 69 additions & 7 deletions src/safeposix/syscalls/fs_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ use crate::safeposix::shm::*;
impl Cage {
/// ## ------------------OPEN SYSCALL------------------
/// ### Description
///
Comment thread
namanlalitnyu marked this conversation as resolved.
/// The `open_syscall()` creates an open file description that refers to a
/// file and a file descriptor that refers to that open file description.
/// The file descriptor is used by other I/O functions to refer to that
Expand All @@ -114,6 +115,7 @@ impl Cage {
/// are checked and based on them, file is updated accordingly.

/// ### Function Arguments
///
/// The `open_syscall()` receives three arguments:
/// * `path` - This argument points to a pathname naming the file. For
/// example: "/parentdir/file1" represents a file which will be either
Expand All @@ -129,11 +131,13 @@ impl Cage {
/// search permissions on the new file.

/// ### Returns
///
/// Upon successful completion of this call, a file descriptor is returned
/// which points the file which is opened. Otherwise, errors or panics
/// are returned for different scenarios.
///
/// ### Errors and Panics
/// ### Errors
///
/// * ENFILE - no available file descriptor number could be found
/// * ENOENT - tried to open a file that did not exist
/// * EINVAL - the input flags contain S_IFCHR flag representing a special
Expand All @@ -145,9 +149,15 @@ impl Cage {
/// passed
/// * ENXIO - the file is of type UNIX domain socket
///
/// A panic occurs when there is some issue fetching the file descriptor.
/// ### Panics
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain a bit more about the EINVAL and ENXIO errors?

///
/// for more detailed description of all the commands and return values, see
/// * If truepath.file_name() returns None or if to_str() fails, causing
/// unwrap() to panic.
/// * If the parent inode does not exist in the inode table, causing
/// unwrap() to panic.
/// * When there is some other issue fetching the file descriptor.
///
/// For more detailed description of all the commands and return values, see
/// [open(2)](https://man7.org/linux/man-pages/man2/open.2.html)

// This function is used to create a new File Descriptor Object and return it.
Expand Down Expand Up @@ -915,9 +925,61 @@ impl Cage {
}
}

//------------------------------------CREAT SYSCALL------------------------------------

/// ## ------------------CREAT SYSCALL------------------
/// ### Description
///
/// The `creat_syscall()` is similar to `open_syscall()` with the "flags"
/// parameter for open_syscall set to representing create, truncate or write
/// only for the file. It simplifies the process of creating a new file or
/// truncating an existing one by combining the O_CREAT, O_TRUNC, and
/// O_WRONLY flags.
/// There are generally two cases which occur when this syscall happens:
/// Case 1: If the file to be opened doesn't exist, then due to O_CREAT flag,
/// a new file is created at the given location and a new file descriptor is
/// created and returned.
/// Case 2: If the file already exists, then due to O_TRUNC flag, the file
/// size gets reduced to 0, and the existing file descriptor is returned.
///
/// ### Function Arguments
///
/// The `creat_syscall()` receives two arguments:
/// * `path` - This argument points to a pathname naming the file. For
/// example: "/parentdir/file1" represents a file which will be either
/// opened if exists or will be created at the given path.
/// * `mode` - This represents the permission of the newly created file. The
/// general mode used is "S_IRWXA": which represents the read, write, and
/// search permissions on the new file.
///
/// ### Returns
///
/// Upon successful completion of this call, a file descriptor is returned
/// which points the file which is opened. Otherwise, errors or panics
/// are returned for different scenarios.
///
/// ### Errors
///
/// * ENFILE - no available file descriptor number could be found
/// * ENOENT - tried to open a file that did not exist
/// * EPERM - the mode bits for a file are not sane
/// * ENOTDIR - tried to create a file as a child of something that isn't a
/// directory
/// * EEXIST - the given file already exists
/// * ENXIO - the file is of type UNIX domain socket
///
/// ### Panics
///
/// * If truepath.file_name() returns None or if to_str() fails, causing
/// unwrap() to panic.
/// * If the parent inode does not exist in the inode table, causing
/// unwrap() to panic.
/// * When there is some other issue fetching the file descriptor.
///
/// For more detailed description of all the commands and return values, see
/// [creat(3p)](https://man7.org/linux/man-pages/man3/creat.3p.html)
pub fn creat_syscall(&self, path: &str, mode: u32) -> i32 {
Comment thread
namanlalitnyu marked this conversation as resolved.
// These flags represent that the given file is either newly created
// (if it doesn't exist) or truncated to zero length (if it does exist),
// and it is opened for write-only access.
self.open_syscall(path, O_CREAT | O_TRUNC | O_WRONLY, mode)
}

Expand Down Expand Up @@ -4488,8 +4550,8 @@ impl Cage {
drop(sementry);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this sementry variable indicate?

// Acquire the semaphore. This operation will block the calling process until
// the
///semaphore becomes available. The`lock` method internally
/// decrements the semaphore value.
// semaphore becomes available. The`lock` method internally
// decrements the semaphore value.
// The lock fun is located in misc.rs
semaphore.lock();
} else {
Expand Down
61 changes: 61 additions & 0 deletions src/tests/fs_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2157,4 +2157,65 @@ pub mod fs_tests {
assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS);
lindrustfinalize();
}

#[test]
pub fn ut_lind_fs_creat_new_file() {
Comment thread
namanlalitnyu marked this conversation as resolved.
// Since this call is almost similar to open_syscall, and we have
// covered all the possible test scenarios for open_syscall above. So,
// just testing the basic working flow for the creat_sycall.

//acquiring a lock on TESTMUTEX prevents other tests from running concurrently,
// and also performs clean env setup
let _thelock = setup::lock_and_init();

let cage = interface::cagetable_getref(1);

// Create a file and validate the size of it.
let path = "/creatFile";
let fd = cage.creat_syscall(path, S_IRWXA);
assert!(fd > 0);

let mut statdata = StatData::default();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the StatData object?


// The size of the file should be 0
assert_eq!(cage.stat_syscall(path, &mut statdata), 0);
assert_eq!(statdata.st_size, 0);

assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS);
lindrustfinalize();
}

#[test]
pub fn ut_lind_fs_creat_truncate_existing_file() {
//acquiring a lock on TESTMUTEX prevents other tests from running concurrently,
// and also performs clean env setup
let _thelock = setup::lock_and_init();

let cage = interface::cagetable_getref(1);

let path = "/creatFile";
// Create a new file
let fd = cage.creat_syscall(path, S_IRWXA);

// Write a string to the newly opened file of size 12
assert_eq!(cage.write_syscall(fd, str2cbuf("hello there!"), 12), 12);

// Get the stat data for the file and check for file attributes
let mut statdata = StatData::default();
assert_eq!(cage.stat_syscall(path, &mut statdata), 0);

// Validate the size of the file to be 12
assert_eq!(statdata.st_size, 12);

// Call the function on the existing file, which should truncate
// the file size to 0.
let _fd2 = cage.creat_syscall(path, S_IRWXA);
assert_eq!(cage.stat_syscall(path, &mut statdata), 0);

// Validate the size of the file to be 0 now as should be truncated
assert_eq!(statdata.st_size, 0);

assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS);
lindrustfinalize();
}
}