Fix F_DUPFD crash when there is no space in file table

This commit is contained in:
He Sun 2020-04-02 16:14:31 +08:00
parent 978edf8a17
commit 52cb897436
2 changed files with 22 additions and 5 deletions

@ -33,17 +33,23 @@ impl FileTable {
if min_fd >= table.len() { if min_fd >= table.len() {
let expand_size = min_fd - table.len() + 1; let expand_size = min_fd - table.len() + 1;
for _ in 0..expand_size { for _ in 0..expand_size {
table.push(None) table.push(None);
} }
} }
table let free_fd = table
.iter() .iter()
.enumerate() .enumerate()
.skip(min_fd as usize) .skip(min_fd as usize)
.find(|&(idx, opt)| opt.is_none()) .find(|&(idx, opt)| opt.is_none());
.unwrap()
.0 if let Some((index, _)) = free_fd {
index
} else {
// Span table when no free fd is found
table.push(None);
table.len() - 1
}
} as FileDesc; } as FileDesc;
self.put_at(min_free_fd, file_ref, close_on_spawn); self.put_at(min_free_fd, file_ref, close_on_spawn);

@ -69,6 +69,12 @@ static int __fcntl_getlk_and_setlk(int fd, int open_flags) {
return 0; 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); typedef int(*test_fcntl_func_t)(int fd, int open_flags);
static int test_fcntl_framework(test_fcntl_func_t fn) { 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); return test_fcntl_framework(__fcntl_getlk_and_setlk);
} }
static int test_fcntl_dupfd() {
return test_fcntl_framework(__fcntl_dupfd);
}
// ============================================================================ // ============================================================================
// Test suite // Test suite
// ============================================================================ // ============================================================================
@ -112,6 +122,7 @@ static test_case_t test_cases[] = {
TEST_CASE(test_fcntl_getfl), TEST_CASE(test_fcntl_getfl),
TEST_CASE(test_fcntl_setfl), TEST_CASE(test_fcntl_setfl),
TEST_CASE(test_getlk_and_setlk), TEST_CASE(test_getlk_and_setlk),
TEST_CASE(test_fcntl_dupfd),
}; };
int main() { int main() {