Skip to content

Commit 1504129

Browse files
namanlalitnyulind
andauthored
Updates to creat_syscall() (#287)
* Added comments and tests for creat_syscall; Reformatted existing code * Refactored comments for open_syscall * Addressed review comments * Fixed minor change --------- Co-authored-by: lind <lind@nyu.edu>
1 parent 3ecae1d commit 1504129

File tree

2 files changed

+130
-7
lines changed

2 files changed

+130
-7
lines changed

src/safeposix/syscalls/fs_calls.rs

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ use crate::safeposix::shm::*;
104104
impl Cage {
105105
/// ## ------------------OPEN SYSCALL------------------
106106
/// ### Description
107+
///
107108
/// The `open_syscall()` creates an open file description that refers to a
108109
/// file and a file descriptor that refers to that open file description.
109110
/// The file descriptor is used by other I/O functions to refer to that
@@ -114,6 +115,7 @@ impl Cage {
114115
/// are checked and based on them, file is updated accordingly.
115116
116117
/// ### Function Arguments
118+
///
117119
/// The `open_syscall()` receives three arguments:
118120
/// * `path` - This argument points to a pathname naming the file. For
119121
/// example: "/parentdir/file1" represents a file which will be either
@@ -129,11 +131,13 @@ impl Cage {
129131
/// search permissions on the new file.
130132
131133
/// ### Returns
134+
///
132135
/// Upon successful completion of this call, a file descriptor is returned
133136
/// which points the file which is opened. Otherwise, errors or panics
134137
/// are returned for different scenarios.
135138
///
136-
/// ### Errors and Panics
139+
/// ### Errors
140+
///
137141
/// * ENFILE - no available file descriptor number could be found
138142
/// * ENOENT - tried to open a file that did not exist
139143
/// * EINVAL - the input flags contain S_IFCHR flag representing a special
@@ -145,9 +149,15 @@ impl Cage {
145149
/// passed
146150
/// * ENXIO - the file is of type UNIX domain socket
147151
///
148-
/// A panic occurs when there is some issue fetching the file descriptor.
152+
/// ### Panics
149153
///
150-
/// for more detailed description of all the commands and return values, see
154+
/// * If truepath.file_name() returns None or if to_str() fails, causing
155+
/// unwrap() to panic.
156+
/// * If the parent inode does not exist in the inode table, causing
157+
/// unwrap() to panic.
158+
/// * When there is some other issue fetching the file descriptor.
159+
///
160+
/// For more detailed description of all the commands and return values, see
151161
/// [open(2)](https://man7.org/linux/man-pages/man2/open.2.html)
152162
153163
// This function is used to create a new File Descriptor Object and return it.
@@ -915,9 +925,61 @@ impl Cage {
915925
}
916926
}
917927

918-
//------------------------------------CREAT SYSCALL------------------------------------
919-
928+
/// ## ------------------CREAT SYSCALL------------------
929+
/// ### Description
930+
///
931+
/// The `creat_syscall()` is similar to `open_syscall()` with the "flags"
932+
/// parameter for open_syscall set to representing create, truncate or write
933+
/// only for the file. It simplifies the process of creating a new file or
934+
/// truncating an existing one by combining the O_CREAT, O_TRUNC, and
935+
/// O_WRONLY flags.
936+
/// There are generally two cases which occur when this syscall happens:
937+
/// Case 1: If the file to be opened doesn't exist, then due to O_CREAT flag,
938+
/// a new file is created at the given location and a new file descriptor is
939+
/// created and returned.
940+
/// Case 2: If the file already exists, then due to O_TRUNC flag, the file
941+
/// size gets reduced to 0, and the existing file descriptor is returned.
942+
///
943+
/// ### Function Arguments
944+
///
945+
/// The `creat_syscall()` receives two arguments:
946+
/// * `path` - This argument points to a pathname naming the file. For
947+
/// example: "/parentdir/file1" represents a file which will be either
948+
/// opened if exists or will be created at the given path.
949+
/// * `mode` - This represents the permission of the newly created file. The
950+
/// general mode used is "S_IRWXA": which represents the read, write, and
951+
/// search permissions on the new file.
952+
///
953+
/// ### Returns
954+
///
955+
/// Upon successful completion of this call, a file descriptor is returned
956+
/// which points the file which is opened. Otherwise, errors or panics
957+
/// are returned for different scenarios.
958+
///
959+
/// ### Errors
960+
///
961+
/// * ENFILE - no available file descriptor number could be found
962+
/// * ENOENT - tried to open a file that did not exist
963+
/// * EPERM - the mode bits for a file are not sane
964+
/// * ENOTDIR - tried to create a file as a child of something that isn't a
965+
/// directory
966+
/// * EEXIST - the given file already exists
967+
/// * ENXIO - the file is of type UNIX domain socket
968+
///
969+
/// ### Panics
970+
///
971+
/// * If truepath.file_name() returns None or if to_str() fails, causing
972+
/// unwrap() to panic.
973+
/// * If the parent inode does not exist in the inode table, causing
974+
/// unwrap() to panic.
975+
/// * When there is some other issue fetching the file descriptor.
976+
///
977+
/// For more detailed description of all the commands and return values, see
978+
/// [creat(3p)](https://man7.org/linux/man-pages/man3/creat.3p.html)
920979
pub fn creat_syscall(&self, path: &str, mode: u32) -> i32 {
980+
// These flags represent that the given file is either newly created
981+
// (if it doesn't exist) or truncated to zero length (if it does exist),
982+
// and it is opened for write-only access.
921983
self.open_syscall(path, O_CREAT | O_TRUNC | O_WRONLY, mode)
922984
}
923985

@@ -4488,8 +4550,8 @@ impl Cage {
44884550
drop(sementry);
44894551
// Acquire the semaphore. This operation will block the calling process until
44904552
// the
4491-
///semaphore becomes available. The`lock` method internally
4492-
/// decrements the semaphore value.
4553+
// semaphore becomes available. The`lock` method internally
4554+
// decrements the semaphore value.
44934555
// The lock fun is located in misc.rs
44944556
semaphore.lock();
44954557
} else {

src/tests/fs_tests.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,4 +2157,65 @@ pub mod fs_tests {
21572157
assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS);
21582158
lindrustfinalize();
21592159
}
2160+
2161+
#[test]
2162+
pub fn ut_lind_fs_creat_new_file() {
2163+
// Since this call is almost similar to open_syscall, and we have
2164+
// covered all the possible test scenarios for open_syscall above. So,
2165+
// just testing the basic working flow for the creat_sycall.
2166+
2167+
//acquiring a lock on TESTMUTEX prevents other tests from running concurrently,
2168+
// and also performs clean env setup
2169+
let _thelock = setup::lock_and_init();
2170+
2171+
let cage = interface::cagetable_getref(1);
2172+
2173+
// Create a file and validate the size of it.
2174+
let path = "/creatFile";
2175+
let fd = cage.creat_syscall(path, S_IRWXA);
2176+
assert!(fd > 0);
2177+
2178+
let mut statdata = StatData::default();
2179+
2180+
// The size of the file should be 0
2181+
assert_eq!(cage.stat_syscall(path, &mut statdata), 0);
2182+
assert_eq!(statdata.st_size, 0);
2183+
2184+
assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS);
2185+
lindrustfinalize();
2186+
}
2187+
2188+
#[test]
2189+
pub fn ut_lind_fs_creat_truncate_existing_file() {
2190+
//acquiring a lock on TESTMUTEX prevents other tests from running concurrently,
2191+
// and also performs clean env setup
2192+
let _thelock = setup::lock_and_init();
2193+
2194+
let cage = interface::cagetable_getref(1);
2195+
2196+
let path = "/creatFile";
2197+
// Create a new file
2198+
let fd = cage.creat_syscall(path, S_IRWXA);
2199+
2200+
// Write a string to the newly opened file of size 12
2201+
assert_eq!(cage.write_syscall(fd, str2cbuf("hello there!"), 12), 12);
2202+
2203+
// Get the stat data for the file and check for file attributes
2204+
let mut statdata = StatData::default();
2205+
assert_eq!(cage.stat_syscall(path, &mut statdata), 0);
2206+
2207+
// Validate the size of the file to be 12
2208+
assert_eq!(statdata.st_size, 12);
2209+
2210+
// Call the function on the existing file, which should truncate
2211+
// the file size to 0.
2212+
let _fd2 = cage.creat_syscall(path, S_IRWXA);
2213+
assert_eq!(cage.stat_syscall(path, &mut statdata), 0);
2214+
2215+
// Validate the size of the file to be 0 now as should be truncated
2216+
assert_eq!(statdata.st_size, 0);
2217+
2218+
assert_eq!(cage.exit_syscall(EXIT_SUCCESS), EXIT_SUCCESS);
2219+
lindrustfinalize();
2220+
}
21602221
}

0 commit comments

Comments
 (0)