/*
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;
}