5 + * Copyright (C) 2006 Felix Fietkau <nbd@nbd.name>
7 + * This is free software, licensed under the GNU General Public License v2.
11 +//config: bool "lock"
14 +//config: Small utility for using locks in scripts
16 +//applet:IF_LOCK(APPLET(lock, BB_DIR_BIN, BB_SUID_DROP))
18 +//kbuild:lib-$(CONFIG_LOCK) += lock.o
20 +//usage:#define lock_trivial_usage NOUSAGE_STR
21 +//usage:#define lock_full_usage ""
23 +#include <sys/types.h>
24 +#include <sys/file.h>
25 +#include <sys/stat.h>
32 +static int unlock = 0;
33 +static int shared = 0;
34 +static int waitonly = 0;
35 +static int try_lock = 0;
39 +static void usage(char *name)
41 + fprintf(stderr, "Usage: %s [-suw] <filename>\n"
42 + " -s Use shared locking\n"
44 + " -w Wait for the lock to become free, don't acquire lock\n"
45 + " -n Don't wait for the lock to become free. Fail with exit code\n"
50 +static void exit_unlock(int sig)
56 +static int do_unlock(void)
61 + if ((f = fopen(file, "r")) == NULL)
64 + fscanf(f, "%d", &i);
73 +static int do_lock(void)
79 + if ((fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0700)) < 0) {
80 + if ((fd = open(file, O_RDWR)) < 0) {
81 + fprintf(stderr, "Can't open %s\n", file);
86 + flags = shared ? LOCK_SH : LOCK_EX;
87 + flags |= try_lock ? LOCK_NB : 0;
89 + if (flock(fd, flags) < 0) {
90 + fprintf(stderr, "Can't lock %s\n", file);
100 + signal(SIGKILL, exit_unlock);
101 + signal(SIGTERM, exit_unlock);
102 + signal(SIGINT, exit_unlock);
110 + lseek(fd, 0, SEEK_SET);
112 + sprintf(pidstr, "%d\n", pid);
113 + write(fd, pidstr, strlen(pidstr));
122 +int lock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
123 +int lock_main(int argc, char **argv)
125 + char **args = &argv[1];
128 + while ((*args != NULL) && (*args)[0] == '-') {
130 + while (*(++ch) > 0) {
155 + return do_unlock();