From patchwork Wed Jan 22 20:03:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 37472 Received: (qmail 104274 invoked by alias); 22 Jan 2020 20:04:05 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 104199 invoked by uid 89); 22 Jan 2020 20:04:05 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=Closing, 1, 100 X-HELO: us-smtp-delivery-1.mimecast.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1579723441; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=z6c2ohgr4NeTt6z6lp8aP++nVUq5B4TIFN3BnQ+fwIg=; b=TzJDGYRi2w8E7Jo0VioN8HI00t5TRFAKHxCv+3MULh3cAv6tsGoA/8KGM8qXIubNT64IE5 Ri66x5h8HulKBbYGgWXbHSHo43t4dXgvt4xOnR9q6XFz7bGORoBB5akMvqlLM+p4L+ikwI dNRs1BJ7mwPJfq3Uys7wQSAQhtT7yV4= From: Florian Weimer To: libc-alpha@sourceware.org Subject: [PATCH 5/5] Linux: Add op/tst-o_path-locks In-Reply-To: References: Message-Id: <4b415134dbbf222d4ed751df99a0f84b81f69070.1579723048.git.fweimer@redhat.com> Date: Wed, 22 Jan 2020 21:03:56 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com The O_PATH-based fchmodat emulation relies on the fact that closing an O_PATH descriptor never releases POSIX advisory locks, so this commit adds a test case for this behavior. --- sysdeps/unix/sysv/linux/Makefile | 2 +- sysdeps/unix/sysv/linux/tst-o_path-locks.c | 100 +++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/tst-o_path-locks.c diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index f12b7b1a2d..487ff274b6 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -273,7 +273,7 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \ sysdep_headers += bits/fcntl-linux.h -tests += tst-fallocate tst-fallocate64 +tests += tst-fallocate tst-fallocate64 tst-o_path-locks endif ifeq ($(subdir),elf) 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 0000000000..07e6556f73 --- /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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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