X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=409ccc7eed7df5fa61cd7b2d51b40d756665cd52;hp=dfaf7f7f45b07416bcd365b869c7b05b4618d752;hb=a7e07206021c6484a8d33c6ee156ecfb5b90534c;hpb=f02ca52281315cb6067a3798450bc814837c85ef diff --git a/src/shared/util.c b/src/shared/util.c index dfaf7f7f4..409ccc7ee 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -61,6 +61,7 @@ #include #include #include +#include #undef basename #ifdef HAVE_SYS_AUXV_H @@ -3456,7 +3457,7 @@ unsigned columns(void) { c = 80; cached_columns = c; - return c; + return cached_columns; } int fd_lines(int fd) { @@ -3473,7 +3474,7 @@ int fd_lines(int fd) { unsigned lines(void) { const char *e; - unsigned l; + int l; if (_likely_(cached_lines > 0)) return cached_lines; @@ -3481,7 +3482,7 @@ unsigned lines(void) { l = 0; e = getenv("LINES"); if (e) - (void) safe_atou(e, &l); + (void) safe_atoi(e, &l); if (l <= 0) l = fd_lines(STDOUT_FILENO); @@ -6858,6 +6859,15 @@ int umount_recursive(const char *prefix, int flags) { return r ? r : n; } +static int get_mount_flags(const char *path, unsigned long *flags) { + struct statvfs buf; + + if (statvfs(path, &buf) < 0) + return -errno; + *flags = buf.f_flag; + return 0; +} + int bind_remount_recursive(const char *prefix, bool ro) { _cleanup_set_free_free_ Set *done = NULL; _cleanup_free_ char *cleaned = NULL; @@ -6892,6 +6902,7 @@ int bind_remount_recursive(const char *prefix, bool ro) { _cleanup_set_free_free_ Set *todo = NULL; bool top_autofs = false; char *x; + unsigned long orig_flags; todo = set_new(&string_hash_ops); if (!todo) @@ -6969,7 +6980,11 @@ int bind_remount_recursive(const char *prefix, bool ro) { if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0) return -errno; - if (mount(NULL, prefix, NULL, MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) + orig_flags = 0; + (void) get_mount_flags(cleaned, &orig_flags); + orig_flags &= ~MS_RDONLY; + + if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) return -errno; x = strdup(cleaned); @@ -6989,7 +7004,14 @@ int bind_remount_recursive(const char *prefix, bool ro) { if (r < 0) return r; - if (mount(NULL, x, NULL, MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) { + /* Try to reuse the original flag set, but + * don't care for errors, in case of + * obstructed mounts */ + orig_flags = 0; + (void) get_mount_flags(x, &orig_flags); + orig_flags &= ~MS_RDONLY; + + if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) { /* Deal with mount points that are * obstructed by a later mount */ @@ -7653,3 +7675,28 @@ int fd_setcrtime(int fd, usec_t usec) { return 0; } + +int same_fd(int a, int b) { + struct stat sta, stb; + + assert(a >= 0); + assert(b >= 0); + + if (a == b) + return true; + + if (fstat(a, &sta) < 0) + return -errno; + + if (fstat(b, &stb) < 0) + return -errno; + + if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT)) + return false; + + if (S_ISREG(sta.st_mode) || S_ISDIR(sta.st_mode) || S_ISFIFO(sta.st_mode) || S_ISSOCK(sta.st_mode) || S_ISLNK(sta.st_mode)) + return (sta.st_dev == stb.st_dev) && (sta.st_ino == stb.st_ino); + + /* We consider all device fds different... */ + return false; +}