Rob Landley | 87aef24 | 2013-07-14 22:12:22 -0500 | [diff] [blame] | 1 | /* pending.c - reusable stuff awaiting review |
| 2 | * |
| 3 | * new lib entries for stuff in toys/pending |
| 4 | */ |
| 5 | |
| 6 | #include "toys.h" |
| 7 | |
| 8 | // Execute a callback for each PID that matches a process name from a list. |
| 9 | void for_each_pid_with_name_in(char **names, int (*callback)(pid_t pid, char *name)) |
| 10 | { |
| 11 | DIR *dp; |
| 12 | struct dirent *entry; |
| 13 | char cmd[sizeof(toybuf)], path[64]; |
| 14 | char **curname; |
| 15 | |
| 16 | if (!(dp = opendir("/proc"))) perror_exit("opendir"); |
| 17 | |
| 18 | while ((entry = readdir(dp))) { |
| 19 | int fd, n; |
| 20 | |
| 21 | if (!isdigit(*entry->d_name)) continue; |
| 22 | |
| 23 | if (sizeof(path) <= snprintf(path, sizeof(path), "/proc/%s/cmdline", |
| 24 | entry->d_name)) continue; |
| 25 | |
| 26 | if (-1 == (fd=open(path, O_RDONLY))) continue; |
| 27 | n = read(fd, cmd, sizeof(cmd)); |
| 28 | close(fd); |
| 29 | if (n<1) continue; |
| 30 | |
| 31 | for (curname = names; *curname; curname++) |
| 32 | if (!strcmp(basename(cmd), *curname)) |
| 33 | if (!callback(atol(entry->d_name), *curname)) goto done; |
| 34 | } |
| 35 | done: |
| 36 | closedir(dp); |
| 37 | } |
| 38 | |
| 39 | char* make_human_readable(unsigned long long size, unsigned long unit) |
| 40 | { |
| 41 | unsigned int frac = 0; |
| 42 | if(unit) { |
| 43 | size = (size/(unit)) + (size%(unit)?1:0); |
| 44 | return xmsprintf("%llu", size); |
| 45 | } |
| 46 | else { |
| 47 | static char units[] = {'\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'}; |
| 48 | int index = 0; |
| 49 | while(size >= 1024) { |
| 50 | frac = size%1024; |
| 51 | size /= 1024; |
| 52 | index++; |
| 53 | } |
| 54 | frac = (frac/102) + ((frac%102)?1:0); |
| 55 | if(frac >= 10) { |
| 56 | size += 1; |
| 57 | frac = 0; |
| 58 | } |
| 59 | if(frac) return xmsprintf("%llu.%u%c", size, frac, units[index]); |
| 60 | else return xmsprintf("%llu%c", size, units[index]); |
| 61 | } |
| 62 | return NULL; //not reached |
| 63 | } |
| 64 | |
| 65 | /* |
| 66 | * used to get the interger value. |
| 67 | */ |
| 68 | unsigned long get_int_value(const char *numstr, unsigned lowrange, unsigned highrange) |
| 69 | { |
| 70 | unsigned long rvalue = 0; |
| 71 | char *ptr; |
| 72 | if(*numstr == '-' || *numstr == '+' || isspace(*numstr)) perror_exit("invalid number '%s'", numstr); |
| 73 | errno = 0; |
| 74 | rvalue = strtoul(numstr, &ptr, 10); |
| 75 | if(errno || numstr == ptr) perror_exit("invalid number '%s'", numstr); |
| 76 | if(*ptr) perror_exit("invalid number '%s'", numstr); |
| 77 | if(rvalue >= lowrange && rvalue <= highrange) return rvalue; |
| 78 | else { |
| 79 | perror_exit("invalid number '%s'", numstr); |
| 80 | return rvalue; //Not reachable; to avoid waring message. |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | /* |
| 85 | * strcat to mallocated buffer |
| 86 | * reallocate if need be |
| 87 | */ |
| 88 | char *astrcat (char *x, char *y) { |
| 89 | char *z; |
| 90 | z = x; |
| 91 | x = realloc (x, (x ? strlen (x) : 0) + strlen (y) + 1); |
| 92 | if (!x) return 0; |
| 93 | (z ? strcat : strcpy) (x, y); |
| 94 | return x; |
| 95 | } |
| 96 | |
| 97 | /* |
| 98 | * astrcat, but die on failure |
| 99 | */ |
| 100 | char *xastrcat (char *x, char *y) { |
| 101 | x = astrcat (x, y); |
| 102 | if (!x) error_exit ("xastrcat"); |
| 103 | return x; |
| 104 | } |
Felix Janda | e49fe14 | 2013-08-10 20:18:18 +0200 | [diff] [blame^] | 105 | |
| 106 | void daemonize(void) |
| 107 | { |
| 108 | int fd = open("/dev/null", O_RDWR); |
| 109 | if (fd < 0) fd = xcreate("/", O_RDONLY, 0666); |
| 110 | |
| 111 | pid_t pid = fork(); |
| 112 | if (pid < 0) perror_exit("DAEMON: failed to fork"); |
| 113 | if (pid) exit(EXIT_SUCCESS); |
| 114 | |
| 115 | setsid(); |
| 116 | dup2(fd, 0); |
| 117 | dup2(fd, 1); |
| 118 | dup2(fd, 2); |
| 119 | if (fd > 2) close(fd); |
| 120 | } |