diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2014-01-13 18:16:50 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2014-01-13 18:16:50 -0500 |
commit | e33d2cfc5e0bafb10eb82bb32776c41e558a026c (patch) | |
tree | 619ae0451cd40f169d740a02f26bf46a17c854b1 /src/libudev | |
parent | 248ea81923ce671979ccbe0bca5683d4239feb70 (diff) |
src/udev: bring up to date with upstream.
These commits were authored by
Zbigniew Jędrzejewski-Szmek
Tom Gundersen
Kay Sievers
Lennart Poettering
Shawn Landden
Daniel Buch
Martin Pitt
Karel Zak
Yang Zhiyong
Note: udev_builtin_net_setup_link has *not* been imported. Also
still missing from udev-builtin is udev_builtin_uaccess.
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
Diffstat (limited to 'src/libudev')
-rw-r--r-- | src/libudev/Makefile.am | 2 | ||||
-rw-r--r-- | src/libudev/fileio.c | 139 | ||||
-rw-r--r-- | src/libudev/fileio.h | 27 | ||||
-rw-r--r-- | src/libudev/util.c | 137 | ||||
-rw-r--r-- | src/libudev/util.h | 44 |
5 files changed, 272 insertions, 77 deletions
diff --git a/src/libudev/Makefile.am b/src/libudev/Makefile.am index a588080d12..286dc4b62a 100644 --- a/src/libudev/Makefile.am +++ b/src/libudev/Makefile.am @@ -37,6 +37,7 @@ libudev_la_SOURCES =\ conf-files.c \ device-nodes.c \ exit-status.c \ + fileio.c \ hashmap.c \ log.c \ MurmurHash2.c \ @@ -56,6 +57,7 @@ noinst_HEADERS = \ def.h \ device-nodes.h \ exit-status.h \ + fileio.h \ hashmap.h \ ioprio.h \ log.h \ diff --git a/src/libudev/fileio.c b/src/libudev/fileio.c new file mode 100644 index 0000000000..8eb834dcd0 --- /dev/null +++ b/src/libudev/fileio.c @@ -0,0 +1,139 @@ +/*** + This file is part of eudev, forked from systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <unistd.h> +#include <sys/sendfile.h> +#include "fileio.h" +#include "util.h" +#include "strv.h" +#include "utf8.h" +#include "ctype.h" + +int write_string_to_file(FILE *f, const char *line) { + errno = 0; + fputs(line, f); + if (!endswith(line, "\n")) + fputc('\n', f); + + fflush(f); + + if (ferror(f)) + return errno ? -errno : -EIO; + + return 0; +} + +int write_string_file(const char *fn, const char *line) { + _cleanup_fclose_ FILE *f = NULL; + + assert(fn); + assert(line); + + f = fopen(fn, "we"); + if (!f) + return -errno; + + return write_string_to_file(f, line); +} +int read_one_line_file(const char *fn, char **line) { + _cleanup_fclose_ FILE *f = NULL; + char t[LINE_MAX], *c; + + assert(fn); + assert(line); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (!fgets(t, sizeof(t), f)) { + + if (ferror(f)) + return errno ? -errno : -EIO; + + t[0] = 0; + } + + c = strdup(t); + if (!c) + return -ENOMEM; + truncate_nl(c); + + *line = c; + return 0; +} + +int read_full_file(const char *fn, char **contents, size_t *size) { + _cleanup_fclose_ FILE *f = NULL; + size_t n, l; + _cleanup_free_ char *buf = NULL; + struct stat st; + + assert(fn); + assert(contents); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (fstat(fileno(f), &st) < 0) + return -errno; + + /* Safety check */ + if (st.st_size > 4*1024*1024) + return -E2BIG; + + n = st.st_size > 0 ? st.st_size : LINE_MAX; + l = 0; + + for (;;) { + char *t; + size_t k; + + t = realloc(buf, n+1); + if (!t) + return -ENOMEM; + + buf = t; + k = fread(buf + l, 1, n - l, f); + + if (k <= 0) { + if (ferror(f)) + return -errno; + + break; + } + + l += k; + n *= 2; + + /* Safety check */ + if (n > 4*1024*1024) + return -E2BIG; + } + + buf[l] = 0; + *contents = buf; + buf = NULL; /* do not free */ + + if (size) + *size = l; + + return 0; +} diff --git a/src/libudev/fileio.h b/src/libudev/fileio.h new file mode 100644 index 0000000000..c7997c58a2 --- /dev/null +++ b/src/libudev/fileio.h @@ -0,0 +1,27 @@ +/*** + This file is part of eudev, forked from systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ +#include <stddef.h> +#include <stdio.h> + +#include "macro.h" + +int write_string_to_file(FILE *f, const char *line); +int write_string_file(const char *fn, const char *line); +int read_one_line_file(const char *fn, char **line); +int read_full_file(const char *fn, char **contents, size_t *size); diff --git a/src/libudev/util.c b/src/libudev/util.c index 58377d548f..98be5307f6 100644 --- a/src/libudev/util.c +++ b/src/libudev/util.c @@ -69,6 +69,7 @@ #include "path-util.h" #include "exit-status.h" #include "hashmap.h" +#include "fileio.h" int saved_argc = 0; char **saved_argv = NULL; @@ -254,23 +255,6 @@ char* endswith(const char *s, const char *postfix) { return (char*) s + sl - pl; } -char* startswith(const char *s, const char *prefix) { - const char *a, *b; - - assert(s); - assert(prefix); - - a = s, b = prefix; - for (;;) { - if (*b == 0) - return (char*) a; - if (*a != *b) - return NULL; - - a++, b++; - } -} - int close_nointr(int fd) { int r; @@ -449,59 +433,6 @@ char *split_quoted(const char *c, size_t *l, char **state) { return (char*) current; } -int write_one_line_file(const char *fn, const char *line) { - _cleanup_fclose_ FILE *f = NULL; - - assert(fn); - assert(line); - - f = fopen(fn, "we"); - if (!f) - return -errno; - - errno = 0; - if (fputs(line, f) < 0) - return errno ? -errno : -EIO; - - if (!endswith(line, "\n")) - fputc('\n', f); - - fflush(f); - - if (ferror(f)) - return errno ? -errno : -EIO; - - return 0; -} - -int read_one_line_file(const char *fn, char **line) { - _cleanup_fclose_ FILE *f = NULL; - char t[LINE_MAX], *c; - - assert(fn); - assert(line); - - f = fopen(fn, "re"); - if (!f) - return -errno; - - if (!fgets(t, sizeof(t), f)) { - - if (ferror(f)) - return errno ? -errno : -EIO; - - t[0] = 0; - } - - c = strdup(t); - if (!c) - return -ENOMEM; - truncate_nl(c); - - *line = c; - return 0; -} - char *truncate_nl(char *s) { assert(s); @@ -794,6 +725,19 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { return endswith(de->d_name, suffix); } +bool nulstr_contains(const char*nulstr, const char *needle) { + const char *i; + + if (!nulstr) + return false; + + NULSTR_FOREACH(i, nulstr) + if (streq(i, needle)) + return true; + + return false; +} + int execute_command(const char *command, char *const argv[]) { @@ -1161,3 +1105,56 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, } return NULL; } + +int proc_cmdline(char **ret) { + int r; + + /* disable containers for now + if (detect_container(NULL) > 0) { + char *buf, *p; + size_t sz = 0; + + r = read_full_file("/proc/1/cmdline", &buf, &sz); + if (r < 0) + return r; + + for (p = buf; p + 1 < buf + sz; p++) + if (*p == 0) + *p = ' '; + + *p = 0; + *ret = buf; + return 1; + } + */ + + r = read_one_line_file("/proc/cmdline", ret); + if (r < 0) + return r; + + return 1; +} + +int getpeercred(int fd, struct ucred *ucred) { + socklen_t n = sizeof(struct ucred); + struct ucred u; + int r; + + assert(fd >= 0); + assert(ucred); + + r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n); + if (r < 0) + return -errno; + + if (n != sizeof(struct ucred)) + return -EIO; + + /* Check if the data is actually useful and not suppressed due + * to namespacing issues */ + if (u.pid <= 0) + return -ENODATA; + + *ucred = u; + return 0; +} diff --git a/src/libudev/util.h b/src/libudev/util.h index 22f48b44ad..50e6a44af5 100644 --- a/src/libudev/util.h +++ b/src/libudev/util.h @@ -21,6 +21,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <string.h> #include <time.h> #include <stdlib.h> #include <stdio.h> @@ -30,6 +31,7 @@ #include <dirent.h> #include <stddef.h> #include <unistd.h> +#include <sys/socket.h> #include "macro.h" @@ -69,9 +71,12 @@ union dirent_storage { /* What is interpreted as whitespace? */ #define WHITESPACE " \t\n\r" -#define NEWLINE "\n\r" -#define QUOTES "\"\'" -#define COMMENTS "#;" +#define NEWLINE "\n\r" +#define QUOTES "\"\'" +#define COMMENTS "#;" +#define GLOB_CHARS "*?[" + +#define FORMAT_BYTES_MAX 8 #define ANSI_HIGHLIGHT_ON "\x1B[1;39m" #define ANSI_RED_ON "\x1B[31m" @@ -79,6 +84,7 @@ union dirent_storage { #define ANSI_GREEN_ON "\x1B[32m" #define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m" #define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m" +#define ANSI_HIGHLIGHT_BLUE_ON "\x1B[1;34m" #define ANSI_HIGHLIGHT_OFF "\x1B[0m" #define ANSI_ERASE_TO_END_OF_LINE "\x1B[K" @@ -105,8 +111,13 @@ static inline bool isempty(const char *p) { return !p || !p[0]; } +static inline const char *startswith(const char *s, const char *prefix) { + if (strncmp(s, prefix, strlen(prefix)) == 0) + return s + strlen(prefix); + return NULL; +} + char *endswith(const char *s, const char *postfix) _pure_; -char *startswith(const char *s, const char *prefix) _pure_; int close_nointr(int fd); void close_nointr_nofail(int fd); @@ -123,9 +134,6 @@ char *split_quoted(const char *c, size_t *l, char **state); #define FOREACH_WORD_QUOTED(word, length, s, state) \ for ((state) = NULL, (word) = split_quoted((s), &(length), &(state)); (word); (word) = split_quoted((s), &(length), &(state))) -int write_one_line_file(const char *fn, const char *line); -int read_one_line_file(const char *fn, char **line); - char *strappend(const char *s, const char *suffix); char *strnappend(const char *s, const char *suffix, size_t length); @@ -206,10 +214,15 @@ int null_or_empty_path(const char *fn); int execute_command(const char *command, char *const argv[]); +bool nulstr_contains(const char*nulstr, const char *needle); + char *strjoin(const char *x, ...) _sentinel_; bool is_main_thread(void); +#define NULSTR_FOREACH(i, l) \ + for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) + #define NULSTR_FOREACH_PAIR(i, j, l) \ for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i)) @@ -247,6 +260,13 @@ static inline void freep(void *p) { free(*(void**) p); } +#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ + static inline void func##p(type *p) { \ + if (*p) \ + func(*p); \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + static inline void fclosep(FILE **f) { if (*f) fclose(*f); @@ -274,6 +294,13 @@ _malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) return malloc(a * b); } +/** + * Check if a string contains any glob patterns. + */ +_pure_ static inline bool string_is_glob(const char *p) { + return !!strpbrk(p, GLOB_CHARS); +} + void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *, void *), void *arg); @@ -300,3 +327,6 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, qsort(base, nmemb, size, compar); } } + +int proc_cmdline(char **ret); +int getpeercred(int fd, struct ucred *ucred); |