fdisk: sanitize partition name printing; drop "Code" column; get rid of one static var
[oweals/busybox.git] / util-linux / flock.c
index 78b1e4ba3dde3313ede038b4cfd6e02a875b673c..f34c0ad8f0458a89d3f24b326b49e9e3c71cae98 100644 (file)
@@ -3,6 +3,25 @@
  *
  * This is free software, licensed under the GNU General Public License v2.
  */
+//config:config FLOCK
+//config:      bool "flock"
+//config:      default y
+//config:      help
+//config:        Manage locks from shell scripts
+
+//applet:IF_FLOCK(APPLET(flock, BB_DIR_USR_BIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_FLOCK) += flock.o
+
+//usage:#define flock_trivial_usage
+//usage:       "[-sxun] FD|{FILE [-c] PROG ARGS}"
+//usage:#define flock_full_usage "\n\n"
+//usage:       "[Un]lock file descriptor, or lock FILE, run PROG\n"
+//usage:     "\n       -s      Shared lock"
+//usage:     "\n       -x      Exclusive lock (default)"
+//usage:     "\n       -u      Unlock FD"
+//usage:     "\n       -n      Fail rather than wait"
+
 #include <sys/file.h>
 #include "libbb.h"
 
@@ -19,7 +38,7 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
        };
 
 #if ENABLE_LONG_OPTS
-        static const char getopt_longopts[] ALIGN1 =
+       static const char getopt_longopts[] ALIGN1 =
                "shared\0"      No_argument       "s"
                "exclusive\0"   No_argument       "x"
                "unlock\0"      No_argument       "u"
@@ -35,19 +54,18 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
        if (argv[1]) {
                fd = open(argv[0], O_RDONLY|O_NOCTTY|O_CREAT, 0666);
                if (fd < 0 && errno == EISDIR)
-                       fd = open(argv[0], O_RDONLY|O_NOCTTY);
+                       fd = open(argv[0], O_RDONLY|O_NOCTTY);
                if (fd < 0)
                        bb_perror_msg_and_die("can't open '%s'", argv[0]);
                //TODO? close_on_exec_on(fd);
        } else {
-               fd = xatoi_u(argv[0]);
+               fd = xatoi_positive(argv[0]);
        }
        argv++;
 
        /* If it is "flock FILE -c PROG", then -c isn't caught by getopt32:
         * we use "+" in order to support "flock -opt FILE PROG -with-opts",
         * we need to remove -c by hand.
-        * TODO: in upstream, -c 'PROG ARGS' means "run sh -c 'PROG ARGS'"
         */
        if (argv[0]
         && argv[0][0] == '-'
@@ -56,6 +74,9 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
            )
        ) {
                argv++;
+               if (argv[1])
+                       bb_error_msg_and_die("-c takes only one argument");
+               opt |= OPT_c;
        }
 
        if (OPT_s == LOCK_SH && OPT_x == LOCK_EX && OPT_n == LOCK_NB && OPT_u == LOCK_UN) {
@@ -80,8 +101,21 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
                bb_perror_nomsg_and_die();
        }
 
-       if (argv[0])
-               return spawn_and_wait(argv);
+       if (argv[0]) {
+               int rc;
+               if (opt & OPT_c) {
+                       /* -c 'PROG ARGS' means "run sh -c 'PROG ARGS'" */
+                       argv -= 2;
+                       argv[0] = (char*)get_shell_name();
+                       argv[1] = (char*)"-c";
+                       /* argv[2] = "PROG ARGS"; */
+                       /* argv[3] = NULL; */
+               }
+               rc = spawn_and_wait(argv);
+               if (rc < 0)
+                       bb_simple_perror_msg(argv[0]);
+               return rc;
+       }
 
        return EXIT_SUCCESS;
 }