diff --git a/src/libos/src/fs/file_table.rs b/src/libos/src/fs/file_table.rs index 4336044b..5ce2766c 100644 --- a/src/libos/src/fs/file_table.rs +++ b/src/libos/src/fs/file_table.rs @@ -33,17 +33,23 @@ impl FileTable { if min_fd >= table.len() { let expand_size = min_fd - table.len() + 1; for _ in 0..expand_size { - table.push(None) + table.push(None); } } - table + let free_fd = table .iter() .enumerate() .skip(min_fd as usize) - .find(|&(idx, opt)| opt.is_none()) - .unwrap() - .0 + .find(|&(idx, opt)| opt.is_none()); + + if let Some((index, _)) = free_fd { + index + } else { + // Span table when no free fd is found + table.push(None); + table.len() - 1 + } } as FileDesc; self.put_at(min_free_fd, file_ref, close_on_spawn); diff --git a/test/fcntl/main.c b/test/fcntl/main.c index 6c01bd6a..221d3502 100644 --- a/test/fcntl/main.c +++ b/test/fcntl/main.c @@ -69,6 +69,12 @@ static int __fcntl_getlk_and_setlk(int fd, int open_flags) { return 0; } +static int __fcntl_dupfd(int fd, int open_flags) { + if (fcntl(fd, F_DUPFD, 0) < 0) + THROW_ERROR("failed to duplicate the fd"); + return 0; +} + typedef int(*test_fcntl_func_t)(int fd, int open_flags); static int test_fcntl_framework(test_fcntl_func_t fn) { @@ -104,6 +110,10 @@ static int test_getlk_and_setlk() { return test_fcntl_framework(__fcntl_getlk_and_setlk); } +static int test_fcntl_dupfd() { + return test_fcntl_framework(__fcntl_dupfd); +} + // ============================================================================ // Test suite // ============================================================================ @@ -112,6 +122,7 @@ static test_case_t test_cases[] = { TEST_CASE(test_fcntl_getfl), TEST_CASE(test_fcntl_setfl), TEST_CASE(test_getlk_and_setlk), + TEST_CASE(test_fcntl_dupfd), }; int main() {