util, pasta: Don't read() and lseek() every single line in read_line()

...periodically checking bound ports becomes quite expensive
otherwise.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
Stefano Brivio 2021-10-15 22:39:17 +02:00
parent 14fe73e766
commit 1fd0c9b0e1
2 changed files with 24 additions and 5 deletions

2
conf.c
View file

@ -293,7 +293,7 @@ static void get_dns(struct ctx *c)
if ((fd = open("/etc/resolv.conf", O_RDONLY)) < 0) if ((fd = open("/etc/resolv.conf", O_RDONLY)) < 0)
goto out; goto out;
while (line_read(buf, BUFSIZ, fd)) { while (!(*buf = 0) && line_read(buf, BUFSIZ, fd)) {
if (!dns_set && strstr(buf, "nameserver ") == buf) { if (!dns_set && strstr(buf, "nameserver ") == buf) {
p = strrchr(buf, ' '); p = strrchr(buf, ' ');
if (!p) if (!p)

27
util.c
View file

@ -368,8 +368,8 @@ int bitmap_isset(uint8_t *map, int bit)
} }
/** /**
* line_read() - Same as fgets(), without using heap, a file instead of a stream * line_read() - Similar to fgets(), no heap usage, a file instead of a stream
* @buf: Read buffer * @buf: Read buffer: on non-empty string, use that instead of reading
* @len: Maximum line length * @len: Maximum line length
* @fd: File descriptor for reading * @fd: File descriptor for reading
* *
@ -377,14 +377,31 @@ int bitmap_isset(uint8_t *map, int bit)
*/ */
char *line_read(char *buf, size_t len, int fd) char *line_read(char *buf, size_t len, int fd)
{ {
int n, do_read = !*buf;
char *p; char *p;
int n;
if (!do_read) {
char *nl;
buf[len - 1] = 0;
if (!strlen(buf))
return NULL;
p = buf + strlen(buf) + 1;
if (!(nl = strchr(p, '\n')))
return NULL;
*nl = 0;
return memmove(buf, p, len - (p - buf));
}
n = read(fd, buf, --len); n = read(fd, buf, --len);
if (n <= 0) if (n <= 0)
return NULL; return NULL;
buf[len] = 0; buf[len] = 0;
if (!(p = strchr(buf, '\n'))) if (!(p = strchr(buf, '\n')))
return buf; return buf;
@ -393,6 +410,7 @@ char *line_read(char *buf, size_t len, int fd)
return buf; return buf;
lseek(fd, (p - buf) - n + 1, SEEK_CUR); lseek(fd, (p - buf) - n + 1, SEEK_CUR);
return buf; return buf;
} }
@ -404,7 +422,7 @@ char *line_read(char *buf, size_t len, int fd)
*/ */
void procfs_scan_listen(char *name, uint8_t *map, uint8_t *exclude) void procfs_scan_listen(char *name, uint8_t *map, uint8_t *exclude)
{ {
char line[200], path[PATH_MAX]; char line[BUFSIZ], path[PATH_MAX];
unsigned long port; unsigned long port;
unsigned int state; unsigned int state;
int fd; int fd;
@ -413,6 +431,7 @@ void procfs_scan_listen(char *name, uint8_t *map, uint8_t *exclude)
if ((fd = open(path, O_RDONLY)) < 0) if ((fd = open(path, O_RDONLY)) < 0)
return; return;
*line = 0;
line_read(line, sizeof(line), fd); line_read(line, sizeof(line), fd);
while (line_read(line, sizeof(line), fd)) { while (line_read(line, sizeof(line), fd)) {
if (sscanf(line, "%*u: %*x:%lx %*x:%*x %x", &port, &state) != 2) if (sscanf(line, "%*u: %*x:%lx %*x:%*x %x", &port, &state) != 2)