dotfiles

personal configuration files and scripts
git clone https://tongong.net/git/dotfiles.git
Log | Files | Refs | README

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 }