diff --git a/src/kill_all/kill_all.c b/src/kill_all/kill_all.c index 039c7352e..e4279bee4 100644 --- a/src/kill_all/kill_all.c +++ b/src/kill_all/kill_all.c @@ -115,7 +115,7 @@ static bool is_user_process(pid_t pid) temp_pid = -1; while (!feof(fp)) { buf = NULL; - if (getline(&buf, &size, fp) != -1) { + if (xgetline(&buf, &size, fp) != -1) { sscanf(buf, "PPid: %d", &temp_pid); free(buf); } else { diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c index e23593b9a..90e9c1649 100644 --- a/src/librc/librc-daemon.c +++ b/src/librc/librc-daemon.c @@ -140,8 +140,7 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) if (exists("/proc/self/status")) { fp = fopen("/proc/self/status", "r"); if (fp) { - while (!feof(fp)) { - rc_getline(&line, &len, fp); + while (xgetline(&line, &len, fp) != -1) { if (strncmp(line, "envID:\t0", 8) == 0) { openvz_host = true; break; @@ -196,8 +195,7 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) free(buffer); if (!fp) continue; - while (!feof(fp)) { - rc_getline(&line, &len, fp); + while (xgetline(&line, &len, fp) != -1) { if (strncmp(line, "envID:", 6) == 0) { container_pid = !(strncmp(line, "envID:\t0", 8) == 0); break; @@ -346,7 +344,7 @@ _match_daemon(const char *path, const char *file, RC_STRINGLIST *match) if (!fp) return false; - while ((rc_getline(&line, &len, fp))) { + while (xgetline(&line, &len, fp) != -1) { TAILQ_FOREACH(m, match, entries) if (strcmp(line, m->value) == 0) { TAILQ_REMOVE(match, m, entries); @@ -559,7 +557,7 @@ rc_service_daemons_crashed(const char *service) if (!fp) break; - while ((rc_getline(&line, &len, fp))) { + while (xgetline(&line, &len, fp) != -1) { p = line; if ((token = strsep(&p, "=")) == NULL || !p) continue; diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c index a48a2ada0..9dc3d5ec0 100644 --- a/src/librc/librc-depend.c +++ b/src/librc/librc-depend.c @@ -160,8 +160,7 @@ rc_deptree_load_file(const char *deptree_file) RC_DEPINFO *depinfo = NULL; RC_DEPTYPE *deptype = NULL; char *line = NULL; - size_t len = 0; - ssize_t size; + size_t size; char *type; char *p; char *e; @@ -171,8 +170,7 @@ rc_deptree_load_file(const char *deptree_file) return NULL; deptree = make_deptree(); - while ((size = getline(&line, &len, fp)) != -1) { - line[size - 1] = '\0'; + while (xgetline(&line, &size, fp) != -1) { p = line; e = strsep(&p, "_"); if (!e || strcmp(e, "depinfo") != 0) @@ -788,8 +786,7 @@ rc_deptree_update(void) RC_STRINGLIST *config, *dupes, *types, *sorted, *visited; RC_STRING *s, *s2, *s2_np, *s3, *s4; char *line = NULL; - size_t len = 0; - ssize_t size; + size_t size; char *depend, *depends, *service, *type; size_t i, l; bool retval = true; @@ -811,8 +808,7 @@ rc_deptree_update(void) config = rc_stringlist_new(); deptree = make_deptree(); - while ((size = getline(&line, &len, fp)) != -1) { - line[size - 1] = '\0'; + while (xgetline(&line, &size, fp) != -1) { depends = line; service = strsep(&depends, " "); if (!service || !*service) @@ -894,8 +890,8 @@ rc_deptree_update(void) * work for them. This doesn't stop them from being run directly. */ if (sys) { char *nosys, *onosys; + size_t len = strlen(sys); - len = strlen(sys); nosys = xmalloc(len + 2); nosys[0] = '-'; for (i = 0; i < len; i++) diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c index 6c0fcbe73..846280fc4 100644 --- a/src/librc/librc-misc.c +++ b/src/librc/librc-misc.c @@ -133,7 +133,6 @@ rc_proc_getent(const char *ent RC_UNUSED) FILE *fp; char *proc = NULL, *p, *value = NULL, *save; size_t i, len; - ssize_t size; if (!exists("/proc/cmdline")) return NULL; @@ -142,11 +141,10 @@ rc_proc_getent(const char *ent RC_UNUSED) return NULL; i = 0; - if ((size = getline(&proc, &i, fp)) == -1) { + if (xgetline(&proc, &i, fp) == -1) { free(proc); return NULL; } - proc[size - 1] = '\0'; save = proc; len = strlen(ent); @@ -184,7 +182,7 @@ rc_config_list(const char *file) if (!(fp = fopen(file, "r"))) return list; - while ((rc_getline(&buffer, &len, fp))) { + while (xgetline(&buffer, &len, fp) != -1) { p = buffer; /* Strip leading spaces/tabs */ while ((*p == ' ') || (*p == '\t')) diff --git a/src/librc/librc.c b/src/librc/librc.c index b54496410..12011d3a3 100644 --- a/src/librc/librc.c +++ b/src/librc/librc.c @@ -175,7 +175,8 @@ file_regex(const char *file, const char *regex) { FILE *fp; char *line = NULL; - size_t size = 0, len = 0; + size_t size = 0; + ssize_t len = 0; regex_t re; bool retval = true; int result; @@ -192,7 +193,7 @@ file_regex(const char *file, const char *regex) return false; } - while ((len = rc_getline(&line, &size, fp))) { + while ((len = xgetline(&line, &size, fp)) != -1) { char *str = line; /* some /proc files have \0 separated content so we have to loop through the 'line' */ @@ -702,19 +703,22 @@ rc_service_extra_commands(const char *service) snprintf(cmd, l, OPTSTR, svc); free(svc); - if ((fp = popen(cmd, "r"))) { - rc_getline(&buffer, &len, fp); + if (!(fp = popen(cmd, "r"))) { + free(cmd); + return NULL; + } + + if (xgetline(&buffer, &len, fp) != -1) { p = buffer; commands = rc_stringlist_new(); while ((token = strsep(&p, " "))) if (token[0] != '\0') rc_stringlist_add(commands, token); - - pclose(fp); - free(buffer); } + pclose(fp); + free(buffer); free(cmd); return commands; } @@ -726,7 +730,7 @@ rc_service_description(const char *service, const char *option) char *svc; char *cmd; char *desc = NULL; - size_t len = 0; + size_t size = 0; FILE *fp; size_t l; @@ -741,7 +745,10 @@ rc_service_description(const char *service, const char *option) snprintf(cmd, l, DESCSTR, svc, *option ? "_" : "", option); free(svc); if ((fp = popen(cmd, "r"))) { - rc_getline(&desc, &len, fp); + if (xgetline(&desc, &size, fp) == -1) { + free(desc); + desc = NULL; + } pclose(fp); } free(cmd); diff --git a/src/mountinfo/mountinfo.c b/src/mountinfo/mountinfo.c index 820182334..001fe08ae 100644 --- a/src/mountinfo/mountinfo.c +++ b/src/mountinfo/mountinfo.c @@ -327,7 +327,7 @@ find_mounts(struct args *args) list = rc_stringlist_new(); buffer = NULL; - while (getline(&buffer, &size, fp) != -1) { + while (xgetline(&buffer, &size, fp) != -1) { netdev = -1; p = buffer; from = strsep(&p, " "); diff --git a/src/openrc/rc.c b/src/openrc/rc.c index 5bee9e6cf..096e77329 100644 --- a/src/openrc/rc.c +++ b/src/openrc/rc.c @@ -335,11 +335,11 @@ static char *get_krunlevel(void) return NULL; } - if (getline(&buffer, &i, fp) != -1) { - i = strlen(buffer); - if (buffer[i - 1] == '\n') - buffer[i - 1] = 0; + if (xgetline(&buffer, &i, fp) == -1) { + free(buffer); + buffer = NULL; } + fclose(fp); return buffer; } diff --git a/src/shared/helpers.h b/src/shared/helpers.h index dee41b75a..ce0ba633f 100644 --- a/src/shared/helpers.h +++ b/src/shared/helpers.h @@ -165,4 +165,16 @@ RC_UNUSED RC_PRINTF(2,3) static int xasprintf(char **strp, const char *fmt, ...) return len; } +RC_UNUSED static ssize_t xgetline(char **restrict lineptr, size_t *restrict n, FILE *restrict stream) +{ + ssize_t ret = getline(lineptr, n, stream); + if (ret == -1) + return -1; + + if ((*lineptr)[ret - 1] == '\n') + (*lineptr)[--ret] = '\0'; + + return ret; +} + #endif diff --git a/src/shared/misc.c b/src/shared/misc.c index 28f4e2352..45409574a 100644 --- a/src/shared/misc.c +++ b/src/shared/misc.c @@ -183,17 +183,14 @@ env_config(void) free(e); if ((fp = fopen(RC_KRUNLEVEL, "r"))) { - if (getline(&buffer, &size, fp) != -1) { - l = strlen (buffer) - 1; - if (buffer[l] == '\n') - buffer[l] = 0; + if (xgetline(&buffer, &size, fp) != -1) setenv("RC_DEFAULTLEVEL", buffer, 1); - } + free(buffer); fclose(fp); - } else + } else { setenv("RC_DEFAULTLEVEL", RC_LEVEL_DEFAULT, 1); + } - free(buffer); if (sys) setenv("RC_SYS", sys, 1); diff --git a/src/shared/selinux.c b/src/shared/selinux.c index 213a00f13..67f84d3c8 100644 --- a/src/shared/selinux.c +++ b/src/shared/selinux.c @@ -261,7 +261,6 @@ static int read_context_file(const char *filename, char **context) char *p; char *p2; size_t len = 0; - ssize_t read; xasprintf(&filepath, "%s/%s", selinux_contexts_path(), filename); @@ -272,7 +271,7 @@ static int read_context_file(const char *filename, char **context) return -1; } - while ((read = getline(&line, &len, fp)) != -1) { + while (xgetline(&line, &len, fp) != -1) { /* cut off spaces before the string */ p = line; while (isspace(*p) && *p != '\0') diff --git a/src/start-stop-daemon/start-stop-daemon.c b/src/start-stop-daemon/start-stop-daemon.c index 027435adb..5868dd377 100644 --- a/src/start-stop-daemon/start-stop-daemon.c +++ b/src/start-stop-daemon/start-stop-daemon.c @@ -745,7 +745,7 @@ int main(int argc, char **argv) fp = fopen(exec_file, "r"); if (fp) { line = NULL; - if (getline(&line, &size, fp) == -1) + if (xgetline(&line, &size, fp) == -1) eerrorx("%s: %s", applet, strerror(errno)); p = line; fclose(fp); @@ -754,10 +754,6 @@ int main(int argc, char **argv) /* Strip leading spaces */ while (*p == ' ' || *p == '\t') p++; - /* Remove the trailing newline */ - len = strlen(p) - 1; - if (p[len] == '\n') - p[len] = '\0'; token = strsep(&p, " "); free(exec_file); xasprintf(&exec_file, "%s", token);