diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2015-01-29 23:12:25 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2015-01-29 23:12:25 +0100 |
commit | 87f3243d790fd8478960528b4ad4d8e708daee74 (patch) | |
tree | 3f376e4c79afa7634466a20efed0455a322f6d55 /sysdeps | |
parent | dca581e0e7ac78a94c1e021c9e56b9818f4cb796 (diff) | |
parent | 0a137670752d07827ce8612505c85f4dafb70d28 (diff) |
Merge branch 't/lockf64' into refs/top-bases/tschwinge/Roger_Whittaker
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/mach/hurd/f_setlk.c | 68 | ||||
-rw-r--r-- | sysdeps/mach/hurd/f_setlk.h | 22 | ||||
-rw-r--r-- | sysdeps/mach/hurd/fcntl.c | 78 | ||||
-rw-r--r-- | sysdeps/mach/hurd/flockconv.c | 69 |
4 files changed, 108 insertions, 129 deletions
diff --git a/sysdeps/mach/hurd/f_setlk.c b/sysdeps/mach/hurd/f_setlk.c new file mode 100644 index 0000000000..8cd86d0db7 --- /dev/null +++ b/sysdeps/mach/hurd/f_setlk.c @@ -0,0 +1,68 @@ +/* Copyright (C) 2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/types.h> +#include <sys/file.h> +#include <fcntl.h> +#include <errno.h> + +/* XXX + We need new RPCs to support POSIX.1 fcntl file locking!! + For the time being we support the whole-file case only, + with all kinds of WRONG WRONG WRONG semantics, + by using flock. This is definitely the Wrong Thing, + but it might be better than nothing (?). */ +int +__f_setlk (int fd, int type, int whence, __off64_t start, __off64_t len, int wait) +{ + int cmd; + + switch (type) + { + case F_RDLCK: cmd |= LOCK_SH | __LOCK_ATOMIC; break; + case F_WRLCK: cmd |= LOCK_EX | __LOCK_ATOMIC; break; + case F_UNLCK: cmd = LOCK_UN; break; + default: + errno = EINVAL; + return -1; + } + + if (wait == 0) + cmd |= LOCK_NB; + + switch (whence) + { + case SEEK_SET: + if (start == 0 && len == 0) /* Whole file request. */ + break; + /* It seems to be common for applications to lock the first + byte of the file when they are really doing whole-file locking. + So, since it's so wrong already, might as well do that too. */ + if (start == 0 && len == 1) + break; + /* FALLTHROUGH */ + case SEEK_CUR: + case SEEK_END: + errno = ENOTSUP; + return -1; + default: + errno = EINVAL; + return -1; + } + + return __flock (fd, cmd); +} diff --git a/sysdeps/mach/hurd/f_setlk.h b/sysdeps/mach/hurd/f_setlk.h new file mode 100644 index 0000000000..363d87fd17 --- /dev/null +++ b/sysdeps/mach/hurd/f_setlk.h @@ -0,0 +1,22 @@ +/* Copyright (C) 2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _F_SETLK_H +#define _F_SETLK_H 1 + +extern int __f_setlk (int fd, int type, int whence, __off64_t start, __off64_t len, int wait); +#endif /* f_setlk.h */ diff --git a/sysdeps/mach/hurd/fcntl.c b/sysdeps/mach/hurd/fcntl.c index 4622370ed9..a7ef21be1c 100644 --- a/sysdeps/mach/hurd/fcntl.c +++ b/sysdeps/mach/hurd/fcntl.c @@ -21,8 +21,7 @@ #include <hurd/fd.h> #include <stdarg.h> #include <sys/file.h> /* XXX for LOCK_* */ - -#include "flockconv.c" +#include "f_setlk.h" /* Perform file control operations on FD. */ int @@ -130,56 +129,24 @@ __libc_fcntl (int fd, int cmd, ...) case F_SETLK: case F_SETLKW: { - /* XXX - We need new RPCs to support POSIX.1 fcntl file locking!! - For the time being we support the whole-file case only, - with all kinds of WRONG WRONG WRONG semantics, - by using flock. This is definitely the Wrong Thing, - but it might be better than nothing (?). */ struct flock *fl = va_arg (ap, struct flock *); + int wait = 0; va_end (ap); switch (cmd) { case F_GETLK: errno = ENOSYS; return -1; - case F_SETLK: - cmd = LOCK_NB; - break; - default: - cmd = 0; - break; - } - switch (fl->l_type) - { - case F_RDLCK: cmd |= LOCK_SH | __LOCK_ATOMIC; break; - case F_WRLCK: cmd |= LOCK_EX | __LOCK_ATOMIC; break; - case F_UNLCK: cmd |= LOCK_UN; break; - default: - errno = EINVAL; - return -1; - } - switch (fl->l_whence) - { - case SEEK_SET: - if (fl->l_start == 0 && fl->l_len == 0) /* Whole file request. */ - break; - /* It seems to be common for applications to lock the first - byte of the file when they are really doing whole-file locking. - So, since it's so wrong already, might as well do that too. */ - if (fl->l_start == 0 && fl->l_len == 1) - break; + case F_SETLKW: + wait = 1; /* FALLTHROUGH */ - case SEEK_CUR: - case SEEK_END: - errno = ENOTSUP; - return -1; + case F_SETLK: + return __f_setlk (fd, fl->l_type, fl->l_whence, + fl->l_start, fl->l_end, wait); default: errno = EINVAL; return -1; } - - return __flock (fd, cmd); } case F_GETLK64: @@ -187,32 +154,23 @@ __libc_fcntl (int fd, int cmd, ...) case F_SETLKW64: { struct flock64 *fl64 = va_arg (ap, struct flock64 *); - struct flock fl; - - if (flock64_conv (&fl, fl64)) - { - result = -1; - break; - } - + int wait = 0; + va_end (ap); switch (cmd) { case F_GETLK64: - result = fcntl (fd, F_GETLK, &fl); - if (flock_conv (fl64, &fl)) - result = -1; - break; - + errno = ENOSYS; + return -1; case F_SETLK64: - result = fcntl (fd, F_SETLK, &fl); - break; - + wait = 1; + /* FALLTHROUGH */ case F_SETLKW64: - result = fcntl (fd, F_SETLKW, &fl); - break; + return __f_setlk (fd, fl->l_type, fl->l_whence, + fl->l_start, fl->l_end, wait); + default: + errno = EINVAL; + return -1; } - - break; } case F_GETFL: /* Get per-open flags. */ diff --git a/sysdeps/mach/hurd/flockconv.c b/sysdeps/mach/hurd/flockconv.c deleted file mode 100644 index 4438784740..0000000000 --- a/sysdeps/mach/hurd/flockconv.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Convert between `struct flock' format, and `struct flock64' format. - Copyright (C) 2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <errno.h> -#include <fcntl.h> - -static inline int -flock64_conv (struct flock *buf, const struct flock64 *buf64) -{ - if (sizeof *buf == sizeof *buf64 - && sizeof buf->l_start == sizeof buf64->l_start - && sizeof buf->l_len == sizeof buf64->l_len) - { - *buf = *(struct flock *) buf64; - return 0; - } - - buf->l_type = buf64->l_type; - buf->l_whence = buf64->l_whence; - buf->l_start = buf64->l_start; - buf->l_len = buf64->l_len; - buf->l_pid = buf64->l_pid; - - if ((sizeof buf->l_start != sizeof buf64->l_start - && buf->l_start != buf64->l_start) - || (sizeof buf->l_len != sizeof buf64->l_len - && buf->l_len != buf64->l_len)) - { - __set_errno (EOVERFLOW); - return -1; - } - - return 0; -} - -static inline int -flock_conv (struct flock64 *buf64, const struct flock *buf) -{ - if (sizeof *buf == sizeof *buf64 - && sizeof buf->l_start == sizeof buf64->l_start - && sizeof buf->l_len == sizeof buf64->l_len) - { - *buf64 = *(struct flock64 *) buf; - return 0; - } - - buf64->l_type = buf->l_type; - buf64->l_whence = buf->l_whence; - buf64->l_start = buf->l_start; - buf64->l_len = buf->l_len; - buf64->l_pid = buf->l_pid; - - return 0; -} |