From 67c9a04d58b2e2041c865a06d39303b897d3b31c Mon Sep 17 00:00:00 2001 From: Matheus Date: Fri, 23 Sep 2022 19:37:25 -0300 Subject: [PATCH] fd: change allocation to add a lowest fd option --- src/fs/fd.c | 24 ++++++++++++++---------- src/include/kernel/fd.h | 3 +-- src/sys/sched/scheduler.c | 6 +++--- src/sys/syscalls/open.c | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/fs/fd.c b/src/fs/fd.c index d38f487d..de2f531e 100644 --- a/src/fs/fd.c +++ b/src/fs/fd.c @@ -4,8 +4,6 @@ #include #include -// XXX limit the max fd number - int fd_release(fd_t* fd){ spinlock_release(&fd->lock); return 0; @@ -28,16 +26,19 @@ int fd_access(fdtable_t* fdtable, fd_t** fd, int ifd){ } -int fd_alloc(fdtable_t* fdtable, fd_t** fd, int* ifd){ +int fd_alloc(fdtable_t* fdtable, fd_t** fd, int* ifd, int lowest){ + if(lowest >= MAX_FD){ + return EBADF; + } + spinlock_acquire(&fdtable->lock); // find fd to use bool ok = false; - for(uintmax_t i = fdtable->firstfreefd; i < fdtable->fdcount; ++i){ + for(uintmax_t i = lowest; i < fdtable->fdcount; ++i){ if(!fdtable->fd[i]){ - fdtable->firstfreefd = i; *ifd = i; ok = true; break; @@ -46,12 +47,16 @@ int fd_alloc(fdtable_t* fdtable, fd_t** fd, int* ifd){ // resize table + int targetfd = fdtable->fdcount > lowest ? fdtable->fdcount : lowest; + if(!ok){ + if(fdtable->fdcount == MAX_FD){ spinlock_release(&fdtable->lock); return EMFILE; } - fd_t** tmp = realloc(fdtable->fd, sizeof(fd_t*)*(fdtable->fdcount + 1)); + + fd_t** tmp = realloc(fdtable->fd, sizeof(fd_t*)*(targetfd + 1)); if(!tmp){ spinlock_release(&fdtable->lock); @@ -59,8 +64,8 @@ int fd_alloc(fdtable_t* fdtable, fd_t** fd, int* ifd){ } fdtable->fd = tmp; - *ifd = fdtable->fdcount; - ++fdtable->fdcount; + *ifd = targetfd; + fdtable->fdcount = targetfd + 1; } @@ -197,7 +202,7 @@ int fd_duplicate(fdtable_t* table, int src, int dest, int type, int* ret){ } if(type == 1){ // allocate for dup - err = fd_alloc(table, &destfd, &dest); + err = fd_alloc(table, &destfd, &dest, dest); // for fcntl F_DUPFD, dest is the lowest fd if(err){ fd_release(srcfd); return err; @@ -226,7 +231,6 @@ int fd_duplicate(fdtable_t* table, int src, int dest, int type, int* ret){ if(destfd){ spinlock_acquire(&destfd->lock); if(--destfd->refcount == 0){ - printf("killing\n"); if(destfd->node) vfs_close(destfd->node); free(destfd); } diff --git a/src/include/kernel/fd.h b/src/include/kernel/fd.h index 16798b36..2f53cdff 100644 --- a/src/include/kernel/fd.h +++ b/src/include/kernel/fd.h @@ -46,11 +46,10 @@ typedef struct { typedef struct { int lock; size_t fdcount; - uintmax_t firstfreefd; fd_t** fd; } fdtable_t; -int fd_alloc(fdtable_t* fdtable, fd_t** fd, int* ifd); +int fd_alloc(fdtable_t* fdtable, fd_t** fd, int* ifd, int lowest); int fd_free(fdtable_t* fdtable, int ifd); int fd_access(fdtable_t* fdtable, fd_t** fd, int ifd); int fd_release(fd_t* fd); diff --git a/src/sys/sched/scheduler.c b/src/sys/sched/scheduler.c index 6dc82bd6..f3ac73b3 100644 --- a/src/sys/sched/scheduler.c +++ b/src/sys/sched/scheduler.c @@ -417,9 +417,9 @@ void sched_runinit(){ fd_t *stdinfd, *stdoutfd, *stderrfd; - fd_alloc(&proc->fdtable, &stdinfd, &tmp); - fd_alloc(&proc->fdtable, &stdoutfd, &tmp); - fd_alloc(&proc->fdtable, &stderrfd, &tmp); + fd_alloc(&proc->fdtable, &stdinfd, &tmp, 0); + fd_alloc(&proc->fdtable, &stdoutfd, &tmp, 0); + fd_alloc(&proc->fdtable, &stderrfd, &tmp, 0); #define CONSOLE_PATH "dev/console" diff --git a/src/sys/syscalls/open.c b/src/sys/syscalls/open.c index 4235d29f..8a2d5e97 100644 --- a/src/sys/syscalls/open.c +++ b/src/sys/syscalls/open.c @@ -32,7 +32,7 @@ syscallret syscall_open(const char* pathname, int flags, mode_t mode){ int ifd; fd_t* fd; - int err = fd_alloc(&proc->fdtable, &fd, &ifd); + int err = fd_alloc(&proc->fdtable, &fd, &ifd, 0); if(err){ retv.errno = err;