/* Copyright (C) 1994, 2002, 2015-2019 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the GNU Hurd. If not, see . */ #include "priv.h" #include "trivfs_fs_S.h" #include #include #include "mach-printf.h" kern_return_t trivfs_S_file_lock (struct trivfs_protid *cred, mach_port_t reply, mach_msg_type_name_t reply_type, int flags) { error_t err = 0; struct flock64 lock; struct trivfs_peropen *po = cred->po; struct trivfs_node *tp = cred->po->tp; int openmodes = cred->po->openmodes; mach_port_t rendezvous = MACH_PORT_NULL; if (!cred) return EOPNOTSUPP; mach_printf("libtrivfs/file-lock.c(trivfs_S_file_lock)\n"); lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; if (flags & LOCK_UN) lock.l_type = F_UNLCK; else if (flags & LOCK_SH) lock.l_type = F_RDLCK; else if (flags & LOCK_EX) lock.l_type = F_WRLCK; else return EINVAL; if (!po) { mach_printf("libtrivfs/file-lock.c(trivfs_S_file_lock): !po\n"); po = trivfs_make_peropen (cred, flags); if (!po) return ENOMEM; cred->po = po; } if (!tp) { mach_printf("libtrivfs/file-lock.c(trivfs_S_file_lock): !tp\n"); tp = trivfs_make_node(); if (!tp) return ENOMEM; cred->po->tp = tp; } /* XXX: Fix for flock(2) calling fcntl(2) From flock(2): A shared or exclusive lock can be placed on a file regardless of the mode in which the file was opened. */ if (cred->po->openmodes & (O_RDONLY|O_WRONLY|O_EXEC)) openmodes |= O_RDONLY|O_WRONLY; pthread_mutex_lock (&tp->lock); err = fshelp_rlock_tweak (&tp->credlock, &tp->lock, &cred->po->lock_status, openmodes, 0, 0, flags & LOCK_NB ? F_SETLK64 : F_SETLKW64, &lock, rendezvous); pthread_mutex_unlock (&tp->lock); return err; }