assert(fn);
assert(line);
- if (!(f = fopen(fn, "re")))
+ f = fopen(fn, "re");
+ if (!f)
return -errno;
- if (!(fgets(t, sizeof(t), f))) {
- r = feof(f) ? -EIO : -errno;
- goto finish;
+ if (!fgets(t, sizeof(t), f)) {
+
+ if (ferror(f)) {
+ r = -errno;
+ goto finish;
+ }
+
+ t[0] = 0;
}
- if (!(c = strdup(t))) {
+ c = strdup(t);
+ if (!c) {
r = -ENOMEM;
goto finish;
}
char ***rl) {
FILE *f;
- char **m = 0;
+ char **m = NULL;
int r;
assert(fname);
/* Undoes C style string escaping */
- if (!(r = new(char, length+1)))
+ r = new(char, length+1);
+ if (!r)
return r;
for (f = s, t = r; f < s + length; f++) {
/* hexadecimal encoding */
int a, b;
- if ((a = unhexchar(f[1])) < 0 ||
- (b = unhexchar(f[2])) < 0) {
+ 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';
/* octal encoding */
int a, b, c;
- if ((a = unoctchar(f[0])) < 0 ||
- (b = unoctchar(f[1])) < 0 ||
- (c = unoctchar(f[2])) < 0) {
+ 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];
return 0;
}
+static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
+ unsigned i;
+
+ assert(n_fdset == 0 || fdset);
+
+ for (i = 0; i < n_fdset; i++)
+ if (fdset[i] == fd)
+ return true;
+
+ return false;
+}
+
int close_all_fds(const int except[], unsigned n_except) {
DIR *d;
struct dirent *de;
int r = 0;
- if (!(d = opendir("/proc/self/fd")))
- return -errno;
+ 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 (fd == dirfd(d))
continue;
- if (except) {
- bool found;
- unsigned i;
-
- found = false;
- for (i = 0; i < n_except; i++)
- if (except[i] == fd) {
- found = true;
- break;
- }
-
- if (found)
- 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 */
log_warning("Failed to read /etc/os-release: %s", strerror(-r));
}
-#if defined(TARGET_FEDORA)
- if (!pretty_name) {
- if ((r = read_one_line_file("/etc/system-release", &pretty_name)) < 0) {
-
- if (r != -ENOENT)
- log_warning("Failed to read /etc/system-release: %s", strerror(-r));
- }
- }
-
- if (!ansi_color && pretty_name) {
-
- /* This tries to mimic the color magic the old Red Hat sysinit
- * script did. */
-
- if (startswith(pretty_name, "Red Hat"))
- const_color = "0;31"; /* Red for RHEL */
- else if (startswith(pretty_name, "Fedora"))
- const_color = "0;34"; /* Blue for Fedora */
- }
-
-#elif defined(TARGET_SUSE)
-
- if (!pretty_name) {
- if ((r = read_one_line_file("/etc/SuSE-release", &pretty_name)) < 0) {
-
- if (r != -ENOENT)
- log_warning("Failed to read /etc/SuSE-release: %s", strerror(-r));
- }
- }
-
- if (!ansi_color)
- const_color = "0;32"; /* Green for openSUSE */
-
-#elif defined(TARGET_GENTOO)
-
- if (!pretty_name) {
- if ((r = read_one_line_file("/etc/gentoo-release", &pretty_name)) < 0) {
-
- if (r != -ENOENT)
- log_warning("Failed to read /etc/gentoo-release: %s", strerror(-r));
- }
- }
-
- if (!ansi_color)
- const_color = "1;34"; /* Light Blue for Gentoo */
-
-#elif defined(TARGET_ALTLINUX)
-
- if (!pretty_name) {
- if ((r = read_one_line_file("/etc/altlinux-release", &pretty_name)) < 0) {
-
- if (r != -ENOENT)
- log_warning("Failed to read /etc/altlinux-release: %s", strerror(-r));
- }
- }
-
- if (!ansi_color)
- const_color = "0;36"; /* Cyan for ALTLinux */
-
-
-#elif defined(TARGET_DEBIAN)
-
- if (!pretty_name) {
- char *version;
-
- if ((r = read_one_line_file("/etc/debian_version", &version)) < 0) {
-
- if (r != -ENOENT)
- log_warning("Failed to read /etc/debian_version: %s", strerror(-r));
- } else {
- pretty_name = strappend("Debian ", version);
- free(version);
-
- if (!pretty_name)
- log_warning("Failed to allocate Debian version string.");
- }
- }
-
- if (!ansi_color)
- const_color = "1;31"; /* Light Red for Debian */
-
-#elif defined(TARGET_UBUNTU)
-
- if ((r = parse_env_file("/etc/lsb-release", NEWLINE,
- "DISTRIB_DESCRIPTION", &pretty_name,
- NULL)) < 0) {
-
- if (r != -ENOENT)
- log_warning("Failed to read /etc/lsb-release: %s", strerror(-r));
- }
-
- if (!ansi_color)
- const_color = "0;33"; /* Orange/Brown for Ubuntu */
-
-#elif defined(TARGET_MANDRIVA)
-
- if (!pretty_name) {
- char *s, *p;
-
- if ((r = read_one_line_file("/etc/mandriva-release", &s) < 0)) {
- if (r != -ENOENT)
- log_warning("Failed to read /etc/mandriva-release: %s", strerror(-r));
- } else {
- p = strstr(s, " release ");
- if (p) {
- *p = '\0';
- p += 9;
- p[strcspn(p, " ")] = '\0';
-
- /* This corresponds to standard rc.sysinit */
- if (asprintf(&pretty_name, "%s\x1B[0;39m %s", s, p) > 0)
- const_color = "1;36";
- else
- log_warning("Failed to allocate Mandriva version string.");
- } else
- log_warning("Failed to parse /etc/mandriva-release");
- free(s);
- }
- }
-#elif defined(TARGET_MEEGO)
-
- if (!pretty_name) {
- if ((r = read_one_line_file("/etc/meego-release", &pretty_name)) < 0) {
-
- if (r != -ENOENT)
- log_warning("Failed to read /etc/meego-release: %s", strerror(-r));
- }
- }
-
- if (!ansi_color)
- const_color = "1;35"; /* Bright Magenta for MeeGo */
-#endif
-
if (!pretty_name && !const_pretty)
const_pretty = "Linux";
}
-void freeze(void) {
+_noreturn_ void freeze(void) {
/* Make sure nobody waits for us on a socket anymore */
close_all_fds(NULL, 0);