static volatile unsigned cached_columns = 0;
static volatile unsigned cached_lines = 0;
-#define PROCFS_PATH_LEN (sizeof("/proc/")-1 + DECIMAL_STR_MAX(pid_t))
-
-#define FORMAT_PROCFS_PATH(buffer, path, pid) \
- do { \
- assert_cc(sizeof(buffer) == (PROCFS_PATH_LEN + 1 + sizeof(path))); \
- snprintf(buffer, sizeof(buffer) - 1, "/proc/%lu/%s", (unsigned long) pid, path); \
- char_array_0(buffer); \
- } while(0)
-
-
size_t page_size(void) {
static __thread size_t pgsz = 0;
long r;
assert(s);
assert(ret_d);
- errno = 0;
- d = strtod(s, &x);
+ RUN_WITH_LOCALE(LC_NUMERIC_MASK, "C") {
+ errno = 0;
+ d = strtod(s, &x);
+ }
if (!x || x == s || *x || errno)
return errno ? -errno : -EINVAL;
int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
int r;
_cleanup_fclose_ FILE *f = NULL;
- char fn[sizeof("/proc/")-1 + DECIMAL_STR_MAX(pid_t) + sizeof("/stat")], line[LINE_MAX], *p;
+ char line[LINE_MAX];
long unsigned ppid;
+ const char *p;
- assert(pid > 0);
+ assert(pid >= 0);
assert(_ppid);
- assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
+ if (pid == 0) {
+ *_ppid = getppid();
+ return 0;
+ }
- f = fopen(fn, "re");
+ p = procfs_file_alloca(pid, "stat");
+ f = fopen(p, "re");
if (!f)
return -errno;
int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
_cleanup_fclose_ FILE *f = NULL;
- char fn[sizeof("/proc/")-1 + DECIMAL_STR_MAX(pid_t) + sizeof("/stat")], line[LINE_MAX], *p;
+ char line[LINE_MAX];
+ const char *p;
- assert(pid > 0);
+ assert(pid >= 0);
assert(st);
- assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
+ if (pid == 0)
+ p = "/proc/self/stat";
+ else
+ p = procfs_file_alloca(pid, "stat");
- f = fopen(fn, "re");
+ f = fopen(p, "re");
if (!f)
return -errno;
}
int get_process_comm(pid_t pid, char **name) {
- int r;
+ const char *p;
assert(name);
+ assert(pid >= 0);
if (pid == 0)
- r = read_one_line_file("/proc/self/comm", name);
- else {
- char path[PROCFS_PATH_LEN + sizeof("/comm")];
- FORMAT_PROCFS_PATH(path, "comm", pid);
- r = read_one_line_file(path, name);
- }
+ p = "/proc/self/comm";
+ else
+ p = procfs_file_alloca(pid, "comm");
- return r;
+ return read_one_line_file(p, name);
}
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
+ _cleanup_fclose_ FILE *f = NULL;
char *r = NULL, *k;
+ const char *p;
int c;
- FILE *f;
assert(line);
+ assert(pid >= 0);
if (pid == 0)
- f = fopen("/proc/self/cmdline", "re");
- else {
- char path[PROCFS_PATH_LEN + sizeof("/cmdline")];
- FORMAT_PROCFS_PATH(path, "cmdline", pid);
- f = fopen(path, "re");
- }
+ p = "/proc/self/cmdline";
+ else
+ p = procfs_file_alloca(pid, "cmdline");
+ f = fopen(p, "re");
if (!f)
return -errno;
+
if (max_length == 0) {
- size_t len = 1;
+ size_t len = 0, allocated = 0;
+
while ((c = getc(f)) != EOF) {
- k = realloc(r, len+1);
- if (k == NULL) {
+
+ if (!GREEDY_REALLOC(r, allocated, len+2)) {
free(r);
- fclose(f);
return -ENOMEM;
}
- r = k;
- r[len-1] = isprint(c) ? c : ' ';
- r[len] = 0;
- len++;
+
+ r[len++] = isprint(c) ? c : ' ';
}
+
+ if (len > 0)
+ r[len-1] = 0;
+
} else {
bool space = false;
size_t left;
+
r = new(char, max_length);
- if (!r) {
- fclose(f);
+ if (!r)
return -ENOMEM;
- }
k = r;
left = max_length;
*k = 0;
}
- fclose(f);
-
/* Kernel threads have no argv[] */
if (r == NULL || r[0] == 0) {
char *t;
}
int is_kernel_thread(pid_t pid) {
- char path[PROCFS_PATH_LEN + sizeof("/cmdline")];
+ const char *p;
size_t count;
char c;
bool eof;
if (pid == 0)
return 0;
- FORMAT_PROCFS_PATH(path, "cmdline", pid);
- f = fopen(path, "re");
+ assert(pid > 0);
+ p = procfs_file_alloca(pid, "cmdline");
+ f = fopen(p, "re");
if (!f)
return -errno;
return 0;
}
+
int get_process_exe(pid_t pid, char **name) {
- int r;
+ const char *p;
+ assert(pid >= 0);
assert(name);
if (pid == 0)
- r = readlink_malloc("/proc/self/exe", name);
- else {
- char path[PROCFS_PATH_LEN + sizeof("/exe")];
- FORMAT_PROCFS_PATH(path, "exe", pid);
- r = readlink_malloc(path, name);
- }
+ p = "/proc/self/exe";
+ else
+ p = procfs_file_alloca(pid, "exe");
- return r;
+ return readlink_malloc(p, name);
}
static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
_cleanup_fclose_ FILE *f = NULL;
- char path[PROCFS_PATH_LEN + sizeof("/status")];
char line[LINE_MAX];
+ const char *p;
assert(field);
assert(uid);
if (pid == 0)
return getuid();
- FORMAT_PROCFS_PATH(path, "status", pid);
- f = fopen(path, "re");
+ p = procfs_file_alloca(pid, "status");
+ f = fopen(p, "re");
if (!f)
return -errno;
}
int get_process_gid(pid_t pid, gid_t *gid) {
+ assert_cc(sizeof(uid_t) == sizeof(gid_t));
return get_process_id(pid, "Gid:", gid);
}
return t;
}
-static bool ignore_file_allow_backup(const char *filename) {
+_pure_ static bool ignore_file_allow_backup(const char *filename) {
assert(filename);
return
return 0;
}
-static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
+_pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
unsigned i;
assert(n_fdset == 0 || fdset);
.sa_handler = SIG_IGN,
.sa_flags = SA_RESTART,
};
- int _cleanup_close_ fd;
+ _cleanup_close_ int fd;
fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC);
if (fd < 0)
}
int get_ctty_devnr(pid_t pid, dev_t *d) {
- int k;
- char line[LINE_MAX], *p, *fn;
+ _cleanup_fclose_ FILE *f = NULL;
+ char line[LINE_MAX], *p;
unsigned long ttynr;
- FILE *f;
+ const char *fn;
+ int k;
- if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
- return -ENOMEM;
+ assert(pid >= 0);
+ assert(d);
+
+ if (pid == 0)
+ fn = "/proc/self/stat";
+ else
+ fn = procfs_file_alloca(pid, "stat");
f = fopen(fn, "re");
- free(fn);
if (!f)
return -errno;
if (!fgets(line, sizeof(line), f)) {
k = feof(f) ? -EIO : -errno;
- fclose(f);
return k;
}
- fclose(f);
-
p = strrchr(line, ')');
if (!p)
return -EIO;
return ret;
}
-static int is_temporary_fs(struct statfs *s) {
+_pure_ static int is_temporary_fs(struct statfs *s) {
assert(s);
- return s->f_type == TMPFS_MAGIC ||
- (long)s->f_type == (long)RAMFS_MAGIC;
+ return
+ F_TYPE_CMP(s->f_type, TMPFS_MAGIC) ||
+ F_TYPE_CMP(s->f_type, RAMFS_MAGIC);
}
int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
}
int glob_exists(const char *path) {
- glob_t _cleanup_globfree_ g = {};
+ _cleanup_globfree_ glob_t g = {};
int r, k;
assert(path);
}
int getenv_for_pid(pid_t pid, const char *field, char **_value) {
- char path[sizeof("/proc/")-1 + DECIMAL_STR_MAX(pid_t) + sizeof("/environ")], *value = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ char *value = NULL;
int r;
- FILE *f;
bool done = false;
size_t l;
+ const char *path;
+ assert(pid >= 0);
assert(field);
assert(_value);
if (pid == 0)
- pid = getpid();
-
- snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
+ path = "/proc/self/environ";
+ else
+ path = procfs_file_alloca(pid, "environ");
f = fopen(path, "re");
if (!f)
if (memcmp(line, field, l) == 0 && line[l] == '=') {
value = strdup(line + l + 1);
- if (!value) {
- r = -ENOMEM;
- break;
- }
+ if (!value)
+ return -ENOMEM;
r = 1;
break;
} while (!done);
- fclose(f);
-
- if (r >= 0)
- *_value = value;
-
+ *_value = value;
return r;
}
return 0;
}
-void fclosep(FILE **f) {
- if (*f)
- fclose(*f);
-}
-
-void pclosep(FILE **f) {
- if (*f)
- pclose(*f);
-}
-
-void closep(int *fd) {
- if (*fd >= 0)
- close_nointr_nofail(*fd);
-}
-
-void closedirp(DIR **d) {
- if (*d)
- closedir(*d);
-}
-
bool filename_is_safe(const char *p) {
if (isempty(p))
*allocated = a;
return q;
}
+
+bool id128_is_valid(const char *s) {
+ size_t i, l;
+
+ l = strlen(s);
+ if (l == 32) {
+
+ /* Simple formatted 128bit hex string */
+
+ for (i = 0; i < l; i++) {
+ char c = s[i];
+
+ if (!(c >= '0' && c <= '9') &&
+ !(c >= 'a' && c <= 'z') &&
+ !(c >= 'A' && c <= 'Z'))
+ return false;
+ }
+
+ } else if (l == 36) {
+
+ /* Formatted UUID */
+
+ for (i = 0; i < l; i++) {
+ char c = s[i];
+
+ if ((i == 8 || i == 13 || i == 18 || i == 23)) {
+ if (c != '-')
+ return false;
+ } else {
+ if (!(c >= '0' && c <= '9') &&
+ !(c >= 'a' && c <= 'z') &&
+ !(c >= 'A' && c <= 'Z'))
+ return false;
+ }
+ }
+
+ } else
+ return false;
+
+ return true;
+}