]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
flock: user-configurable exit code
authorJan \"Yenya\" Kasprzak <kas@fi.muni.cz>
Tue, 5 Jun 2012 14:26:58 +0000 (16:26 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 15 Jun 2012 09:12:06 +0000 (11:12 +0200)
When locking the file fails with -n or -w option, caller has no way
to distinguish between the exit code 1 of the -c command,
and the exit code 1 of flock(1) caused by the conflicting lock.

Add a new -E <exitcode> (--conflict-exit-code) option to set
the exit code for the case of locking failure to any value.

sys-utils/flock.1
sys-utils/flock.c

index 5a6f27fbbdb052d409c84ce55e19ad3d579ace46..b50c619cf350fa29a92b0d3329a13b753fed2485 100644 (file)
@@ -71,13 +71,19 @@ cases, for example if the enclosed command group may have forked a background
 process which should not be holding the lock.
 .TP
 \fB\-n\fP, \fB\-\-nb\fP, \fB\-\-nonblock\fP
-Fail (with an exit code of 1) rather than wait if the lock cannot be
+Fail rather than wait if the lock cannot be
 immediately acquired.
+See the
+.I \-E
+option for the exit code used.
 .TP
 \fB\-w\fP, \fB\-\-wait\fP, \fB\-\-timeout\fP \fIseconds\fP
-Fail (with an exit code of 1) if the lock cannot be acquired within
+Fail if the lock cannot be acquired within
 .IR seconds .
 Decimal fractional values are allowed.
+See the
+.I \-E
+option for the exit code used.
 .TP
 \fB\-o\fP, \fB\-\-close\fP
 Close the file descriptor on which the lock is held before executing
@@ -86,6 +92,11 @@ This is useful if
 .B command
 spawns a child process which should not be holding the lock.
 .TP
+\fB\-E\fP, \fB\-\-conflict\-exit\-code\fP \fInumber\fP
+The exit code used when the \fB\-n\fP option is in use, and the
+conflicting lock exists, or the \fB\-w\fP option is in use,
+and the timeout is reached. The default value is 1.
+.TP
 \fB\-c\fP, \fB\-\-command\fP \fIcommand\fP
 Pass a single
 .IR command ,
@@ -134,7 +145,9 @@ return values for everything else but an options
 .I \-n
 or
 .I \-w
-failures which return 1.
+failures which return either the value given by the
+.I \-E
+option, or 1 by default.
 .SH AUTHOR
 .UR hpa@zytor.com
 H. Peter Anvin
index 1db28a294fcbf80df249e2d7c5e1be2c2e857a78..5a3422a1d2f81a73a46de239a8fd954526dcf844 100644 (file)
@@ -58,6 +58,7 @@ static void __attribute__((__noreturn__)) usage(int ex)
        fputs(_(  " -u  --unlock             remove a lock\n"), stderr);
        fputs(_(  " -n  --nonblock           fail rather than wait\n"), stderr);
        fputs(_(  " -w  --timeout <secs>     wait for a limited amount of time\n"), stderr);
+       fputs(_(  " -E  --conflict-exit-code <number>  exit code after conflict or timeout\n"), stderr);
        fputs(_(  " -o  --close              close file descriptor before running command\n"), stderr);
        fputs(_(  " -c  --command <command>  run a single command string through the shell\n"), stderr);
        fprintf(stderr, USAGE_SEPARATOR);
@@ -141,6 +142,11 @@ int main(int argc, char *argv[])
        int opt, ix;
        int do_close = 0;
        int status;
+       /*
+        * The default exit code for lock conflict or timeout
+        * is specified in man flock.1
+        */
+       int conflict_exit_code = 1;
        char **cmd_argv = NULL, *sh_c_argv[4];
        const char *filename = NULL;
        struct sigaction sa, old_sa;
@@ -153,6 +159,7 @@ int main(int argc, char *argv[])
                {"nb", no_argument, NULL, 'n'},
                {"timeout", required_argument, NULL, 'w'},
                {"wait", required_argument, NULL, 'w'},
+               {"conflict-exit-code", required_argument, NULL, 'E'},
                {"close", no_argument, NULL, 'o'},
                {"help", no_argument, NULL, 'h'},
                {"version", no_argument, NULL, 'V'},
@@ -171,7 +178,7 @@ int main(int argc, char *argv[])
 
        optopt = 0;
        while ((opt =
-               getopt_long(argc, argv, "+sexnouw:hV?", long_options,
+               getopt_long(argc, argv, "+sexnouw:E:hV?", long_options,
                            &ix)) != EOF) {
                switch (opt) {
                case 's':
@@ -194,6 +201,10 @@ int main(int argc, char *argv[])
                        have_timeout = 1;
                        strtotimeval(optarg, &timeout.it_value);
                        break;
+               case 'E':
+                       conflict_exit_code = strtos32_or_err(optarg,
+                               _("invalid exit code"));
+                       break;
                case 'V':
                        printf("flock (%s)\n", PACKAGE_STRING);
                        exit(EX_OK);
@@ -252,18 +263,13 @@ int main(int argc, char *argv[])
        while (flock(fd, type | block)) {
                switch (errno) {
                case EWOULDBLOCK:
-                       /* -n option set and failed to lock. The numeric
-                        * exit value is specified in man flock.1
-                        */
-                       exit(1);
+                       /* -n option set and failed to lock. */
+                       exit(conflict_exit_code);
                case EINTR:
                        /* Signal received */
                        if (timeout_expired)
-                               /* -w option set and failed to lock. The
-                                * numeric exit value is specified in man
-                                * flock.1
-                                */
-                               exit(1);
+                               /* -w option set and failed to lock. */
+                               exit(conflict_exit_code);
                        /* otherwise try again */
                        continue;
                case EIO: