chiark / gitweb /
efi: use efi_get_variable_string() instead of efi_get_variable() where we can
[elogind.git] / src / shared / util.c
index 29cb9f1e8df05782302322fe5d76a22ba6636aee..d754c836f2b5386cd01f711fb71b74e030a4aa30 100644 (file)
@@ -183,18 +183,25 @@ bool first_word(const char *s, const char *word) {
 }
 
 int close_nointr(int fd) {
-        assert(fd >= 0);
-
-        for (;;) {
-                int r;
+        int r;
 
-                r = close(fd);
-                if (r >= 0)
-                        return r;
+        assert(fd >= 0);
+        r = close(fd);
 
-                if (errno != EINTR)
-                        return -errno;
-        }
+        /* Just ignore EINTR; a retry loop is the wrong
+         * thing to do on Linux.
+         *
+         * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
+         * https://bugzilla.gnome.org/show_bug.cgi?id=682819
+         * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
+         * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
+         */
+        if (_unlikely_(r < 0 && errno == EINTR))
+                return 0;
+        else if (r >= 0)
+                return r;
+        else
+                return -errno;
 }
 
 void close_nointr_nofail(int fd) {
@@ -218,9 +225,9 @@ void close_many(const int fds[], unsigned n_fd) {
 int parse_boolean(const char *v) {
         assert(v);
 
-        if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
+        if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || strcaseeq(v, "on"))
                 return 1;
-        else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
+        else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || strcaseeq(v, "off"))
                 return 0;
 
         return -EINVAL;
@@ -720,7 +727,7 @@ int parse_env_file(
                                 value = va_arg(ap, char **);
 
                                 n = strlen(key);
-                                if (strncmp(p, key, n) != 0 ||
+                                if (!strneq(p, key, n) ||
                                     p[n] != '=')
                                         continue;
 
@@ -5909,3 +5916,82 @@ int on_ac_power(void) {
 
         return found_online || !found_offline;
 }
+
+static int search_and_fopen_internal(const char *path, const char *mode, char **search, FILE **_f) {
+        char **i;
+
+        assert(path);
+        assert(mode);
+        assert(_f);
+
+        if (!path_strv_canonicalize_uniq(search))
+                return -ENOMEM;
+
+        STRV_FOREACH(i, search) {
+                _cleanup_free_ char *p = NULL;
+                FILE *f;
+
+                p = strjoin(*i, "/", path, NULL);
+                if (!p)
+                        return -ENOMEM;
+
+                f = fopen(p, mode);
+                if (f) {
+                        *_f = f;
+                        return 0;
+                }
+
+                if (errno != ENOENT)
+                        return -errno;
+        }
+
+        return -ENOENT;
+}
+
+int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f) {
+        _cleanup_strv_free_ char **copy = NULL;
+
+        assert(path);
+        assert(mode);
+        assert(_f);
+
+        if (path_is_absolute(path)) {
+                FILE *f;
+
+                f = fopen(path, mode);
+                if (f) {
+                        *_f = f;
+                        return 0;
+                }
+
+                return -errno;
+        }
+
+        copy = strv_copy((char**) search);
+        if (!copy)
+                return -ENOMEM;
+
+        return search_and_fopen_internal(path, mode, copy, _f);
+}
+
+int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f) {
+        _cleanup_strv_free_ char **s = NULL;
+
+        if (path_is_absolute(path)) {
+                FILE *f;
+
+                f = fopen(path, mode);
+                if (f) {
+                        *_f = f;
+                        return 0;
+                }
+
+                return -errno;
+        }
+
+        s = strv_split_nulstr(search);
+        if (!s)
+                return -ENOMEM;
+
+        return search_and_fopen_internal(path, mode, s, _f);
+}