From ad16de59f8ebc71ec7974950ac41c8311845205f Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 6 Jan 2026 15:57:01 +0200 Subject: [PATCH] Kernel: Implement basic F_{GET,SET}LK{,W} At the moment these lock the whole file which is not what is supposed to happen. Some port was trying to use these and this seems to work for that. This may cause deadlocks but that should be easy enough to find the reason because of the debug warnings --- kernel/kernel/OpenFileDescriptorSet.cpp | 40 +++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/kernel/kernel/OpenFileDescriptorSet.cpp b/kernel/kernel/OpenFileDescriptorSet.cpp index fa36b47a..2e9b0cdc 100644 --- a/kernel/kernel/OpenFileDescriptorSet.cpp +++ b/kernel/kernel/OpenFileDescriptorSet.cpp @@ -252,6 +252,46 @@ namespace Kernel m_open_files[fd].status_flags() &= O_ACCMODE; m_open_files[fd].status_flags() |= extra; return 0; + case F_GETLK: + { + dwarnln("TODO: proper fcntl F_GETLK"); + + auto* param = reinterpret_cast(extra); + const auto& flock = m_open_files[fd].description->flock; + + if (flock.lockers.empty()) + param->l_type = F_UNLCK; + else + { + *param = { + .l_type = static_cast(flock.shared ? F_RDLCK : F_WRLCK), + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 1, + .l_pid = *flock.lockers.begin(), + }; + } + + return 0; + } + case F_SETLK: + case F_SETLKW: + { + dwarnln("TODO: proper fcntl F_SETLK(W)"); + + int op = cmd == F_SETLKW ? LOCK_NB : 0; + switch (reinterpret_cast(extra)->l_type) + { + case F_UNLCK: op |= LOCK_UN; break; + case F_RDLCK: op |= LOCK_SH; break; + case F_WRLCK: op |= LOCK_EX; break; + default: + return BAN::Error::from_errno(EINVAL); + } + TRY(flock(fd, op)); + + return 0; + } default: break; }