2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2016 Joyent, Inc.
17 * Acquire the specified kind of lock with the specified parameters. After
18 * acquiring the lock, a byte will be written to stdout. The program will
19 * then wait for a byte to be written to stdin before exiting.
21 * Usage: <posix|ofd|flock> <shared|exclusive> <path>
35 static void acq_fcntl(int, int, int);
36 static void acq_flock(int fd
, int mode
);
37 static void acq_run(int, lock_style_t
, boolean_t
);
41 acq_fcntl(int fd
, int cmd
, int mode
)
47 * Acquire the lock, and then try reacquiring it several times. Once we
48 * have acquired the lock, trying to acquire it again should succeed,
49 * and shouldn't upgrade, downgrade or free the lock.
51 for (i
= 0; i
< 3; i
++) {
52 flock_reinit(&fl
, mode
);
53 flock_log("Acquiring lock (fcntl)...\n");
54 ret
= fcntl(fd
, cmd
, &fl
);
56 err(EXIT_FAILURE
, "fcntl failed");
61 /* Let the parent know we have the lock and wait */
62 flock_log("Waiting (fcntl)...\n");
67 flock_reinit(&fl
, F_UNLCK
);
68 flock_log("Releasing lock (fcntl)...\n");
69 ret
= fcntl(fd
, cmd
, &fl
);
71 err(EXIT_FAILURE
, "fcntl failed");
77 acq_flock(int fd
, int mode
)
82 * Acquire the lock, and then try reacquiring it several times. Once we
83 * have acquired the lock, trying to acquire it again should succeed,
84 * and shouldn't upgrade, downgrade or free the lock.
86 for (i
= 0; i
< 3; i
++) {
87 flock_log("Acquiring lock (flock)...\n");
88 ret
= flock(fd
, mode
);
90 err(EXIT_FAILURE
, "flock failed");
94 /* Wait to be okayed to unlock */
95 flock_log("Waiting (flock)...\n");
100 flock_log("Releasing lock (flock)...\n");
101 ret
= flock(fd
, LOCK_UN
);
103 err(EXIT_FAILURE
, "flock failed");
109 acq_run(int fd
, lock_style_t style
, boolean_t is_exclusive
)
113 acq_fcntl(fd
, F_SETLKW
, is_exclusive
? F_WRLCK
: F_RDLCK
);
116 acq_fcntl(fd
, F_OFD_SETLKW
, is_exclusive
? F_WRLCK
: F_RDLCK
);
119 acq_flock(fd
, is_exclusive
? LOCK_EX
: LOCK_SH
);
128 main(int argc
, char *argv
[])
130 char *modestr
, *path
;
132 boolean_t is_exclusive
;
136 errx(EXIT_FAILURE
, BAD_ARGS_MESSAGE
, argc
- 1);
142 style
= flock_styleenum(argv
[1]);
144 if (strcmp(modestr
, "shared") == 0) {
145 is_exclusive
= B_FALSE
;
146 } else if (strcmp(modestr
, "exclusive") == 0) {
147 is_exclusive
= B_TRUE
;
149 errx(EXIT_FAILURE
, BAD_MODE_MESSAGE
);
152 boolean_t rdonly
= style
== LSTYLE_FLOCK
|| !is_exclusive
;
153 fd
= open(path
, rdonly
? O_RDONLY
: O_WRONLY
);
155 err(EXIT_FAILURE
, "Failed to open %s", path
);
158 acq_run(fd
, style
, is_exclusive
);