sigdsblocks.c (2793B)
1 #include <errno.h> 2 #include <fcntl.h> 3 #include <limits.h> 4 #include <signal.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <unistd.h> 8 9 #define NILL INT_MIN 10 #define LOCKFILE "/tmp/dsblocks.pid" 11 12 int 13 parsesignal(char *arg) 14 { 15 int i = 0; 16 17 for (; *arg != '\0'; arg++) 18 if (*arg >= '0' && *arg <= '9') 19 i = 10 * i + *arg - '0'; 20 else { 21 fputs("Usage: sigdsblocks <signal> [<sigval>]\n", stderr); 22 exit(2); 23 } 24 if ((i += SIGRTMIN) > SIGRTMAX) { 25 fputs("Error: <signal> out of range.\n", stderr); 26 exit(2); 27 } 28 return i; 29 } 30 31 int 32 parsesigval(char *arg) 33 { 34 int s = 1, i = 0; 35 36 if (*arg == '-') { 37 s = -1; 38 arg++; 39 } else if (*arg == '+') 40 arg++; 41 for (; *arg != '\0'; arg++) 42 if (*arg >= '0' && *arg <= '9') 43 i = 10 * i + *arg - '0'; 44 else { 45 fputs("Usage: sigdsblocks <signal> [<sigval>]\n", stderr); 46 exit(2); 47 } 48 return s * i; 49 } 50 51 void 52 sendsignal(int sig, union sigval sv) 53 { 54 int fd; 55 struct flock fl; 56 57 if ((fd = open(LOCKFILE, O_RDONLY)) == -1) { 58 if (errno == ENOENT) { 59 fputs("Error: no running instance of dsblocks.\n", stderr); 60 exit(3); 61 } 62 perror("sendsignal - open"); 63 exit(1); 64 } 65 fl.l_type = F_WRLCK; 66 fl.l_whence = SEEK_SET; 67 fl.l_start = 0; 68 fl.l_len = 0; 69 if (fcntl(fd, F_GETLK, &fl) == -1) { 70 perror("sendsignal - fcntl"); 71 close(fd); 72 exit(1); 73 } 74 close(fd); 75 if (fl.l_type == F_UNLCK) { 76 fputs("Error: no running instance of dsblocks.\n", stderr); 77 exit(3); 78 } 79 if (sigqueue(fl.l_pid, sig, sv) == -1) { 80 if (errno == ESRCH) { 81 fputs("Error: no running instance of dsblocks.\n", stderr); 82 exit(3); 83 } else { 84 perror("sendsignal - sigqueue"); 85 exit(1); 86 } 87 } 88 } 89 90 int 91 main(int argc, char *argv[]) 92 { 93 int sig; 94 union sigval sv; 95 96 if (argc < 2 || argc > 3) { 97 fputs("Usage: sigdsblocks <signal> [<sigval>]\n", stderr); 98 return 2; 99 } 100 sig = parsesignal(argv[1]); 101 sv.sival_int = argc == 2 ? NILL : parsesigval(argv[2]); 102 sendsignal(sig, sv); 103 return 0; 104 }