From d6571884c734b06c8f5270d00a2f2746714de613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 5 Oct 2004 13:36:44 +0000 Subject: [PATCH] Added basic fcntl() functions and syscalls. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9201 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/fs/vfs.cpp | 87 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 4 deletions(-) diff --git a/src/kernel/core/fs/vfs.cpp b/src/kernel/core/fs/vfs.cpp index 62d68c1688..3b202832a6 100755 --- a/src/kernel/core/fs/vfs.cpp +++ b/src/kernel/core/fs/vfs.cpp @@ -2594,21 +2594,86 @@ common_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer, size_t { struct vnode *vnode = descriptor->u.vnode; - if (FS_CALL(vnode, ioctl)) - return FS_CALL(vnode, ioctl)(vnode->mount->cookie,vnode->private_node,descriptor->cookie,op,buffer,length); + if (FS_CALL(vnode, ioctl)) { + return FS_CALL(vnode, ioctl)(vnode->mount->cookie, vnode->private_node, + descriptor->cookie, op, buffer, length); + } return EOPNOTSUPP; } +static status_t +common_fcntl(int fd, int op, uint32 argument, bool kernel) +{ + struct file_descriptor *descriptor; + struct vnode *vnode; + status_t status; + + FUNCTION(("common_fcntl(fd = %d, op = %d, argument = %lx, %s)\n", + fd, op, argument, kernel ? "kernel" : "user")); + + descriptor = get_fd_and_vnode(fd, &vnode, kernel); + if (descriptor == NULL) + return B_FILE_ERROR; + + switch (op) { + case F_SETFD: + // Set file descriptor flags + + // O_CLOEXEC is the only flag available at this time + if (argument == FD_CLOEXEC) + descriptor->open_mode |= O_CLOEXEC; + else + descriptor->open_mode &= O_CLOEXEC; + + status = B_OK; + break; + + case F_GETFD: + // Get file descriptor flags + status = (descriptor->open_mode & O_CLOEXEC) ? FD_CLOEXEC : 0; + break; + + case F_SETFL: + // Set file descriptor open mode + if (FS_CALL(vnode, set_flags)) { + // we only accept changes to O_APPEND and O_NONBLOCK + argument &= O_APPEND | O_NONBLOCK; + + status = FS_CALL(vnode, set_flags)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, (int)argument); + if (status == B_OK) { + // update this descriptor's open_mode field + descriptor->open_mode = (descriptor->open_mode & ~(O_APPEND | O_NONBLOCK)) | argument; + } + } else + status = EOPNOTSUPP; + break; + + case F_GETFL: + // Get file descriptor open mode + status = descriptor->open_mode; + break; + + // ToDo: add support for more ops + + default: + status = B_BAD_VALUE; + } + + put_fd(descriptor); + return status; +} + + static status_t common_sync(int fd, bool kernel) { struct file_descriptor *descriptor; struct vnode *vnode; - int status; + status_t status; - FUNCTION(("vfs_fsync: entry. fd %d kernel %d\n", fd, kernel)); + FUNCTION(("common_fsync: entry. fd %d kernel %d\n", fd, kernel)); descriptor = get_fd_and_vnode(fd, &vnode, kernel); if (descriptor == NULL) @@ -4026,6 +4091,13 @@ _kern_open_dir(int fd, const char *path) } +status_t +_kern_fcntl(int fd, int op, uint32 argument) +{ + return common_fcntl(fd, op, argument, true); +} + + status_t _kern_fsync(int fd) { @@ -4805,6 +4877,13 @@ _user_open_parent_dir(int fd, char *userName, size_t nameLength) } +status_t +_user_fcntl(int fd, int op, uint32 argument) +{ + return common_fcntl(fd, op, argument, false); +} + + status_t _user_fsync(int fd) {