340-lock_util.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. --- a/include/applets.h
  2. +++ b/include/applets.h
  3. @@ -220,6 +220,7 @@
  4. USE_LOAD_POLICY(APPLET(load_policy, _BB_DIR_USR_SBIN, _BB_SUID_NEVER))
  5. USE_LOADFONT(APPLET(loadfont, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
  6. USE_LOADKMAP(APPLET(loadkmap, _BB_DIR_SBIN, _BB_SUID_NEVER))
  7. +USE_LOCK(APPLET(lock, _BB_DIR_BIN, _BB_SUID_NEVER))
  8. USE_LOGGER(APPLET(logger, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
  9. USE_LOGIN(APPLET(login, _BB_DIR_BIN, _BB_SUID_ALWAYS))
  10. USE_LOGNAME(APPLET_NOFORK(logname, logname, _BB_DIR_USR_BIN, _BB_SUID_NEVER, logname))
  11. --- a/include/usage.h
  12. +++ b/include/usage.h
  13. @@ -2138,6 +2138,9 @@
  14. #define loadkmap_example_usage \
  15. "$ loadkmap < /etc/i18n/lang-keymap\n"
  16. +#define lock_trivial_usage NOUSAGE_STR
  17. +#define lock_full_usage ""
  18. +
  19. #define logger_trivial_usage \
  20. "[OPTION]... [MESSAGE]"
  21. #define logger_full_usage "\n\n" \
  22. --- a/miscutils/Config.in
  23. +++ b/miscutils/Config.in
  24. @@ -364,6 +364,12 @@
  25. Enables the 'hdparm -d' option to get/set using_dma flag.
  26. This is dangerous stuff, so you should probably say N.
  27. +config LOCK
  28. + bool "lock"
  29. + default y
  30. + help
  31. + Small utility for using locks in scripts
  32. +
  33. config MAKEDEVS
  34. bool "makedevs"
  35. default n
  36. --- a/miscutils/Kbuild
  37. +++ b/miscutils/Kbuild
  38. @@ -20,6 +20,7 @@
  39. lib-$(CONFIG_FEATURE_LAST_SMALL)+= last.o
  40. lib-$(CONFIG_FEATURE_LAST_FANCY)+= last_fancy.o
  41. lib-$(CONFIG_LESS) += less.o
  42. +lib-$(CONFIG_LOCK) += lock.o
  43. lib-$(CONFIG_MAKEDEVS) += makedevs.o
  44. lib-$(CONFIG_MAN) += man.o
  45. lib-$(CONFIG_MICROCOM) += microcom.o
  46. --- /dev/null
  47. +++ b/miscutils/lock.c
  48. @@ -0,0 +1,132 @@
  49. +/*
  50. + * Copyright (C) 2006 Felix Fietkau <[email protected]>
  51. + *
  52. + * This is free software, licensed under the GNU General Public License v2.
  53. + */
  54. +#include <sys/types.h>
  55. +#include <sys/file.h>
  56. +#include <sys/stat.h>
  57. +#include <signal.h>
  58. +#include <fcntl.h>
  59. +#include <unistd.h>
  60. +#include <stdio.h>
  61. +#include "busybox.h"
  62. +
  63. +static int unlock = 0;
  64. +static int shared = 0;
  65. +static int waitonly = 0;
  66. +static int fd;
  67. +static char *file;
  68. +
  69. +static void usage(char *name)
  70. +{
  71. + fprintf(stderr, "Usage: %s [-suw] <filename>\n"
  72. + " -s Use shared locking\n"
  73. + " -u Unlock\n"
  74. + " -w Wait for the lock to become free, don't acquire lock\n"
  75. + "\n", name);
  76. + exit(1);
  77. +}
  78. +
  79. +static void exit_unlock(int sig)
  80. +{
  81. + flock(fd, LOCK_UN);
  82. + exit(0);
  83. +}
  84. +
  85. +static int do_unlock(void)
  86. +{
  87. + FILE *f;
  88. + int i;
  89. +
  90. + if ((f = fopen(file, "r")) == NULL)
  91. + return 0;
  92. +
  93. + fscanf(f, "%d", &i);
  94. + if (i > 0)
  95. + kill(i, SIGTERM);
  96. +
  97. + fclose(f);
  98. +
  99. + return 0;
  100. +}
  101. +
  102. +static int do_lock(void)
  103. +{
  104. + int pid;
  105. + char pidstr[8];
  106. +
  107. + if ((fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0700)) < 0) {
  108. + if ((fd = open(file, O_RDWR)) < 0) {
  109. + fprintf(stderr, "Can't open %s\n", file);
  110. + return 1;
  111. + }
  112. + }
  113. +
  114. + if (flock(fd, (shared ? LOCK_SH : LOCK_EX)) < 0) {
  115. + fprintf(stderr, "Can't lock %s\n", file);
  116. + return 1;
  117. + }
  118. +
  119. + pid = fork();
  120. +
  121. + if (pid < 0)
  122. + return -1;
  123. +
  124. + if (pid == 0) {
  125. + signal(SIGKILL, exit_unlock);
  126. + signal(SIGTERM, exit_unlock);
  127. + signal(SIGINT, exit_unlock);
  128. + if (waitonly)
  129. + exit_unlock(0);
  130. + else
  131. + while (1)
  132. + sleep(1);
  133. + } else {
  134. + if (!waitonly) {
  135. + lseek(fd, 0, SEEK_SET);
  136. + ftruncate(fd, 0);
  137. + sprintf(pidstr, "%d\n", pid);
  138. + write(fd, pidstr, strlen(pidstr));
  139. + close(fd);
  140. + }
  141. +
  142. + return 0;
  143. + }
  144. + return 0;
  145. +}
  146. +
  147. +int lock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  148. +int lock_main(int argc, char **argv)
  149. +{
  150. + char **args = &argv[1];
  151. + int c = argc - 1;
  152. +
  153. + while ((*args != NULL) && (*args)[0] == '-') {
  154. + char *ch = *args;
  155. + while (*(++ch) > 0) {
  156. + switch(*ch) {
  157. + case 'w':
  158. + waitonly = 1;
  159. + break;
  160. + case 's':
  161. + shared = 1;
  162. + break;
  163. + case 'u':
  164. + unlock = 1;
  165. + break;
  166. + }
  167. + }
  168. + c--;
  169. + args++;
  170. + }
  171. +
  172. + if (c != 1)
  173. + usage(argv[0]);
  174. +
  175. + file = *args;
  176. + if (unlock)
  177. + return do_unlock();
  178. + else
  179. + return do_lock();
  180. +}