• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) International Business Machines  Corp., 2002
4  * Author: Cyril Hrubis
5  *
6  * Test Description:
7  *  This test verifies that flock() cannot unlock a file locked by another
8  *  task.
9  *
10  * Test Steps:
11  *  Fork a child processes The parent flocks a file with LOCK_EX Child waits
12  *  for that to happen, then checks to make sure it is locked.  Child then
13  *  tries to unlock the file. If the unlock succeeds, the child attempts to
14  *  lock the file with LOCK_EX. The test passes if the child is able to lock
15  *  the file.
16  */
17 
18 #include <errno.h>
19 #include <stdlib.h>
20 #include <sys/file.h>
21 
22 #include "tst_test.h"
23 
childfunc(int fd)24 static void childfunc(int fd)
25 {
26 	int fd2;
27 	TST_CHECKPOINT_WAIT(0);
28 
29 	fd2 = SAFE_OPEN("testfile", O_RDWR);
30 	if (flock(fd2, LOCK_EX | LOCK_NB) != -1)
31 		tst_brk(TBROK, "CHILD: The file was not already locked");
32 
33 	TEST(flock(fd, LOCK_UN));
34 	if (TST_RET == -1) {
35 		tst_res(TFAIL, "CHILD: Unable to unlock file locked by "
36 			"parent: %s", tst_strerrno(TST_ERR));
37 		exit(1);
38 	} else {
39 		tst_res(TPASS, "CHILD: File locked by parent unlocked");
40 	}
41 
42 	TEST(flock(fd2, LOCK_EX | LOCK_NB));
43 	if (TST_RET == -1) {
44 		tst_res(TFAIL, "CHILD: Unable to unlock file after "
45 			"unlocking: %s", tst_strerrno(TST_ERR));
46 		exit(1);
47 	} else {
48 		tst_res(TPASS, "Locking after unlock passed");
49 	}
50 
51 	SAFE_CLOSE(fd);
52 	SAFE_CLOSE(fd2);
53 
54 	exit(0);
55 }
56 
verify_flock(void)57 static void verify_flock(void)
58 {
59 	int fd1;
60 	pid_t pid;
61 
62 	fd1 = SAFE_OPEN("testfile", O_RDWR);
63 
64 	pid = SAFE_FORK();
65 	if (pid == 0)
66 		childfunc(fd1);
67 
68 	TEST(flock(fd1, LOCK_EX | LOCK_NB));
69 	if (TST_RET != 0) {
70 		tst_res(TFAIL | TTERRNO,
71 			"Parent: Initial attempt to flock() failed");
72 	} else {
73 		tst_res(TPASS,
74 			"Parent: Initial attempt to flock() passed");
75 	}
76 
77 	TST_CHECKPOINT_WAKE(0);
78 
79 	tst_reap_children();
80 
81 	SAFE_CLOSE(fd1);
82 }
83 
setup(void)84 static void setup(void)
85 {
86 	int fd;
87 
88 	fd = SAFE_OPEN("testfile", O_CREAT | O_TRUNC | O_RDWR, 0666);
89 	SAFE_CLOSE(fd);
90 }
91 
92 static struct tst_test test = {
93 	.test_all = verify_flock,
94 	.needs_checkpoints = 1,
95 	.forks_child = 1,
96 	.setup = setup,
97 };
98