1 /* 2 * Copyright 2001, 2002, 2003 Adam Sampson <ats@offog.org> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <unistd.h> 18 #include <fcntl.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <sys/types.h> 22 #include <sys/stat.h> 23 #include <sys/file.h> 24 #include "iolib.h" 25 #include "freedt.h" 26 #include "config.h" 27 const char *progname = "setlock"; 28 const char *proghelp = 29 "Usage: setlock [OPTIONS] lockfile command ...\n" 30 "Run a command with an advisory lock set on a file.\n\n" 31 "-n If the lock is already held, exit immediately\n" 32 "-N If the lock is already held, block (default)\n" 33 "-x On error, exit silently with rc 0\n" 34 "-X On error, exit noisily with rc 111 (default)\n"; 35 36 int error = 1; 37 38 void fail(const char *msg1, const char *msg2) { 39 if (error) 40 die2(msg1, msg2); recordio(const char * data,size_t length,const char * prefix)41 else 42 exit(0); 43 } 44 45 int main(int argc, char **argv) { 46 int fd, block = 1; 47 48 while (1) { 49 int c = getopt(argc, argv, "+V?nNxX"); 50 if (c == -1) 51 break; 52 switch (c) { 53 case 'n': 54 block = 0; 55 break; 56 case 'N': 57 block = 1; 58 break; 59 case 'x': 60 error = 0; 61 break; 62 case 'X': 63 error = 1; 64 break; 65 case 'V': 66 version(); main(int argc,char ** argv)67 default: 68 help(); 69 } 70 } 71 72 if ((argc - optind) < 2) 73 help(); 74 75 fd = open(argv[optind], O_WRONLY | O_CREAT, 0600); 76 if (fd < 0) 77 fail(argv[optind], "unable to open"); 78 if (fcntl(fd, F_SETFD, 0) < 0) 79 fail(argv[optind], "unable to set fd non-close-on-exec"); 80 if (lock_fd(fd, block) < 0) 81 fail(argv[optind], "unable to lock"); 82 83 execvp(argv[optind + 1], &argv[optind + 1]); 84 die2(argv[optind + 1], "unable to exec"); 85 86 return 0; /* NOTREACHED */ 87 } 88 89