kernel/fifo: Properly support opening FIFOs in O_RDWR mode.

While pipe() only supports a read end and a write end, named FIFOs
are supposed to allow opening in read/write mode (which, indeed,
is something the Fish shell seems to require.)

The code that checks open_mode in the read/write routines was introduced
all the way back in 2003 (2469f26dfc).
At that time, the VFS did not do open_mode checks on FDs in the
I/O syscalls, so these doubled as permissions checks. Now, however,
the VFS does check that in common_user_io, so we can remove these
entirely and let things behave as they should.

Additionally, there is now also no reason to prevent select()ing
on both events for the same FD independent of open_mode, so
allow that too.

Change-Id: Ib3cba76d18e91b7c00d1695e8d29dd47cae06b79
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5427
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2022-07-01 18:57:28 +00:00
committed by waddlesplash
parent fe3405c087
commit 27fda3e46f
+7 -12
View File
@@ -634,7 +634,7 @@ Inode::Open(int openMode)
{
MutexLocker locker(RequestLock());
if ((openMode & O_ACCMODE) == O_WRONLY)
if ((openMode & O_ACCMODE) == O_WRONLY || (openMode & O_ACCMODE) == O_RDWR)
fWriterCount++;
if ((openMode & O_ACCMODE) == O_RDONLY || (openMode & O_ACCMODE) == O_RDWR)
@@ -669,11 +669,12 @@ Inode::Close(file_cookie* cookie)
request->Notify(B_FILE_ERROR);
}
if ((openMode & O_ACCMODE) == O_WRONLY && --fWriterCount == 0)
NotifyEndClosed(true);
if ((openMode & O_ACCMODE) == O_WRONLY || (openMode & O_ACCMODE) == O_RDWR) {
if (--fWriterCount == 0)
NotifyEndClosed(true);
}
if ((openMode & O_ACCMODE) == O_RDONLY
|| (openMode & O_ACCMODE) == O_RDWR) {
if ((openMode & O_ACCMODE) == O_RDONLY || (openMode & O_ACCMODE) == O_RDWR) {
if (--fReaderCount == 0)
NotifyEndClosed(false);
}
@@ -697,7 +698,7 @@ Inode::Select(uint8 event, selectsync* sync, int openMode)
{
bool writer = true;
select_sync_pool** pool;
if ((openMode & O_RWMASK) == O_RDONLY) {
if (event == B_SELECT_READ || (openMode & O_RWMASK) == O_RDONLY) {
pool = &fReadSelectSyncPool;
writer = false;
} else if ((openMode & O_RWMASK) == O_WRONLY) {
@@ -938,9 +939,6 @@ fifo_read(fs_volume* _volume, fs_vnode* _node, void* _cookie,
MutexLocker locker(inode->RequestLock());
if ((cookie->open_mode & O_RWMASK) != O_RDONLY)
return B_NOT_ALLOWED;
if (inode->IsActive() && inode->WriterCount() == 0) {
// as long there is no writer, and the pipe is empty,
// we always just return 0 to indicate end of file
@@ -987,9 +985,6 @@ fifo_write(fs_volume* _volume, fs_vnode* _node, void* _cookie,
MutexLocker locker(inode->RequestLock());
if ((cookie->open_mode & O_RWMASK) != O_WRONLY)
return B_NOT_ALLOWED;
size_t length = *_length;
if (length == 0)
return B_OK;