flock: add --verbose option
Jenkins script jobs using flock are a great example of a situation in which one may want an automation to be verbose, so that when unexpected events happen there is more hints in logs. Reviewed-by: Benno Schulenberg <bensberg@justemail.net> Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
a3d29ee0c7
commit
59dc9f28b5
|
@ -1,8 +1,8 @@
|
||||||
if BUILD_FLOCK
|
if BUILD_FLOCK
|
||||||
usrbin_exec_PROGRAMS += flock
|
usrbin_exec_PROGRAMS += flock
|
||||||
dist_man_MANS += sys-utils/flock.1
|
dist_man_MANS += sys-utils/flock.1
|
||||||
flock_SOURCES = sys-utils/flock.c
|
flock_SOURCES = sys-utils/flock.c lib/monotonic.c
|
||||||
flock_LDADD = $(LDADD) libcommon.la
|
flock_LDADD = $(LDADD) libcommon.la $(CLOCKGETTIME_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_IPCMK
|
if BUILD_IPCMK
|
||||||
|
|
|
@ -107,6 +107,10 @@ option for the exit code used. The zero number of
|
||||||
.IR seconds
|
.IR seconds
|
||||||
is interpreted as \fB\-\-nonblock\fR.
|
is interpreted as \fB\-\-nonblock\fR.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-\-verbose
|
||||||
|
Report how long it took to acquire the lock, or why the lock could not be
|
||||||
|
obtained.
|
||||||
|
.TP
|
||||||
.BR \-V , " \-\-version"
|
.BR \-V , " \-\-version"
|
||||||
Display version information and exit.
|
Display version information and exit.
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "strutils.h"
|
#include "strutils.h"
|
||||||
#include "closestream.h"
|
#include "closestream.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
#include "monotonic.h"
|
||||||
|
|
||||||
static void __attribute__((__noreturn__)) usage(int ex)
|
static void __attribute__((__noreturn__)) usage(int ex)
|
||||||
{
|
{
|
||||||
|
@ -66,6 +67,7 @@ static void __attribute__((__noreturn__)) usage(int ex)
|
||||||
fputs(_( " -E, --conflict-exit-code <number> exit code after conflict or timeout\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(_( " -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(_( " -c, --command <command> run a single command string through the shell\n"), stderr);
|
||||||
|
fputs(_( " --verbose increase verbosity\n"), stderr);
|
||||||
fprintf(stderr, USAGE_SEPARATOR);
|
fprintf(stderr, USAGE_SEPARATOR);
|
||||||
fprintf(stderr, USAGE_HELP);
|
fprintf(stderr, USAGE_HELP);
|
||||||
fprintf(stderr, USAGE_VERSION);
|
fprintf(stderr, USAGE_VERSION);
|
||||||
|
@ -120,6 +122,8 @@ int main(int argc, char *argv[])
|
||||||
int opt, ix;
|
int opt, ix;
|
||||||
int do_close = 0;
|
int do_close = 0;
|
||||||
int status;
|
int status;
|
||||||
|
int verbose = 0;
|
||||||
|
struct timeval time_start, time_done;
|
||||||
/*
|
/*
|
||||||
* The default exit code for lock conflict or timeout
|
* The default exit code for lock conflict or timeout
|
||||||
* is specified in man flock.1
|
* is specified in man flock.1
|
||||||
|
@ -128,7 +132,9 @@ int main(int argc, char *argv[])
|
||||||
char **cmd_argv = NULL, *sh_c_argv[4];
|
char **cmd_argv = NULL, *sh_c_argv[4];
|
||||||
const char *filename = NULL;
|
const char *filename = NULL;
|
||||||
struct sigaction old_sa;
|
struct sigaction old_sa;
|
||||||
|
enum {
|
||||||
|
OPT_VERBOSE = CHAR_MAX + 1
|
||||||
|
};
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{"shared", no_argument, NULL, 's'},
|
{"shared", no_argument, NULL, 's'},
|
||||||
{"exclusive", no_argument, NULL, 'x'},
|
{"exclusive", no_argument, NULL, 'x'},
|
||||||
|
@ -139,6 +145,7 @@ int main(int argc, char *argv[])
|
||||||
{"wait", required_argument, NULL, 'w'},
|
{"wait", required_argument, NULL, 'w'},
|
||||||
{"conflict-exit-code", required_argument, NULL, 'E'},
|
{"conflict-exit-code", required_argument, NULL, 'E'},
|
||||||
{"close", no_argument, NULL, 'o'},
|
{"close", no_argument, NULL, 'o'},
|
||||||
|
{"verbose", no_argument, NULL, OPT_VERBOSE},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"version", no_argument, NULL, 'V'},
|
{"version", no_argument, NULL, 'V'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
|
@ -184,6 +191,9 @@ int main(int argc, char *argv[])
|
||||||
conflict_exit_code = strtos32_or_err(optarg,
|
conflict_exit_code = strtos32_or_err(optarg,
|
||||||
_("invalid exit code"));
|
_("invalid exit code"));
|
||||||
break;
|
break;
|
||||||
|
case OPT_VERBOSE:
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
printf(UTIL_LINUX_VERSION);
|
printf(UTIL_LINUX_VERSION);
|
||||||
exit(EX_OK);
|
exit(EX_OK);
|
||||||
|
@ -239,16 +249,23 @@ int main(int argc, char *argv[])
|
||||||
setup_timer(&timeout, &old_timer, &old_sa, timeout_handler);
|
setup_timer(&timeout, &old_timer, &old_sa, timeout_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
gettime_monotonic(&time_start);
|
||||||
while (flock(fd, type | block)) {
|
while (flock(fd, type | block)) {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case EWOULDBLOCK:
|
case EWOULDBLOCK:
|
||||||
/* -n option set and failed to lock. */
|
/* -n option set and failed to lock. */
|
||||||
|
if (verbose)
|
||||||
|
warnx(_("failed to get lock"));
|
||||||
exit(conflict_exit_code);
|
exit(conflict_exit_code);
|
||||||
case EINTR:
|
case EINTR:
|
||||||
/* Signal received */
|
/* Signal received */
|
||||||
if (timeout_expired)
|
if (timeout_expired) {
|
||||||
/* -w option set and failed to lock. */
|
/* -w option set and failed to lock. */
|
||||||
|
if (verbose)
|
||||||
|
warnx(_("timeout while waiting to get lock"));
|
||||||
exit(conflict_exit_code);
|
exit(conflict_exit_code);
|
||||||
|
}
|
||||||
/* otherwise try again */
|
/* otherwise try again */
|
||||||
continue;
|
continue;
|
||||||
case EIO:
|
case EIO:
|
||||||
|
@ -282,13 +299,23 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (have_timeout)
|
if (have_timeout)
|
||||||
cancel_timer(&old_timer, &old_sa);
|
cancel_timer(&old_timer, &old_sa);
|
||||||
|
if (verbose) {
|
||||||
|
struct timeval delta;
|
||||||
|
|
||||||
|
gettime_monotonic(&time_done);
|
||||||
|
timersub(&time_done, &time_start, &delta);
|
||||||
|
printf(_("%s: getting lock took %ld.%06ld seconds\n"),
|
||||||
|
program_invocation_short_name, delta.tv_sec,
|
||||||
|
delta.tv_usec);
|
||||||
|
}
|
||||||
status = EX_OK;
|
status = EX_OK;
|
||||||
|
|
||||||
if (cmd_argv) {
|
if (cmd_argv) {
|
||||||
pid_t w, f;
|
pid_t w, f;
|
||||||
/* Clear any inherited settings */
|
/* Clear any inherited settings */
|
||||||
signal(SIGCHLD, SIG_DFL);
|
signal(SIGCHLD, SIG_DFL);
|
||||||
|
if (verbose)
|
||||||
|
printf(_("%s: executing %s\n"), program_invocation_short_name, cmd_argv[2]);
|
||||||
f = fork();
|
f = fork();
|
||||||
|
|
||||||
if (f < 0) {
|
if (f < 0) {
|
||||||
|
|
Loading…
Reference in New Issue