diff --git a/sortix/descriptor.cpp b/sortix/descriptor.cpp index 38cc3a91..9ec02417 100644 --- a/sortix/descriptor.cpp +++ b/sortix/descriptor.cpp @@ -110,6 +110,23 @@ Descriptor::~Descriptor() { } +bool Descriptor::SetFlags(int new_dflags) +{ + // TODO: Hmm, there is race condition between changing the flags here and + // the code that uses the flags below. We could add a lock, but that + // would kinda prevent concurrency on the same file descriptor. Since + // the chances of this becoming a problem is rather slim (but could + // happen!), we'll do the unsafe thing for now. (See below also) + dflags = (dflags & ~DESCRIPTOR_FLAGS) & (new_dflags & DESCRIPTOR_FLAGS); + return true; +} + +int Descriptor::GetFlags() +{ + // TODO: The race condition also applies here if the variable can change. + return dflags; +} + Ref Descriptor::Fork() { Ref ret(new Descriptor(vnode, dflags)); diff --git a/sortix/include/sortix/kernel/descriptor.h b/sortix/include/sortix/kernel/descriptor.h index 9179c49d..8c0ec279 100644 --- a/sortix/include/sortix/kernel/descriptor.h +++ b/sortix/include/sortix/kernel/descriptor.h @@ -53,6 +53,8 @@ public: Descriptor(Ref vnode, int dflags); virtual ~Descriptor(); Ref Fork(); + bool SetFlags(int new_dflags); + int GetFlags(); int sync(ioctx_t* ctx); int stat(ioctx_t* ctx, struct stat* st); int chmod(ioctx_t* ctx, mode_t mode); diff --git a/sortix/io.cpp b/sortix/io.cpp index 45b62fb2..84aef4fc 100644 --- a/sortix/io.cpp +++ b/sortix/io.cpp @@ -300,6 +300,7 @@ static int sys_fstat(int fd, struct stat* st) static int sys_fcntl(int fd, int cmd, unsigned long arg) { Ref dtable = CurrentProcess()->GetDTable(); + Ref desc; int ret = -1; switch ( cmd ) { @@ -310,8 +311,12 @@ static int sys_fcntl(int fd, int cmd, unsigned long arg) ret = dtable->GetFlags(fd); break; case F_SETFL: + if ( (desc = dtable->Get(fd)) ) + ret = desc->SetFlags((int) arg) ? 0 : -1; + break; case F_GETFL: - errno = ENOSYS; + if ( (desc = dtable->Get(fd)) ) + ret = desc->GetFlags(); break; default: errno = EINVAL;