#include "monotonic.h"
#include "timer.h"
-static void __attribute__((__noreturn__)) usage(int ex)
+static void __attribute__((__noreturn__)) usage(void)
{
- fprintf(stderr, USAGE_HEADER);
- fprintf(stderr,
+ fputs(USAGE_HEADER, stdout);
+ printf(
_(" %1$s [options] <file>|<directory> <command> [<argument>...]\n"
" %1$s [options] <file>|<directory> -c <command>\n"
" %1$s [options] <file descriptor number>\n"),
program_invocation_short_name);
- fputs(USAGE_SEPARATOR, stderr);
- fputs(_("Manage file locks from shell scripts.\n"), stderr);
-
- fputs(USAGE_OPTIONS, stderr);
- fputs(_( " -s, --shared get a shared lock\n"), stderr);
- fputs(_( " -x, --exclusive get an exclusive lock (default)\n"), stderr);
- 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);
- fputs(_( " -F, --no-fork execute command without forking\n"), stderr);
- fputs(_( " --verbose increase verbosity\n"), stderr);
- fprintf(stderr, USAGE_SEPARATOR);
- fprintf(stderr, USAGE_HELP);
- fprintf(stderr, USAGE_VERSION);
- fprintf(stderr, USAGE_MAN_TAIL("flock(1)"));
- exit(ex);
+ fputs(USAGE_SEPARATOR, stdout);
+ fputs(_("Manage file locks from shell scripts.\n"), stdout);
+
+ fputs(USAGE_OPTIONS, stdout);
+ fputs(_( " -s, --shared get a shared lock\n"), stdout);
+ fputs(_( " -x, --exclusive get an exclusive lock (default)\n"), stdout);
+ fputs(_( " -u, --unlock remove a lock\n"), stdout);
+ fputs(_( " -n, --nonblock fail rather than wait\n"), stdout);
+ fputs(_( " -w, --timeout <secs> wait for a limited amount of time\n"), stdout);
+ fputs(_( " -E, --conflict-exit-code <number> exit code after conflict or timeout\n"), stdout);
+ fputs(_( " -o, --close close file descriptor before running command\n"), stdout);
+ fputs(_( " -c, --command <command> run a single command string through the shell\n"), stdout);
+ fputs(_( " -F, --no-fork execute command without forking\n"), stdout);
+ fputs(_( " --verbose increase verbosity\n"), stdout);
+ fputs(USAGE_SEPARATOR, stdout);
+ printf(USAGE_HELP_OPTIONS(26));
+ printf(USAGE_MAN_TAIL("flock(1)"));
+ exit(EXIT_SUCCESS);
}
static sig_atomic_t timeout_expired = 0;
return fd;
}
+static void __attribute__((__noreturn__)) run_program(char **cmd_argv)
+{
+ execvp(cmd_argv[0], cmd_argv);
+
+ warn(_("failed to execute %s"), cmd_argv[0]);
+ _exit((errno == ENOMEM) ? EX_OSERR : EX_UNAVAILABLE);
+}
+
int main(int argc, char *argv[])
{
static timer_t t_id;
textdomain(PACKAGE);
atexit(close_stdout);
- if (argc < 2)
- usage(EX_USAGE);
+ strutils_set_exitcode(EX_USAGE);
+
+ if (argc < 2) {
+ warnx(_("not enough arguments"));
+ errtryhelp(EX_USAGE);
+ }
memset(&timeout, 0, sizeof timeout);
case 'V':
printf(UTIL_LINUX_VERSION);
exit(EX_OK);
+ case 'h':
+ usage();
default:
- /* optopt will be set if this was an unrecognized
- * option, i.e. *not* 'h' or '?
- */
- usage(optopt ? EX_USAGE : 0);
- break;
+ errtryhelp(EX_USAGE);
}
}
cmd_argv[0] = _PATH_BSHELL;
cmd_argv[1] = "-c";
cmd_argv[2] = argv[optind + 2];
- cmd_argv[3] = 0;
+ cmd_argv[3] = NULL;
} else {
cmd_argv = &argv[optind + 1];
}
if (open_flags & O_RDWR)
break;
}
- /* go through */
+ /* fallthrough */
default:
/* Other errors */
if (filename)
if (!no_fork) {
f = fork();
- if (f < 0) {
+ if (f < 0)
err(EX_OSERR, _("fork failed"));
- if (f != 0) {
- do {
- w = waitpid(f, &status, 0);
- if (w == -1 && errno != EINTR)
+
+ /* child */
+ else if (f == 0) {
+ if (do_close)
+ close(fd);
+ run_program(cmd_argv);
+
+ /* parent */
+ } else {
+ do {
+ w = waitpid(f, &status, 0);
+ if (w == -1 && errno != EINTR)
break;
- } while (w != f);
+ } while (w != f);
- if (w == -1) {
+ if (w == -1) {
status = EXIT_FAILURE;
warn(_("waitpid failed"));
} else if (WIFEXITED(status))
else
/* WTF? */
status = EX_OSERR;
- }
- goto out;
}
- }
- if (do_close)
- close(fd);
- execvp(cmd_argv[0], cmd_argv);
- /* execvp() failed */
- warn(_("failed to execute %s"), cmd_argv[0]);
- _exit((errno == ENOMEM) ? EX_OSERR : EX_UNAVAILABLE);
+
+ } else
+ /* no-fork execution */
+ run_program(cmd_argv);
}
-out:
return status;
}