#include <sys/utsname.h>
#include <pwd.h>
#include <netinet/ip.h>
+#include <linux/kd.h>
#include "macro.h"
#include "util.h"
fclose(f);
- if (r[0] == 0)
- return get_process_name(pid, line);
+ /* Kernel threads have no argv[] */
+ if (r[0] == 0) {
+ char *t;
+ int h;
+
+ free(r);
+
+ if ((h = get_process_name(pid, &t)) < 0)
+ return h;
+
+ h = asprintf(&r, "[%s]", t);
+ free(t);
+
+ if (h < 0)
+ return -ENOMEM;
+ }
*line = r;
return 0;
return 0;
}
+int parent_of_path(const char *path, char **_r) {
+ const char *e, *a = NULL, *b = NULL, *p;
+ char *r;
+ bool slash = false;
+
+ assert(path);
+ assert(_r);
+
+ if (!*path)
+ return -EINVAL;
+
+ for (e = path; *e; e++) {
+
+ if (!slash && *e == '/') {
+ a = b;
+ b = e;
+ slash = true;
+ } else if (slash && *e != '/')
+ slash = false;
+ }
+
+ if (*(e-1) == '/')
+ p = a;
+ else
+ p = b;
+
+ if (!p)
+ return -EINVAL;
+
+ if (p == path)
+ r = strdup("/");
+ else
+ r = strndup(path, p-path);
+
+ if (!r)
+ return -ENOMEM;
+
+ *_r = r;
+ return 0;
+}
+
+
char *file_name_from_path(const char *p) {
char *r;
return -ENOMEM;
r = mkdir(t, mode);
-
free(t);
if (r < 0 && errno != EEXIST)
if ((r = mkdir_parents(path, mode)) < 0)
return r;
- if (mkdir(path, mode) < 0)
+ if (mkdir(path, mode) < 0 && errno != EEXIST)
return -errno;
return 0;
int reset_terminal(int fd) {
struct termios termios;
int r = 0;
+ long arg;
+
+ /* Set terminal to some sane defaults */
assert(fd >= 0);
- /* Set terminal to some sane defaults */
+ /* First, unlock termios */
+ zero(termios);
+ ioctl(fd, TIOCSLCKTRMIOS, &termios);
+
+ /* Disable exclusive mode, just in case */
+ ioctl(fd, TIOCNXCL);
+
+ /* Enable console unicode mode */
+ arg = K_UNICODE;
+ ioctl(fd, KDSKBMODE, &arg);
if (tcgetattr(fd, &termios) < 0) {
r = -errno;
}
if (e.wd != wd || !(e.mask & IN_CLOSE)) {
- r = -errno;
+ r = -EIO;
goto fail;
}
int path_is_mount_point(const char *t) {
struct stat a, b;
- char *copy;
+ char *parent;
+ int r;
if (lstat(t, &a) < 0) {
-
if (errno == ENOENT)
return 0;
return -errno;
}
- if (!(copy = strdup(t)))
- return -ENOMEM;
+ if ((r = parent_of_path(t, &parent)) < 0)
+ return r;
- if (lstat(dirname(copy), &b) < 0) {
- free(copy);
- return -errno;
- }
+ r = lstat(parent, &b);
+ free(parent);
- free(copy);
+ if (r < 0)
+ return -errno;
return a.st_dev != b.st_dev;
}
if (!(d = fdopendir(fd))) {
close_nointr_nofail(fd);
- return -errno;
+
+ return errno == ENOENT ? 0 : -errno;
}
for (;;) {
struct stat st;
if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
- if (ret == 0)
+ if (ret == 0 && errno != ENOENT)
ret = -errno;
continue;
}
int subdir_fd;
if ((subdir_fd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC)) < 0) {
- if (ret == 0)
+ if (ret == 0 && errno != ENOENT)
ret = -errno;
continue;
}
}
if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
- if (ret == 0)
+ if (ret == 0 && errno != ENOENT)
ret = -errno;
}
} else if (!only_dirs) {
if (unlinkat(fd, de->d_name, 0) < 0) {
- if (ret == 0)
+ if (ret == 0 && errno != ENOENT)
ret = -errno;
}
}