summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2013-06-06 00:18:45 -0400
committerAnthony G. Basile <blueness@gentoo.org>2013-06-06 00:18:45 -0400
commit6f8f3edfe8dd70e24105d889f664ff033eb0555e (patch)
treec9a74b97b9c9cc01cd2608ba1506f8c70f2d8df6
parentac6af1454474115a0105f07c5704e13e40d0ff0e (diff)
Round 3 of remove unused functions from src/libudev/{conf-files,hashmap,util}
The following functions were removed: strv_env_get_n strv_env_get conf_files_list hashmap_remove hashmap_move log_dump_internal parse_uid read_full_file strstrip file_in_same_dir cunescape cunescape_length cunescape_length_with_prefix xescape dirent_is_file close_all_fds read_one_char ask reset_terminal_fd reset_terminal flush_fd loop_read get_ctty_devnr get_ctty rm_rf_children rm_rf_children_dangerous rm_rf status_vprintf fd_columns columns fd_lines lines on_tty ellipsize ellipsize_mem touch unquote resolve_dev_console tty_is_vc vtnr_from_tty terminal_vhangup_fd terminal_vhangup file_is_priv_sticky signal_from_string fd_wait_for_event memdup memdup_multiply Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
-rw-r--r--src/libudev/Makefile.am2
-rw-r--r--src/libudev/conf-files.c17
-rw-r--r--src/libudev/conf-files.h1
-rw-r--r--src/libudev/env-util.c49
-rw-r--r--src/libudev/env-util.h25
-rw-r--r--src/libudev/hashmap.c60
-rw-r--r--src/libudev/hashmap.h2
-rw-r--r--src/libudev/log.h11
-rw-r--r--src/libudev/util.c1282
-rw-r--r--src/libudev/util.h70
10 files changed, 0 insertions, 1519 deletions
diff --git a/src/libudev/Makefile.am b/src/libudev/Makefile.am
index 521eea8253..683944a671 100644
--- a/src/libudev/Makefile.am
+++ b/src/libudev/Makefile.am
@@ -36,7 +36,6 @@ libudev_la_SOURCES =\
cgroup-util.c \
conf-files.c \
exit-status.c \
- env-util.c \
hashmap.c \
log.c \
path-util.c \
@@ -51,7 +50,6 @@ noinst_HEADERS = \
cgroup-util.h \
conf-files.h \
def.h \
- env-util.h \
exit-status.h \
hashmap.h \
ioprio.h \
diff --git a/src/libudev/conf-files.c b/src/libudev/conf-files.c
index 5938481f6b..2baefffad5 100644
--- a/src/libudev/conf-files.c
+++ b/src/libudev/conf-files.c
@@ -146,20 +146,3 @@ int conf_files_list_strv(char ***strv, const char *suffix, const char *root, con
return conf_files_list_strv_internal(strv, suffix, root, copy);
}
-
-int conf_files_list(char ***strv, const char *suffix, const char *root, const char *dir, ...) {
- _cleanup_strv_free_ char **dirs = NULL;
- va_list ap;
-
- assert(strv);
- assert(suffix);
-
- va_start(ap, dir);
- dirs = strv_new_ap(dir, ap);
- va_end(ap);
-
- if (!dirs)
- return -ENOMEM;
-
- return conf_files_list_strv_internal(strv, suffix, root, dirs);
-}
diff --git a/src/libudev/conf-files.h b/src/libudev/conf-files.h
index 73afe19b97..8fdf9a4632 100644
--- a/src/libudev/conf-files.h
+++ b/src/libudev/conf-files.h
@@ -25,7 +25,6 @@
#include "macro.h"
-int conf_files_list(char ***strv, const char *suffix, const char *root, const char *dir, ...);
int conf_files_list_strv(char ***strv, const char *suffix, const char *root, const char* const* dirs);
#endif
diff --git a/src/libudev/env-util.c b/src/libudev/env-util.c
deleted file mode 100644
index c2381ec6a3..0000000000
--- a/src/libudev/env-util.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2012 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 <assert.h>
-#include <string.h>
-#include <util.h>
-#include <unistd.h>
-
-#include "strv.h"
-
-char *strv_env_get_n(char **l, const char *name, size_t k) {
- char **i;
-
- assert(name);
-
- if (k <= 0)
- return NULL;
-
- STRV_FOREACH(i, l)
- if (strneq(*i, name, k) &&
- (*i)[k] == '=')
- return *i + k + 1;
-
- return NULL;
-}
-
-char *strv_env_get(char **l, const char *name) {
- assert(name);
-
- return strv_env_get_n(l, name, strlen(name));
-}
diff --git a/src/libudev/env-util.h b/src/libudev/env-util.h
deleted file mode 100644
index 2aa30aeda3..0000000000
--- a/src/libudev/env-util.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 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/>.
-***/
-
-char *strv_env_get_n(char **l, const char *name, size_t k) _pure_;
-char *strv_env_get(char **x, const char *n) _pure_;
diff --git a/src/libudev/hashmap.c b/src/libudev/hashmap.c
index 6626288cdc..58702d7d59 100644
--- a/src/libudev/hashmap.c
+++ b/src/libudev/hashmap.c
@@ -103,19 +103,6 @@ static void deallocate_tile(void **first_tile, void *p) {
*first_tile = p;
}
-#ifdef VALGRIND
-
-static void drop_pool(struct pool *p) {
- while (p) {
- struct pool *n;
- n = p->next;
- free(p);
- p = n;
- }
-}
-
-#endif
-
unsigned string_hash_func(const void *p) {
unsigned hash = 5381;
const signed char *c;
@@ -363,25 +350,6 @@ bool hashmap_contains(Hashmap *h, const void *key) {
return true;
}
-void* hashmap_remove(Hashmap *h, const void *key) {
- struct hashmap_entry *e;
- unsigned hash;
- void *data;
-
- if (!h)
- return NULL;
-
- hash = h->hash_func(key) % NBUCKETS;
-
- if (!(e = hash_scan(h, hash, key)))
- return NULL;
-
- data = e->value;
- remove_entry(h, e);
-
- return data;
-}
-
void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key) {
struct hashmap_entry *e;
@@ -494,34 +462,6 @@ int hashmap_merge(Hashmap *h, Hashmap *other) {
return 0;
}
-void hashmap_move(Hashmap *h, Hashmap *other) {
- struct hashmap_entry *e, *n;
-
- assert(h);
-
- /* The same as hashmap_merge(), but every new item from other
- * is moved to h. This function is guaranteed to succeed. */
-
- if (!other)
- return;
-
- for (e = other->iterate_list_head; e; e = n) {
- unsigned h_hash, other_hash;
-
- n = e->iterate_next;
-
- h_hash = h->hash_func(e->key) % NBUCKETS;
-
- if (hash_scan(h, h_hash, e->key))
- continue;
-
- other_hash = other->hash_func(e->key) % NBUCKETS;
-
- unlink_entry(other, e, other_hash);
- link_entry(h, e, h_hash);
- }
-}
-
char **hashmap_get_strv(Hashmap *h) {
char **sv;
Iterator it;
diff --git a/src/libudev/hashmap.h b/src/libudev/hashmap.h
index a889fc7c18..4c17fe4d33 100644
--- a/src/libudev/hashmap.h
+++ b/src/libudev/hashmap.h
@@ -56,10 +56,8 @@ void hashmap_free_free(Hashmap *h);
int hashmap_put(Hashmap *h, const void *key, void *value);
void *hashmap_get(Hashmap *h, const void *key);
bool hashmap_contains(Hashmap *h, const void *key);
-void *hashmap_remove(Hashmap *h, const void *key);
int hashmap_merge(Hashmap *h, Hashmap *other);
-void hashmap_move(Hashmap *h, Hashmap *other);
unsigned hashmap_size(Hashmap *h) _pure_;
diff --git a/src/libudev/log.h b/src/libudev/log.h
index fab0100b6a..0a15adb41c 100644
--- a/src/libudev/log.h
+++ b/src/libudev/log.h
@@ -73,14 +73,6 @@ int log_oom_internal(
int line,
const char *func);
-/* This modifies the buffer passed! */
-int log_dump_internal(
- int level,
- const char*file,
- int line,
- const char *func,
- char *buffer);
-
_noreturn_ void log_assert_failed(
const char *text,
const char *file,
@@ -103,9 +95,6 @@ _noreturn_ void log_assert_failed_unreachable(
#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
-/* This modifies the buffer passed! */
-#define log_dump(level, buffer) log_dump_internal(level, __FILE__, __LINE__, __func__, buffer)
-
const char *log_target_to_string(LogTarget target) _const_;
LogTarget log_target_from_string(const char *s) _pure_;
diff --git a/src/libudev/util.c b/src/libudev/util.c
index 48469e6e34..dc1641c3bc 100644
--- a/src/libudev/util.c
+++ b/src/libudev/util.c
@@ -70,7 +70,6 @@
#include "path-util.h"
#include "exit-status.h"
#include "hashmap.h"
-#include "env-util.h"
int saved_argc = 0;
char **saved_argv = NULL;
@@ -197,27 +196,6 @@ void close_nointr_nofail(int fd) {
assert_se(close_nointr(fd) == 0);
}
-int parse_uid(const char *s, uid_t* ret_uid) {
- unsigned long ul = 0;
- uid_t uid;
- int r;
-
- assert(s);
- assert(ret_uid);
-
- r = safe_atolu(s, &ul);
- if (r < 0)
- return r;
-
- uid = (uid_t) ul;
-
- if ((unsigned long) uid != ul)
- return -ERANGE;
-
- *ret_uid = uid;
- return 0;
-}
-
int safe_atou(const char *s, unsigned *ret_u) {
char *x = NULL;
unsigned long l;
@@ -418,62 +396,6 @@ int read_one_line_file(const char *fn, char **line) {
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;
-
- 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;
-
- if (size)
- *size = l;
-
- return 0;
-}
-
char *truncate_nl(char *s) {
assert(s);
@@ -546,50 +468,6 @@ int readlink_malloc(const char *p, char **r) {
}
}
-char *strstrip(char *s) {
- char *e;
-
- /* Drops trailing whitespace. Modifies the string in
- * place. Returns pointer to first non-space character */
-
- s += strspn(s, WHITESPACE);
-
- for (e = strchr(s, 0); e > s; e --)
- if (!strchr(WHITESPACE, e[-1]))
- break;
-
- *e = 0;
-
- return s;
-}
-
-char *file_in_same_dir(const char *path, const char *filename) {
- char *e, *r;
- size_t k;
-
- assert(path);
- assert(filename);
-
- /* This removes the last component of path and appends
- * filename, unless the latter is absolute anyway or the
- * former isn't */
-
- if (path_is_absolute(filename))
- return strdup(filename);
-
- if (!(e = strrchr(path, '/')))
- return strdup(filename);
-
- k = strlen(filename);
- if (!(r = new(char, e-path+1+k+1)))
- return NULL;
-
- memcpy(r, path, e-path+1);
- memcpy(r+(e-path)+1, filename, k+1);
-
- return r;
-}
-
char hexchar(int x) {
static const char table[16] = "0123456789abcdef";
@@ -622,174 +500,6 @@ int unoctchar(char c) {
return -1;
}
-char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
- char *r, *t;
- const char *f;
- size_t pl;
-
- assert(s);
-
- /* Undoes C style string escaping, and optionally prefixes it. */
-
- pl = prefix ? strlen(prefix) : 0;
-
- r = new(char, pl+length+1);
- if (!r)
- return r;
-
- if (prefix)
- memcpy(r, prefix, pl);
-
- for (f = s, t = r + pl; f < s + length; f++) {
-
- if (*f != '\\') {
- *(t++) = *f;
- continue;
- }
-
- f++;
-
- switch (*f) {
-
- case 'a':
- *(t++) = '\a';
- break;
- case 'b':
- *(t++) = '\b';
- break;
- case 'f':
- *(t++) = '\f';
- break;
- case 'n':
- *(t++) = '\n';
- break;
- case 'r':
- *(t++) = '\r';
- break;
- case 't':
- *(t++) = '\t';
- break;
- case 'v':
- *(t++) = '\v';
- break;
- case '\\':
- *(t++) = '\\';
- break;
- case '"':
- *(t++) = '"';
- break;
- case '\'':
- *(t++) = '\'';
- break;
-
- case 's':
- /* This is an extension of the XDG syntax files */
- *(t++) = ' ';
- break;
-
- case 'x': {
- /* hexadecimal encoding */
- int a, b;
-
- a = unhexchar(f[1]);
- b = unhexchar(f[2]);
-
- if (a < 0 || b < 0) {
- /* Invalid escape code, let's take it literal then */
- *(t++) = '\\';
- *(t++) = 'x';
- } else {
- *(t++) = (char) ((a << 4) | b);
- f += 2;
- }
-
- break;
- }
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7': {
- /* octal encoding */
- int a, b, c;
-
- a = unoctchar(f[0]);
- b = unoctchar(f[1]);
- c = unoctchar(f[2]);
-
- if (a < 0 || b < 0 || c < 0) {
- /* Invalid escape code, let's take it literal then */
- *(t++) = '\\';
- *(t++) = f[0];
- } else {
- *(t++) = (char) ((a << 6) | (b << 3) | c);
- f += 2;
- }
-
- break;
- }
-
- case 0:
- /* premature end of string.*/
- *(t++) = '\\';
- goto finish;
-
- default:
- /* Invalid escape code, let's take it literal then */
- *(t++) = '\\';
- *(t++) = *f;
- break;
- }
- }
-
-finish:
- *t = 0;
- return r;
-}
-
-char *cunescape_length(const char *s, size_t length) {
- return cunescape_length_with_prefix(s, length, NULL);
-}
-
-char *cunescape(const char *s) {
- assert(s);
-
- return cunescape_length(s, strlen(s));
-}
-
-char *xescape(const char *s, const char *bad) {
- char *r, *t;
- const char *f;
-
- /* Escapes all chars in bad, in addition to \ and all special
- * chars, in \xFF style escaping. May be reversed with
- * cunescape. */
-
- r = new(char, strlen(s) * 4 + 1);
- if (!r)
- return NULL;
-
- for (f = s, t = r; *f; f++) {
-
- if ((*f < ' ') || (*f >= 127) ||
- (*f == '\\') || strchr(bad, *f)) {
- *(t++) = '\\';
- *(t++) = 'x';
- *(t++) = hexchar(*f >> 4);
- *(t++) = hexchar(*f);
- } else
- *(t++) = *f;
- }
-
- *t = 0;
-
- return r;
-}
-
_pure_ static bool ignore_file_allow_backup(const char *filename) {
assert(filename);
@@ -827,66 +537,6 @@ _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
return false;
}
-int close_all_fds(const int except[], unsigned n_except) {
- DIR *d;
- struct dirent *de;
- int r = 0;
-
- assert(n_except == 0 || except);
-
- d = opendir("/proc/self/fd");
- if (!d) {
- int fd;
- struct rlimit rl;
-
- /* When /proc isn't available (for example in chroots)
- * the fallback is brute forcing through the fd
- * table */
-
- assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
- for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
-
- if (fd_in_set(fd, except, n_except))
- continue;
-
- if (close_nointr(fd) < 0)
- if (errno != EBADF && r == 0)
- r = -errno;
- }
-
- return r;
- }
-
- while ((de = readdir(d))) {
- int fd = -1;
-
- if (ignore_file(de->d_name))
- continue;
-
- if (safe_atoi(de->d_name, &fd) < 0)
- /* Let's better ignore this, just in case */
- continue;
-
- if (fd < 3)
- continue;
-
- if (fd == dirfd(d))
- continue;
-
- if (fd_in_set(fd, except, n_except))
- continue;
-
- if (close_nointr(fd) < 0) {
- /* Valgrind has its own FD and doesn't want to have it closed */
- if (errno != EBADF && r == 0)
- r = -errno;
- }
- }
-
- closedir(d);
- return r;
-}
-
char *format_timespan(char *buf, size_t l, usec_t t) {
static const struct {
const char *suffix;
@@ -942,190 +592,6 @@ char *format_timespan(char *buf, size_t l, usec_t t) {
return buf;
}
-int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
- struct termios old_termios, new_termios;
- char c;
- char line[LINE_MAX];
-
- assert(f);
- assert(ret);
-
- if (tcgetattr(fileno(f), &old_termios) >= 0) {
- new_termios = old_termios;
-
- new_termios.c_lflag &= ~ICANON;
- new_termios.c_cc[VMIN] = 1;
- new_termios.c_cc[VTIME] = 0;
-
- if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
- size_t k;
-
- if (t != (usec_t) -1) {
- if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
- tcsetattr(fileno(f), TCSADRAIN, &old_termios);
- return -ETIMEDOUT;
- }
- }
-
- k = fread(&c, 1, 1, f);
-
- tcsetattr(fileno(f), TCSADRAIN, &old_termios);
-
- if (k <= 0)
- return -EIO;
-
- if (need_nl)
- *need_nl = c != '\n';
-
- *ret = c;
- return 0;
- }
- }
-
- if (t != (usec_t) -1)
- if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
- return -ETIMEDOUT;
-
- if (!fgets(line, sizeof(line), f))
- return -EIO;
-
- truncate_nl(line);
-
- if (strlen(line) != 1)
- return -EBADMSG;
-
- if (need_nl)
- *need_nl = false;
-
- *ret = line[0];
- return 0;
-}
-
-int ask(char *ret, const char *replies, const char *text, ...) {
-
- assert(ret);
- assert(replies);
- assert(text);
-
- for (;;) {
- va_list ap;
- char c;
- int r;
- bool need_nl = true;
-
- if (on_tty())
- fputs(ANSI_HIGHLIGHT_ON, stdout);
-
- va_start(ap, text);
- vprintf(text, ap);
- va_end(ap);
-
- if (on_tty())
- fputs(ANSI_HIGHLIGHT_OFF, stdout);
-
- fflush(stdout);
-
- r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
- if (r < 0) {
-
- if (r == -EBADMSG) {
- puts("Bad input, please try again.");
- continue;
- }
-
- putchar('\n');
- return r;
- }
-
- if (need_nl)
- putchar('\n');
-
- if (strchr(replies, c)) {
- *ret = c;
- return 0;
- }
-
- puts("Read unexpected character, please try again.");
- }
-}
-
-int reset_terminal_fd(int fd, bool switch_to_text) {
- struct termios termios;
- int r = 0;
-
- /* Set terminal to some sane defaults */
-
- assert(fd >= 0);
-
- /* We leave locked terminal attributes untouched, so that
- * Plymouth may set whatever it wants to set, and we don't
- * interfere with that. */
-
- /* Disable exclusive mode, just in case */
- ioctl(fd, TIOCNXCL);
-
- /* Switch to text mode */
- if (switch_to_text)
- ioctl(fd, KDSETMODE, KD_TEXT);
-
- /* Enable console unicode mode */
- ioctl(fd, KDSKBMODE, K_UNICODE);
-
- if (tcgetattr(fd, &termios) < 0) {
- r = -errno;
- goto finish;
- }
-
- /* We only reset the stuff that matters to the software. How
- * hardware is set up we don't touch assuming that somebody
- * else will do that for us */
-
- termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
- termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
- termios.c_oflag |= ONLCR;
- termios.c_cflag |= CREAD;
- termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
-
- termios.c_cc[VINTR] = 03; /* ^C */
- termios.c_cc[VQUIT] = 034; /* ^\ */
- termios.c_cc[VERASE] = 0177;
- termios.c_cc[VKILL] = 025; /* ^X */
- termios.c_cc[VEOF] = 04; /* ^D */
- termios.c_cc[VSTART] = 021; /* ^Q */
- termios.c_cc[VSTOP] = 023; /* ^S */
- termios.c_cc[VSUSP] = 032; /* ^Z */
- termios.c_cc[VLNEXT] = 026; /* ^V */
- termios.c_cc[VWERASE] = 027; /* ^W */
- termios.c_cc[VREPRINT] = 022; /* ^R */
- termios.c_cc[VEOL] = 0;
- termios.c_cc[VEOL2] = 0;
-
- termios.c_cc[VTIME] = 0;
- termios.c_cc[VMIN] = 1;
-
- if (tcsetattr(fd, TCSANOW, &termios) < 0)
- r = -errno;
-
-finish:
- /* Just in case, flush all crap out */
- tcflush(fd, TCIOFLUSH);
-
- return r;
-}
-
-int reset_terminal(const char *name) {
- int fd, r;
-
- fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- r = reset_terminal_fd(fd, true);
- close_nointr_nofail(fd);
-
- return r;
-}
-
int open_terminal(const char *name, int mode) {
int fd, r;
unsigned c = 0;
@@ -1172,294 +638,6 @@ int open_terminal(const char *name, int mode) {
return fd;
}
-int flush_fd(int fd) {
- struct pollfd pollfd = {
- .fd = fd,
- .events = POLLIN,
- };
-
- for (;;) {
- char buf[LINE_MAX];
- ssize_t l;
- int r;
-
- r = poll(&pollfd, 1, 0);
- if (r < 0) {
- if (errno == EINTR)
- continue;
-
- return -errno;
-
- } else if (r == 0)
- return 0;
-
- l = read(fd, buf, sizeof(buf));
- if (l < 0) {
-
- if (errno == EINTR)
- continue;
-
- if (errno == EAGAIN)
- return 0;
-
- return -errno;
- } else if (l == 0)
- return 0;
- }
-}
-
-ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
- uint8_t *p;
- ssize_t n = 0;
-
- assert(fd >= 0);
- assert(buf);
-
- p = buf;
-
- while (nbytes > 0) {
- ssize_t k;
-
- if ((k = read(fd, p, nbytes)) <= 0) {
-
- if (k < 0 && errno == EINTR)
- continue;
-
- if (k < 0 && errno == EAGAIN && do_poll) {
- struct pollfd pollfd = {
- .fd = fd,
- .events = POLLIN,
- };
-
- if (poll(&pollfd, 1, -1) < 0) {
- if (errno == EINTR)
- continue;
-
- return n > 0 ? n : -errno;
- }
-
- if (pollfd.revents != POLLIN)
- return n > 0 ? n : -EIO;
-
- continue;
- }
-
- return n > 0 ? n : (k < 0 ? -errno : 0);
- }
-
- p += k;
- nbytes -= k;
- n += k;
- }
-
- return n;
-}
-
-int get_ctty_devnr(pid_t pid, dev_t *d) {
- _cleanup_fclose_ FILE *f = NULL;
- char line[LINE_MAX], *p;
- unsigned long ttynr;
- const char *fn;
- int k;
-
- assert(pid >= 0);
- assert(d);
-
- if (pid == 0)
- fn = "/proc/self/stat";
- else
- fn = procfs_file_alloca(pid, "stat");
-
- f = fopen(fn, "re");
- if (!f)
- return -errno;
-
- if (!fgets(line, sizeof(line), f)) {
- k = feof(f) ? -EIO : -errno;
- return k;
- }
-
- p = strrchr(line, ')');
- if (!p)
- return -EIO;
-
- p++;
-
- if (sscanf(p, " "
- "%*c " /* state */
- "%*d " /* ppid */
- "%*d " /* pgrp */
- "%*d " /* session */
- "%lu ", /* ttynr */
- &ttynr) != 1)
- return -EIO;
-
- if (major(ttynr) == 0 && minor(ttynr) == 0)
- return -ENOENT;
-
- *d = (dev_t) ttynr;
- return 0;
-}
-
-int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
- int k;
- char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *s, *b, *p;
- dev_t devnr;
-
- assert(r);
-
- k = get_ctty_devnr(pid, &devnr);
- if (k < 0)
- return k;
-
- snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
-
- k = readlink_malloc(fn, &s);
- if (k < 0) {
-
- if (k != -ENOENT)
- return k;
-
- /* This is an ugly hack */
- if (major(devnr) == 136) {
- if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
- return -ENOMEM;
-
- *r = b;
- if (_devnr)
- *_devnr = devnr;
-
- return 0;
- }
-
- /* Probably something like the ptys which have no
- * symlink in /dev/char. Let's return something
- * vaguely useful. */
-
- b = strdup(fn + 5);
- if (!b)
- return -ENOMEM;
-
- *r = b;
- if (_devnr)
- *_devnr = devnr;
-
- return 0;
- }
-
- if (startswith(s, "/dev/"))
- p = s + 5;
- else if (startswith(s, "../"))
- p = s + 3;
- else
- p = s;
-
- b = strdup(p);
- free(s);
-
- if (!b)
- return -ENOMEM;
-
- *r = b;
- if (_devnr)
- *_devnr = devnr;
-
- return 0;
-}
-
-int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
- DIR *d;
- int ret = 0;
-
- assert(fd >= 0);
-
- /* This returns the first error we run into, but nevertheless
- * tries to go on. This closes the passed fd. */
-
- d = fdopendir(fd);
- if (!d) {
- close_nointr_nofail(fd);
-
- return errno == ENOENT ? 0 : -errno;
- }
-
- for (;;) {
- struct dirent *de;
- union dirent_storage buf;
- bool is_dir, keep_around;
- struct stat st;
- int r;
-
- r = readdir_r(d, &buf.de, &de);
- if (r != 0 && ret == 0) {
- ret = -r;
- break;
- }
-
- if (!de)
- break;
-
- if (streq(de->d_name, ".") || streq(de->d_name, ".."))
- continue;
-
- if (de->d_type == DT_UNKNOWN ||
- honour_sticky ||
- (de->d_type == DT_DIR && root_dev)) {
- if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
- if (ret == 0 && errno != ENOENT)
- ret = -errno;
- continue;
- }
-
- is_dir = S_ISDIR(st.st_mode);
- keep_around =
- honour_sticky &&
- (st.st_uid == 0 || st.st_uid == getuid()) &&
- (st.st_mode & S_ISVTX);
- } else {
- is_dir = de->d_type == DT_DIR;
- keep_around = false;
- }
-
- if (is_dir) {
- int subdir_fd;
-
- /* if root_dev is set, remove subdirectories only, if device is same as dir */
- if (root_dev && st.st_dev != root_dev->st_dev)
- continue;
-
- subdir_fd = openat(fd, de->d_name,
- O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
- if (subdir_fd < 0) {
- if (ret == 0 && errno != ENOENT)
- ret = -errno;
- continue;
- }
-
- r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
- if (r < 0 && ret == 0)
- ret = r;
-
- if (!keep_around)
- if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
- if (ret == 0 && errno != ENOENT)
- ret = -errno;
- }
-
- } else if (!only_dirs && !keep_around) {
-
- if (unlinkat(fd, de->d_name, 0) < 0) {
- if (ret == 0 && errno != ENOENT)
- ret = -errno;
- }
- }
- }
-
- closedir(d);
-
- return ret;
-}
-
_pure_ static int is_temporary_fs(struct statfs *s) {
assert(s);
return
@@ -1467,97 +645,6 @@ _pure_ static int is_temporary_fs(struct statfs *s) {
F_TYPE_CMP(s->f_type, RAMFS_MAGIC);
}
-int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
- struct statfs s;
-
- assert(fd >= 0);
-
- if (fstatfs(fd, &s) < 0) {
- close_nointr_nofail(fd);
- return -errno;
- }
-
- /* We refuse to clean disk file systems with this call. This
- * is extra paranoia just to be sure we never ever remove
- * non-state data */
- if (!is_temporary_fs(&s)) {
- log_error("Attempted to remove disk file system, and we can't allow that.");
- close_nointr_nofail(fd);
- return -EPERM;
- }
-
- return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
-}
-
-static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
- int fd, r;
- struct statfs s;
-
- assert(path);
-
- /* We refuse to clean the root file system with this
- * call. This is extra paranoia to never cause a really
- * seriously broken system. */
- if (path_equal(path, "/")) {
- log_error("Attempted to remove entire root file system, and we can't allow that.");
- return -EPERM;
- }
-
- fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
- if (fd < 0) {
-
- if (errno != ENOTDIR)
- return -errno;
-
- if (!dangerous) {
- if (statfs(path, &s) < 0)
- return -errno;
-
- if (!is_temporary_fs(&s)) {
- log_error("Attempted to remove disk file system, and we can't allow that.");
- return -EPERM;
- }
- }
-
- if (delete_root && !only_dirs)
- if (unlink(path) < 0 && errno != ENOENT)
- return -errno;
-
- return 0;
- }
-
- if (!dangerous) {
- if (fstatfs(fd, &s) < 0) {
- close_nointr_nofail(fd);
- return -errno;
- }
-
- if (!is_temporary_fs(&s)) {
- log_error("Attempted to remove disk file system, and we can't allow that.");
- close_nointr_nofail(fd);
- return -EPERM;
- }
- }
-
- r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
- if (delete_root) {
-
- if (honour_sticky && file_is_priv_sticky(path) > 0)
- return r;
-
- if (rmdir(path) < 0 && errno != ENOENT) {
- if (r == 0)
- r = -errno;
- }
- }
-
- return r;
-}
-
-int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
- return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
-}
-
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
assert(path);
@@ -1576,219 +663,6 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
return 0;
}
-int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) {
- static const char status_indent[] = " "; /* "[" STATUS "] " */
- _cleanup_free_ char *s = NULL;
- _cleanup_close_ int fd = -1;
- struct iovec iovec[6] = {};
- int n = 0;
- static bool prev_ephemeral;
-
- assert(format);
-
- /* This is independent of logging, as status messages are
- * optional and go exclusively to the console. */
-
- if (vasprintf(&s, format, ap) < 0)
- return log_oom();
-
- fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- if (ellipse) {
- char *e;
- size_t emax, sl;
- int c;
-
- c = fd_columns(fd);
- if (c <= 0)
- c = 80;
-
- sl = status ? sizeof(status_indent)-1 : 0;
-
- emax = c - sl - 1;
- if (emax < 3)
- emax = 3;
-
- e = ellipsize(s, emax, 75);
- if (e) {
- free(s);
- s = e;
- }
- }
-
- if (prev_ephemeral)
- IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE);
- prev_ephemeral = ephemeral;
-
- if (status) {
- if (!isempty(status)) {
- IOVEC_SET_STRING(iovec[n++], "[");
- IOVEC_SET_STRING(iovec[n++], status);
- IOVEC_SET_STRING(iovec[n++], "] ");
- } else
- IOVEC_SET_STRING(iovec[n++], status_indent);
- }
-
- IOVEC_SET_STRING(iovec[n++], s);
- if (!ephemeral)
- IOVEC_SET_STRING(iovec[n++], "\n");
-
- if (writev(fd, iovec, n) < 0)
- return -errno;
-
- return 0;
-}
-
-int fd_columns(int fd) {
- struct winsize ws = {};
-
- if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
- return -errno;
-
- if (ws.ws_col <= 0)
- return -EIO;
-
- return ws.ws_col;
-}
-
-unsigned columns(void) {
- const char *e;
- int c;
-
- if (_likely_(cached_columns > 0))
- return cached_columns;
-
- c = 0;
- e = getenv("COLUMNS");
- if (e)
- safe_atoi(e, &c);
-
- if (c <= 0)
- c = fd_columns(STDOUT_FILENO);
-
- if (c <= 0)
- c = 80;
-
- cached_columns = c;
- return c;
-}
-
-int fd_lines(int fd) {
- struct winsize ws = {};
-
- if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
- return -errno;
-
- if (ws.ws_row <= 0)
- return -EIO;
-
- return ws.ws_row;
-}
-
-unsigned lines(void) {
- const char *e;
- unsigned l;
-
- if (_likely_(cached_lines > 0))
- return cached_lines;
-
- l = 0;
- e = getenv("LINES");
- if (e)
- safe_atou(e, &l);
-
- if (l <= 0)
- l = fd_lines(STDOUT_FILENO);
-
- if (l <= 0)
- l = 24;
-
- cached_lines = l;
- return cached_lines;
-}
-
-bool on_tty(void) {
- static int cached_on_tty = -1;
-
- if (_unlikely_(cached_on_tty < 0))
- cached_on_tty = isatty(STDOUT_FILENO) > 0;
-
- return cached_on_tty;
-}
-
-char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
- size_t x;
- char *r;
-
- assert(s);
- assert(percent <= 100);
- assert(new_length >= 3);
-
- if (old_length <= 3 || old_length <= new_length)
- return strndup(s, old_length);
-
- r = new0(char, new_length+1);
- if (!r)
- return r;
-
- x = (new_length * percent) / 100;
-
- if (x > new_length - 3)
- x = new_length - 3;
-
- memcpy(r, s, x);
- r[x] = '.';
- r[x+1] = '.';
- r[x+2] = '.';
- memcpy(r + x + 3,
- s + old_length - (new_length - x - 3),
- new_length - x - 3);
-
- return r;
-}
-
-char *ellipsize(const char *s, size_t length, unsigned percent) {
- return ellipsize_mem(s, strlen(s), length, percent);
-}
-
-int touch(const char *path) {
- int fd;
-
- assert(path);
-
- /* This just opens the file for writing, ensuring it
- * exists. It doesn't call utimensat() the way /usr/bin/touch
- * does it. */
-
- fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
- if (fd < 0)
- return -errno;
-
- close_nointr_nofail(fd);
- return 0;
-}
-
-char *unquote(const char *s, const char* quotes) {
- size_t l;
- assert(s);
-
- /* This is rather stupid, simply removes the heading and
- * trailing quotes if there is one. Doesn't care about
- * escaping or anything. We should make this smarter one
- * day...*/
-
- l = strlen(s);
- if (l < 2)
- return strdup(s);
-
- if (strchr(quotes, s[0]) && s[l-1] == s[0])
- return strndup(s+1, l-2);
-
- return strdup(s);
-}
-
bool null_or_empty(struct stat *st) {
assert(st);
@@ -1812,76 +686,6 @@ int null_or_empty_path(const char *fn) {
return null_or_empty(&st);
}
-bool tty_is_vc(const char *tty) {
- assert(tty);
-
- if (startswith(tty, "/dev/"))
- tty += 5;
-
- return vtnr_from_tty(tty) >= 0;
-}
-
-int vtnr_from_tty(const char *tty) {
- int i, r;
-
- assert(tty);
-
- if (startswith(tty, "/dev/"))
- tty += 5;
-
- if (!startswith(tty, "tty") )
- return -EINVAL;
-
- if (tty[3] < '0' || tty[3] > '9')
- return -EINVAL;
-
- r = safe_atoi(tty+3, &i);
- if (r < 0)
- return r;
-
- if (i < 0 || i > 63)
- return -EINVAL;
-
- return i;
-}
-
-char *resolve_dev_console(char **active) {
- char *tty;
-
- /* Resolve where /dev/console is pointing to, if /sys is actually ours
- * (i.e. not read-only-mounted which is a sign for container setups) */
-
- if (path_is_read_only_fs("/sys") > 0)
- return NULL;
-
- if (read_one_line_file("/sys/class/tty/console/active", active) < 0)
- return NULL;
-
- /* If multiple log outputs are configured the last one is what
- * /dev/console points to */
- tty = strrchr(*active, ' ');
- if (tty)
- tty++;
- else
- tty = *active;
-
- return tty;
-}
-
-bool dirent_is_file(const struct dirent *de) {
- assert(de);
-
- if (ignore_file(de->d_name))
- return false;
-
- if (de->d_type != DT_REG &&
- de->d_type != DT_LNK &&
- de->d_type != DT_UNKNOWN)
- return false;
-
- return true;
-}
-
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
assert(de);
@@ -1936,23 +740,6 @@ int execute_command(const char *command, char *const argv[])
}
}
-int fd_wait_for_event(int fd, int event, usec_t t) {
- int r;
- struct pollfd pollfd = {
- .fd = fd,
- .events = event,
- };
-
- r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
- if (r < 0)
- return -errno;
-
- if (r == 0)
- return 0;
-
- return pollfd.revents;
-}
-
int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
FILE *f;
char *t;
@@ -1998,28 +785,6 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
return 0;
}
-int terminal_vhangup_fd(int fd) {
- assert(fd >= 0);
-
- if (ioctl(fd, TIOCVHANGUP) < 0)
- return -errno;
-
- return 0;
-}
-
-int terminal_vhangup(const char *name) {
- int fd, r;
-
- fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- r = terminal_vhangup_fd(fd);
- close_nointr_nofail(fd);
-
- return r;
-}
-
char *strjoin(const char *x, ...) {
va_list ap;
size_t l;
@@ -2086,19 +851,6 @@ bool is_main_thread(void) {
return cached > 0;
}
-int file_is_priv_sticky(const char *p) {
- struct stat st;
-
- assert(p);
-
- if (lstat(p, &st) < 0)
- return -errno;
-
- return
- (st.st_uid == 0 || st.st_uid == getuid()) &&
- (st.st_mode & S_ISVTX);
-}
-
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
@@ -2251,40 +1003,6 @@ const char *signal_to_string(int signo) {
return buf;
}
-int signal_from_string(const char *s) {
- int signo;
- int offset = 0;
- unsigned u;
-
- signo = __signal_from_string(s);
- if (signo > 0)
- return signo;
-
- if (startswith(s, "RTMIN+")) {
- s += 6;
- offset = SIGRTMIN;
- }
- if (safe_atou(s, &u) >= 0) {
- signo = (int) u + offset;
- if (signo > 0 && signo < _NSIG)
- return signo;
- }
- return -1;
-}
-
-void* memdup(const void *p, size_t l) {
- void *r;
-
- assert(p);
-
- r = malloc(l);
- if (!r)
- return NULL;
-
- memcpy(r, p, l);
- return r;
-}
-
int fd_inc_sndbuf(int fd, size_t n) {
int r, value;
socklen_t l = sizeof(value);
diff --git a/src/libudev/util.h b/src/libudev/util.h
index 0920082613..80a0c436ad 100644
--- a/src/libudev/util.h
+++ b/src/libudev/util.h
@@ -145,9 +145,6 @@ char *startswith(const char *s, const char *prefix) _pure_;
int close_nointr(int fd);
void close_nointr_nofail(int fd);
-int parse_uid(const char *s, uid_t* ret_uid);
-#define parse_gid(s, ret_uid) parse_uid(s, ret_uid)
-
int safe_atou(const char *s, unsigned *ret_u);
int safe_atoi(const char *s, int *ret_i);
@@ -208,30 +205,19 @@ char *split_quoted(const char *c, size_t *l, char **state);
int write_one_line_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);
char *strappend(const char *s, const char *suffix);
char *strnappend(const char *s, const char *suffix, size_t length);
int readlink_malloc(const char *p, char **r);
-char *strstrip(char *s);
char *truncate_nl(char *s);
-char *file_in_same_dir(const char *path, const char *filename);
-
char hexchar(int x) _const_;
int unhexchar(char c) _const_;
char octchar(int x) _const_;
int unoctchar(char c) _const_;
-char *cunescape(const char *s);
-char *cunescape_length(const char *s, size_t length);
-char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix);
-
-char *xescape(const char *s, const char *bad);
-
-bool dirent_is_file(const struct dirent *de) _pure_;
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
bool ignore_file(const char *filename) _pure_;
@@ -292,65 +278,21 @@ char *format_timespan(char *buf, size_t l, usec_t t);
} \
struct __useless_struct_to_allow_trailing_semicolon__
-int close_all_fds(const int except[], unsigned n_except);
-
-int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
-int ask(char *ret, const char *replies, const char *text, ...) _printf_attr_(3, 4);
-
-int reset_terminal_fd(int fd, bool switch_to_text);
-int reset_terminal(const char *name);
-
int open_terminal(const char *name, int mode);
-int flush_fd(int fd);
-
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
-ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
-
-int get_ctty_devnr(pid_t pid, dev_t *d);
-int get_ctty(pid_t, dev_t *_devnr, char **r);
-
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
-int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
-int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
-int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
-
-int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) _printf_attr_(4,0);
-
-int fd_columns(int fd);
-unsigned columns(void);
-int fd_lines(int fd);
-unsigned lines(void);
-
-bool on_tty(void);
-
-char *ellipsize(const char *s, size_t length, unsigned percent);
-char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent);
-
-int touch(const char *path);
-
-char *unquote(const char *s, const char *quotes);
-
bool null_or_empty(struct stat *st) _pure_;
int null_or_empty_path(const char *fn);
-char *resolve_dev_console(char **active);
-bool tty_is_vc(const char *tty);
-int vtnr_from_tty(const char *tty);
-
int execute_command(const char *command, char *const argv[]);
-int terminal_vhangup_fd(int fd);
-int terminal_vhangup(const char *name);
-
char *strjoin(const char *x, ...) _sentinel_;
bool is_main_thread(void);
-int file_is_priv_sticky(const char *p);
-
#define NULSTR_FOREACH(i, l) \
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
@@ -379,15 +321,10 @@ int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
const char *signal_to_string(int i) _const_;
-int signal_from_string(const char *s) _pure_;
extern int saved_argc;
extern char **saved_argv;
-int fd_wait_for_event(int fd, int event, usec_t timeout);
-
-void* memdup(const void *p, size_t l) _alloc_(2);
-
int fd_inc_sndbuf(int fd, size_t n);
bool in_initrd(void);
@@ -435,13 +372,6 @@ _malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b)
return malloc(a * b);
}
-_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
- if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
- return NULL;
-
- return memdup(p, a * b);
-}
-
void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar) (const void *, const void *, void *),
void *arg);