1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-12 09:17:44 +03:00

Merge pull request #10447 from poettering/fgets-excorcism

let's get rid of fgets()
This commit is contained in:
Yu Watanabe 2018-10-19 08:36:01 +09:00 committed by GitHub
commit 218b4609d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 202 additions and 125 deletions

View File

@ -10,8 +10,11 @@
#include <sys/ioctl.h>
#include <sys/time.h>
#include "alloc-util.h"
#include "clock-util.h"
#include "def.h"
#include "fd-util.h"
#include "fileio.h"
#include "macro.h"
#include "string-util.h"
#include "util.h"
@ -54,6 +57,7 @@ int clock_set_hwclock(const struct tm *tm) {
int clock_is_localtime(const char* adjtime_path) {
_cleanup_fclose_ FILE *f;
int r;
if (!adjtime_path)
adjtime_path = "/etc/adjtime";
@ -67,24 +71,30 @@ int clock_is_localtime(const char* adjtime_path) {
*/
f = fopen(adjtime_path, "re");
if (f) {
char line[LINE_MAX];
bool b;
_cleanup_free_ char *line = NULL;
unsigned i;
b = fgets(line, sizeof(line), f) &&
fgets(line, sizeof(line), f) &&
fgets(line, sizeof(line), f);
if (!b)
/* less than three lines -> default to UTC */
return 0;
for (i = 0; i < 2; i++) { /* skip the first two lines */
r = read_line(f, LONG_LINE_MAX, NULL);
if (r < 0)
return r;
if (r == 0)
return false; /* less than three lines → default to UTC */
}
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return r;
if (r == 0)
return false; /* less than three lines → default to UTC */
truncate_nl(line);
return streq(line, "LOCAL");
} else if (errno != ENOENT)
return -errno;
/* adjtime not present -> default to UTC */
return 0;
/* adjtime not present default to UTC */
return false;
}
int clock_set_timezone(int *min) {

View File

@ -81,35 +81,42 @@ int chvt(int vt) {
}
int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
struct termios old_termios, new_termios;
char c, line[LINE_MAX];
_cleanup_free_ char *line = NULL;
struct termios old_termios;
int r;
assert(f);
assert(ret);
/* If this is a terminal, then switch canonical mode off, so that we can read a single character */
if (tcgetattr(fileno(f), &old_termios) >= 0) {
new_termios = old_termios;
struct termios 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;
int c;
if (t != USEC_INFINITY) {
if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
tcsetattr(fileno(f), TCSADRAIN, &old_termios);
(void) tcsetattr(fileno(f), TCSADRAIN, &old_termios);
return -ETIMEDOUT;
}
}
k = fread(&c, 1, 1, f);
errno = 0;
c = fgetc(f);
if (c == EOF)
r = ferror(f) && errno > 0 ? -errno : -EIO;
else
r = 0;
tcsetattr(fileno(f), TCSADRAIN, &old_termios);
(void) tcsetattr(fileno(f), TCSADRAIN, &old_termios);
if (k <= 0)
return -EIO;
if (r < 0)
return r;
if (need_nl)
*need_nl = c != '\n';
@ -124,11 +131,13 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
return -ETIMEDOUT;
}
errno = 0;
if (!fgets(line, sizeof(line), f))
return errno > 0 ? -errno : -EIO;
/* If this is not a terminal, then read a full line instead */
truncate_nl(line);
r = read_line(f, 16, &line); /* longer than necessary, to eat up UTF-8 chars/vt100 key sequences */
if (r < 0)
return r;
if (r == 0)
return -EIO;
if (strlen(line) != 1)
return -EBADMSG;
@ -196,11 +205,13 @@ int ask_char(char *ret, const char *replies, const char *fmt, ...) {
}
int ask_string(char **ret, const char *text, ...) {
int r;
assert(ret);
assert(text);
for (;;) {
char line[LINE_MAX];
_cleanup_free_ char *line = NULL;
va_list ap;
if (colors_enabled())
@ -215,24 +226,14 @@ int ask_string(char **ret, const char *text, ...) {
fflush(stdout);
errno = 0;
if (!fgets(line, sizeof(line), stdin))
return errno > 0 ? -errno : -EIO;
r = read_line(stdin, LONG_LINE_MAX, &line);
if (r < 0)
return r;
if (r == 0)
return -EIO;
if (!endswith(line, "\n"))
putchar('\n');
else {
char *s;
if (isempty(line))
continue;
truncate_nl(line);
s = strdup(line);
if (!s)
return -ENOMEM;
*ret = s;
if (!isempty(line)) {
*ret = TAKE_PTR(line);
return 0;
}
}

View File

@ -15,6 +15,7 @@
#include "fileio.h"
#include "log.h"
#include "pager.h"
#include "path-util.h"
#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"
@ -27,6 +28,7 @@ static int delete_rule(const char *rule) {
_cleanup_free_ char *x = NULL, *fn = NULL;
char *e;
assert(rule);
assert(rule[0]);
x = strdup(rule);
@ -36,6 +38,11 @@ static int delete_rule(const char *rule) {
e = strchrnul(x+1, x[0]);
*e = 0;
if (!filename_is_valid(x + 1)) {
log_error("Rule file name '%s' is not valid, refusing.", x+1);
return -EINVAL;
}
fn = strappend("/proc/sys/fs/binfmt_misc/", x+1);
if (!fn)
return log_oom();
@ -46,7 +53,7 @@ static int delete_rule(const char *rule) {
static int apply_rule(const char *rule) {
int r;
delete_rule(rule);
(void) delete_rule(rule);
r = write_string_file("/proc/sys/fs/binfmt_misc/register", rule, 0);
if (r < 0)
@ -66,25 +73,25 @@ static int apply_file(const char *path, bool ignore_enoent) {
if (ignore_enoent && r == -ENOENT)
return 0;
return log_error_errno(r, "Failed to open file '%s', ignoring: %m", path);
return log_error_errno(r, "Failed to open file '%s': %m", path);
}
log_debug("apply: %s", path);
for (;;) {
char l[LINE_MAX], *p;
_cleanup_free_ char *line = NULL;
char *p;
int k;
if (!fgets(l, sizeof(l), f)) {
if (feof(f))
break;
k = read_line(f, LONG_LINE_MAX, &line);
if (k < 0)
return log_error_errno(k, "Failed to read file '%s': %m", path);
if (k == 0)
break;
return log_error_errno(errno, "Failed to read file '%s', ignoring: %m", path);
}
p = strstrip(l);
if (!*p)
p = strstrip(line);
if (isempty(p))
continue;
if (strchr(COMMENTS "\n", *p))
if (strchr(COMMENTS, p[0]))
continue;
k = apply_rule(p);

View File

@ -343,10 +343,14 @@ static int process(
}
for (;;) {
char line[LINE_MAX], *l;
_cleanup_free_ char *line = NULL;
uint64_t k, *q;
char *l;
if (!fgets(line, sizeof(line), f))
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return r;
if (r == 0)
break;
/* Trim and skip the device */

View File

@ -4,6 +4,7 @@
#include <stdio_ext.h>
#include "alloc-util.h"
#include "def.h"
#include "dropin.h"
#include "fd-util.h"
#include "fileio.h"
@ -443,9 +444,10 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
}
static int add_crypttab_devices(void) {
struct stat st;
unsigned crypttab_line = 0;
_cleanup_fclose_ FILE *f = NULL;
unsigned crypttab_line = 0;
struct stat st;
int r;
if (!arg_read_crypttab)
return 0;
@ -465,18 +467,21 @@ static int add_crypttab_devices(void) {
}
for (;;) {
int r, k;
char line[LINE_MAX], *l, *uuid;
_cleanup_free_ char *line = NULL, *name = NULL, *device = NULL, *keyfile = NULL, *options = NULL;
crypto_device *d = NULL;
_cleanup_free_ char *name = NULL, *device = NULL, *keyfile = NULL, *options = NULL;
char *l, *uuid;
int k;
if (!fgets(line, sizeof(line), f))
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return log_error_errno(r, "Failed to read /etc/crypttab: %m");
if (r == 0)
break;
crypttab_line++;
l = strstrip(line);
if (IN_SET(*l, 0, '#'))
if (IN_SET(l[0], 0, '#'))
continue;
k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &keyfile, &options);

View File

@ -13,6 +13,7 @@
#include "alloc-util.h"
#include "catalog.h"
#include "conf-files.h"
#include "def.h"
#include "fd-util.h"
#include "fileio.h"
#include "hashmap.h"
@ -267,26 +268,23 @@ int catalog_import_file(Hashmap *h, const char *path) {
log_debug("File %s has language %s.", path, deflang);
for (;;) {
char line[LINE_MAX];
_cleanup_free_ char *line = NULL;
size_t line_len;
if (!fgets(line, sizeof(line), f)) {
if (feof(f))
break;
return log_error_errno(errno, "Failed to read file %s: %m", path);
}
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return log_error_errno(r, "Failed to read file %s: %m", path);
if (r == 0)
break;
n++;
truncate_nl(line);
if (line[0] == 0) {
if (isempty(line)) {
empty_line = true;
continue;
}
if (strchr(COMMENTS "\n", line[0]))
if (strchr(COMMENTS, line[0]))
continue;
if (empty_line &&

View File

@ -5,6 +5,7 @@
#include "alloc-util.h"
#include "conf-files.h"
#include "def.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
@ -472,7 +473,6 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
HW_DATA,
} state = HW_NONE;
_cleanup_fclose_ FILE *f = NULL;
char line[LINE_MAX];
_cleanup_strv_free_ char **match_list = NULL;
uint32_t line_number = 0;
char *match = NULL;
@ -482,10 +482,17 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr
if (!f)
return -errno;
while (fgets(line, sizeof(line), f)) {
for (;;) {
_cleanup_free_ char *line = NULL;
size_t len;
char *pos;
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return r;
if (r == 0)
break;
++line_number;
/* comment line */

View File

@ -199,7 +199,6 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
int x11_read_data(Context *c, sd_bus_message *m) {
_cleanup_fclose_ FILE *f = NULL;
bool in_section = false;
char line[LINE_MAX];
struct stat st;
usec_t t;
int r;
@ -234,12 +233,17 @@ int x11_read_data(Context *c, sd_bus_message *m) {
if (!f)
return -errno;
while (fgets(line, sizeof(line), f)) {
for (;;) {
_cleanup_free_ char *line = NULL;
char *l;
char_array_0(line);
l = strstrip(line);
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return r;
if (r == 0)
break;
l = strstrip(line);
if (IN_SET(l[0], 0, '#'))
continue;
@ -470,19 +474,16 @@ static int read_next_mapping(const char* filename,
assert(a);
for (;;) {
char line[LINE_MAX];
_cleanup_free_ char *line = NULL;
size_t length;
char *l, **b;
int r;
size_t length;
errno = 0;
if (!fgets(line, sizeof(line), f)) {
if (ferror(f))
return errno > 0 ? -errno : -EIO;
return 0;
}
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return r;
if (r == 0)
break;
(*n)++;
@ -505,6 +506,8 @@ static int read_next_mapping(const char* filename,
*a = b;
return 1;
}
return 0;
}
int vconsole_convert_to_x11(Context *c) {

View File

@ -72,25 +72,25 @@ static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent
if (ignore_enoent && r == -ENOENT)
return 0;
return log_error_errno(r, "Failed to open %s, ignoring: %m", path);
return log_error_errno(r, "Failed to open %s: %m", path);
}
log_debug("apply: %s", path);
for (;;) {
char line[LINE_MAX], *l;
_cleanup_free_ char *line = NULL;
char *l;
int k;
if (!fgets(line, sizeof(line), f)) {
if (feof(f))
break;
return log_error_errno(errno, "Failed to read file '%s', ignoring: %m", path);
}
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return log_error_errno(errno, "Failed to read file '%s': %m", path);
if (r == 0)
break;
l = strstrip(line);
if (!*l)
if (isempty(l))
continue;
if (strchr(COMMENTS "\n", *l))
if (strchr(COMMENTS, *l))
continue;
k = module_load_and_warn(ctx, l, true);

View File

@ -6,7 +6,10 @@
#include <sys/socket.h>
#include <sys/un.h>
#include "alloc-util.h"
#include "def.h"
#include "fd-util.h"
#include "fileio.h"
#include "log.h"
#include "macro.h"
#include "socket-util.h"
@ -32,8 +35,8 @@ static int send_on_socket(int fd, const char *socket_name, const void *packet, s
}
int main(int argc, char *argv[]) {
_cleanup_free_ char *packet = NULL;
_cleanup_close_ int fd = -1;
char packet[LINE_MAX];
size_t length;
int r;
@ -47,18 +50,36 @@ int main(int argc, char *argv[]) {
}
if (streq(argv[1], "1")) {
_cleanup_string_free_erase_ char *line = NULL;
packet[0] = '+';
if (!fgets(packet+1, sizeof(packet)-1, stdin)) {
r = log_error_errno(errno, "Failed to read password: %m");
r = read_line(stdin, LONG_LINE_MAX, &line);
if (r < 0) {
log_error_errno(r, "Failed to read password: %m");
goto finish;
}
if (r == 0) {
log_error("Got EOF while reading password.");
r = -EIO;
goto finish;
}
truncate_nl(packet+1);
length = 1 + strlen(packet+1) + 1;
packet = strjoin("+", line);
if (!packet) {
r = log_oom();
goto finish;
}
length = 1 + strlen(line) + 1;
} else if (streq(argv[1], "0")) {
packet[0] = '-';
packet = strdup("-");
if (!packet) {
r = log_oom();
goto finish;
}
length = 1;
} else {
log_error("Invalid first argument %s", argv[1]);
r = -EINVAL;
@ -74,7 +95,7 @@ int main(int argc, char *argv[]) {
r = send_on_socket(fd, argv[2], packet, length);
finish:
explicit_bzero(packet, sizeof(packet));
explicit_bzero(packet, length);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

View File

@ -384,10 +384,9 @@ static int condition_test_security(Condition *c) {
}
static int condition_test_capability(Condition *c) {
unsigned long long capabilities = (unsigned long long) -1;
_cleanup_fclose_ FILE *f = NULL;
int value;
char line[LINE_MAX];
unsigned long long capabilities = -1;
int value, r;
assert(c);
assert(c->parameter);
@ -405,11 +404,21 @@ static int condition_test_capability(Condition *c) {
if (!f)
return -errno;
while (fgets(line, sizeof(line), f)) {
truncate_nl(line);
for (;;) {
_cleanup_free_ char *line = NULL;
const char *p;
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return r;
if (r == 0)
break;
p = startswith(line, "CapBnd:");
if (p) {
if (sscanf(line+7, "%llx", &capabilities) != 1)
return -EIO;
if (startswith(line, "CapBnd:")) {
(void) sscanf(line+7, "%llx", &capabilities);
break;
}
}

View File

@ -15,9 +15,11 @@
#include "alloc-util.h"
#include "conf-files.h"
#include "def.h"
#include "dirent-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "glob-util.h"
#include "path-util.h"
@ -613,15 +615,25 @@ static int import_property_from_string(struct udev_device *dev, char *line) {
}
static int import_file_into_properties(struct udev_device *dev, const char *filename) {
FILE *f;
char line[UTIL_LINE_SIZE];
_cleanup_fclose_ FILE *f = NULL;
int r;
f = fopen(filename, "re");
if (f == NULL)
return -1;
while (fgets(line, sizeof(line), f) != NULL)
import_property_from_string(dev, line);
fclose(f);
if (!f)
return -errno;
for (;;) {
_cleanup_free_ char *line = NULL;
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return r;
if (r == 0)
break;
(void) import_property_from_string(dev, line);
}
return 0;
}
@ -646,7 +658,7 @@ static int import_program_into_properties(struct udev_event *event,
pos[0] = '\0';
pos = &pos[1];
}
import_property_from_string(event->dev, line);
(void) import_property_from_string(event->dev, line);
line = pos;
}
return 0;
@ -1431,8 +1443,8 @@ static int parse_file(struct udev_rules *rules, const char *filename) {
if (!f) {
if (errno == ENOENT)
return 0;
else
return -errno;
return -errno;
}
if (null_or_empty_fd(fileno(f))) {