flock.c - sbase - suckless unix tools
 (HTM) git clone git://git.suckless.org/sbase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       flock.c (1358B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <sys/file.h>
            3 #include <sys/wait.h>
            4 
            5 #include <errno.h>
            6 #include <fcntl.h>
            7 #include <stdio.h>
            8 #include <unistd.h>
            9 
           10 #include "util.h"
           11 
           12 static void
           13 usage(void)
           14 {
           15         eprintf("usage: %s [-nosux] file cmd [arg ...]\n", argv0);
           16 }
           17 
           18 int
           19 main(int argc, char *argv[])
           20 {
           21         int fd, status, savederrno, flags = LOCK_EX, nonblk = 0, oflag = 0;
           22         pid_t pid;
           23 
           24         ARGBEGIN {
           25         case 'n':
           26                 nonblk = LOCK_NB;
           27                 break;
           28         case 'o':
           29                 oflag = 1;
           30                 break;
           31         case 's':
           32                 flags = LOCK_SH;
           33                 break;
           34         case 'u':
           35                 flags = LOCK_UN;
           36                 break;
           37         case 'x':
           38                 flags = LOCK_EX;
           39                 break;
           40         default:
           41                 usage();
           42         } ARGEND
           43 
           44         if (argc < 2)
           45                 usage();
           46 
           47         if ((fd = open(*argv, O_RDONLY | O_CREAT, 0644)) < 0)
           48                 eprintf("open %s:", *argv);
           49 
           50         if (flock(fd, flags | nonblk)) {
           51                 if (nonblk && errno == EWOULDBLOCK)
           52                         return 1;
           53                 eprintf("flock:");
           54         }
           55 
           56         switch ((pid = fork())) {
           57         case -1:
           58                 eprintf("fork:");
           59         case 0:
           60                 if (oflag && close(fd) < 0)
           61                         eprintf("close:");
           62                 argv++;
           63                 execvp(*argv, argv);
           64                 savederrno = errno;
           65                 weprintf("execvp %s:", *argv);
           66                 _exit(126 + (savederrno == ENOENT));
           67         default:
           68                 break;
           69         }
           70         if (waitpid(pid, &status, 0) < 0)
           71                 eprintf("waitpid:");
           72 
           73         if (close(fd) < 0)
           74                 eprintf("close:");
           75 
           76         if (WIFSIGNALED(status))
           77                 return 128 + WTERMSIG(status);
           78         if (WIFEXITED(status))
           79                 return WEXITSTATUS(status);
           80 
           81         return 0;
           82 }