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 }