diff options
author | Florian Weimer <fweimer@redhat.com> | 2020-02-09 11:51:08 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2020-02-09 11:51:08 +0100 |
commit | f6233ab412c3bebebacf65745e775e01506dd58d (patch) | |
tree | 953377ff860085247980c856e1f55a56d840fc80 /sysdeps/unix/sysv/linux/tst-o_path-locks.c | |
parent | 173ec37bb2af6e30892a141d74d42db5957ddd36 (diff) | |
download | glibc-f6233ab412c3bebebacf65745e775e01506dd58d.zip glibc-f6233ab412c3bebebacf65745e775e01506dd58d.tar.gz glibc-f6233ab412c3bebebacf65745e775e01506dd58d.tar.bz2 |
Linux: Add io/tst-o_path-locks test
The O_PATH-based fchmodat emulation will rely on the fact that closing
an O_PATH descriptor never releases POSIX advisory locks, so this
commit adds a test case for this behavior.
Diffstat (limited to 'sysdeps/unix/sysv/linux/tst-o_path-locks.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/tst-o_path-locks.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/tst-o_path-locks.c b/sysdeps/unix/sysv/linux/tst-o_path-locks.c new file mode 100644 index 0000000..07e6556 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-o_path-locks.c @@ -0,0 +1,100 @@ +/* Test that closing O_PATH descriptors does not release POSIX advisory locks. + Copyright (C) 2020 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdlib.h> +#include <support/check.h> +#include <support/namespace.h> +#include <support/support.h> +#include <support/temp_file.h> +#include <support/xunistd.h> + +/* The subprocess writes the errno value of the lock operation + here. */ +static int *shared_errno; + +/* The path of the temporary file which is locked. */ +static char *path; + +/* Try to obtain an exclusive lock on the file at path. */ +static void +subprocess (void *closure) +{ + int fd = xopen (path, O_RDWR, 0); + struct flock64 lock = { .l_type = F_WRLCK, }; + int ret = fcntl64 (fd, F_SETLK, &lock); + if (ret == 0) + *shared_errno = 0; + else + *shared_errno = errno; + xclose (fd); +} + +/* Return true if the file at path is currently locked, false if + not. */ +static bool +probe_lock (void) +{ + *shared_errno = -1; + support_isolate_in_subprocess (subprocess, NULL); + if (*shared_errno == 0) + /* Lock was aquired by the subprocess, so this process has not + locked it. */ + return false; + else + { + /* POSIX allows both EACCES and EAGAIN. Linux use EACCES. */ + TEST_COMPARE (*shared_errno, EAGAIN); + return true; + } +} + +static int +do_test (void) +{ + shared_errno = support_shared_allocate (sizeof (*shared_errno)); + int fd = create_temp_file ("tst-o_path-locks-", &path); + + /* The file is not locked initially. */ + TEST_VERIFY (!probe_lock ()); + + struct flock64 lock = { .l_type = F_WRLCK, }; + TEST_COMPARE (fcntl64 (fd, F_SETLK, &lock), 0); + + /* The lock has been acquired. */ + TEST_VERIFY (probe_lock ()); + + /* Closing the same file via a different descriptor releases the + lock. */ + xclose (xopen (path, O_RDONLY, 0)); + TEST_VERIFY (!probe_lock ()); + + /* But not if it is an O_PATH descriptor. */ + TEST_COMPARE (fcntl64 (fd, F_SETLK, &lock), 0); + xclose (xopen (path, O_PATH, 0)); + TEST_VERIFY (probe_lock ()); + + xclose (fd); + free (path); + support_shared_free (shared_errno); + return 0; +} + +#include <support/test-driver.c> |