X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=1bffd84d1fa71610df46a445f405581241d8d271;hb=5c0d398dfc4d79df2209515d28cafd9dc129838e;hp=2241b79859ff16233f4a33e7f66aea13efb11464;hpb=844ec79b3c2f246114ea316ebe1f36044bdb688e;p=elogind.git diff --git a/src/shared/util.c b/src/shared/util.c index 2241b7985..1bffd84d1 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -207,14 +207,12 @@ int close_nointr(int fd) { } void close_nointr_nofail(int fd) { - int saved_errno = errno; + PROTECT_ERRNO; /* like close_nointr() but cannot fail, and guarantees errno * is unchanged */ assert_se(close_nointr(fd) == 0); - - errno = saved_errno; } void close_many(const int fds[], unsigned n_fd) { @@ -449,14 +447,13 @@ char *split_quoted(const char *c, size_t *l, char **state) { int get_parent_of_pid(pid_t pid, pid_t *_ppid) { int r; _cleanup_fclose_ FILE *f = NULL; - char fn[PATH_MAX], line[LINE_MAX], *p; + char fn[sizeof("/proc/")-1 + DECIMAL_STR_MAX(pid_t) + sizeof("/stat")], line[LINE_MAX], *p; long unsigned ppid; assert(pid > 0); assert(_ppid); assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1)); - char_array_0(fn); f = fopen(fn, "re"); if (!f) @@ -493,13 +490,12 @@ int get_parent_of_pid(pid_t pid, pid_t *_ppid) { int get_starttime_of_pid(pid_t pid, unsigned long long *st) { _cleanup_fclose_ FILE *f = NULL; - char fn[PATH_MAX], line[LINE_MAX], *p; + char fn[sizeof("/proc/")-1 + DECIMAL_STR_MAX(pid_t) + sizeof("/stat")], line[LINE_MAX], *p; assert(pid > 0); assert(st); assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1)); - char_array_0(fn); f = fopen(fn, "re"); if (!f) @@ -1069,6 +1065,32 @@ char *hexmem(const void *p, size_t l) { return r; } +void *unhexmem(const char *p, size_t l) { + uint8_t *r, *z; + const char *x; + + assert(p); + + z = r = malloc((l + 1) / 2 + 1); + if (!r) + return NULL; + + for (x = p; x < p + l; x += 2) { + int a, b; + + a = unhexchar(x[0]); + if (x+1 < p + l) + b = unhexchar(x[1]); + else + b = 0; + + *(z++) = (uint8_t) a << 4 | (uint8_t) b; + } + + *z = 0; + return r; +} + char octchar(int x) { return '0' + (x & 7); } @@ -1847,18 +1869,18 @@ int flush_fd(int fd) { ssize_t l; int r; - if ((r = poll(&pollfd, 1, 0)) < 0) { - + r = poll(&pollfd, 1, 0); + if (r < 0) { if (errno == EINTR) continue; return -errno; - } - if (r == 0) + } else if (r == 0) return 0; - if ((l = read(fd, buf, sizeof(buf))) < 0) { + l = read(fd, buf, sizeof(buf)); + if (l < 0) { if (errno == EINTR) continue; @@ -1867,9 +1889,7 @@ int flush_fd(int fd) { return 0; return -errno; - } - - if (l <= 0) + } else if (l == 0) return 0; } } @@ -2042,10 +2062,12 @@ fail: } int release_terminal(void) { - int r = 0, fd; + int r = 0; struct sigaction sa_old, sa_new; + int _cleanup_close_ fd; - if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0) + fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC); + if (fd < 0) return -errno; /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed @@ -2061,7 +2083,6 @@ int release_terminal(void) { assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0); - close_nointr_nofail(fd); return r; } @@ -2265,7 +2286,7 @@ int parse_bytes(const char *t, off_t *bytes) { errno = 0; l = strtoll(p, &e, 10); - if (errno != 0) + if (errno > 0) return -errno; if (l < 0) @@ -2588,7 +2609,7 @@ int get_ctty_devnr(pid_t pid, dev_t *d) { int get_ctty(pid_t pid, dev_t *_devnr, char **r) { int k; - char fn[PATH_MAX], *s, *b, *p; + char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *s, *b, *p; dev_t devnr; assert(r); @@ -2598,7 +2619,6 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) { return k; snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr)); - char_array_0(fn); k = readlink_malloc(fn, &s); if (k < 0) { @@ -4191,7 +4211,7 @@ int get_user_creds( } if (!p) - return errno != 0 ? -errno : -ESRCH; + return errno > 0 ? -errno : -ESRCH; if (uid) *uid = p->pw_uid; @@ -4272,7 +4292,7 @@ int get_group_creds(const char **groupname, gid_t *gid) { } if (!g) - return errno != 0 ? -errno : -ESRCH; + return errno > 0 ? -errno : -ESRCH; if (gid) *gid = g->gr_gid; @@ -4739,7 +4759,7 @@ static const char *const __signal_table[] = { DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int); const char *signal_to_string(int signo) { - static __thread char buf[12]; + static __thread char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1]; const char *name; name = __signal_to_string(signo); @@ -4747,10 +4767,10 @@ const char *signal_to_string(int signo) { return name; if (signo >= SIGRTMIN && signo <= SIGRTMAX) - snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN); + snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN); else - snprintf(buf, sizeof(buf) - 1, "%d", signo); - char_array_0(buf); + snprintf(buf, sizeof(buf), "%d", signo); + return buf; } @@ -5018,7 +5038,7 @@ int setrlimit_closest(int resource, const struct rlimit *rlim) { } int getenv_for_pid(pid_t pid, const char *field, char **_value) { - char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL; + char path[sizeof("/proc/")-1 + DECIMAL_STR_MAX(pid_t) + sizeof("/environ")], *value = NULL; int r; FILE *f; bool done = false; @@ -5031,7 +5051,6 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value) { pid = getpid(); snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid); - char_array_0(path); f = fopen(path, "re"); if (!f) @@ -5713,12 +5732,12 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *sear int create_tmp_dir(char template[], char** dir_name) { int r = 0; char *d, *dt; - mode_t _cleanup_umask_ u; assert(dir_name); - u = umask(0077); - d = mkdtemp(template); + RUN_WITH_UMASK(0077) { + d = mkdtemp(template); + } if (!d) { log_error("Can't create directory %s: %m", template); return -errno; @@ -5730,9 +5749,10 @@ int create_tmp_dir(char template[], char** dir_name) { goto fail3; } - umask(0000); - r = mkdir(dt, 0777); - if (r) { + RUN_WITH_UMASK(0000) { + r = mkdir(dt, 0777); + } + if (r < 0) { log_error("Can't create directory %s: %m", dt); r = -errno; goto fail2; @@ -5829,3 +5849,20 @@ char *strrep(const char *s, unsigned n) { *p = 0; return r; } + +void* greedy_realloc(void **p, size_t *allocated, size_t need) { + size_t a; + void *q; + + if (*allocated >= need) + return *p; + + a = MAX(64u, need * 2); + q = realloc(*p, a); + if (!q) + return NULL; + + *p = q; + *allocated = a; + return q; +}