Use new standard I/O for reading/writing sysctl values

thereby use one allocated buffer for I/O which now might
be increased by the stdio function getline(3) on the
file if required.

Signed-off-by: Werner Fink <werner@suse.de>
This commit is contained in:
Werner Fink 2018-01-18 11:38:02 +01:00 committed by Craig Small
parent 3373a58fb6
commit 20ce03e08c

View File

@ -45,6 +45,7 @@
#include "fileutils.h" #include "fileutils.h"
#include "nls.h" #include "nls.h"
#include "xalloc.h" #include "xalloc.h"
#include "proc/procio.h"
/* /*
* Globals... * Globals...
@ -64,6 +65,10 @@ static bool IgnoreError;
static bool Quiet; static bool Quiet;
static char *pattern; static char *pattern;
#define LINELEN 4096
static char *iobuf;
static size_t iolen = LINELEN;
/* Function prototypes. */ /* Function prototypes. */
static int pattern_match(const char *string, const char *pat); static int pattern_match(const char *string, const char *pat);
static int DisplayAll(const char *restrict const path); static int DisplayAll(const char *restrict const path);
@ -156,14 +161,12 @@ static char *StripLeadingAndTrailingSpaces(char *oneline)
/* /*
* Read a sysctl setting * Read a sysctl setting
*/ */
#define IOBUFSIZ (128<<10)
static char *iobuf;
static int ReadSetting(const char *restrict const name) static int ReadSetting(const char *restrict const name)
{ {
int rc = 0; int rc = 0;
char *restrict tmpname; char *restrict tmpname;
char *restrict outname; char *restrict outname;
char inbuf[1025]; ssize_t rlen;
FILE *restrict fp; FILE *restrict fp;
struct stat ts; struct stat ts;
@ -218,7 +221,7 @@ static int ReadSetting(const char *restrict const name)
goto out; goto out;
} }
fp = fopen(tmpname, "r"); fp = fprocopen(tmpname, "r");
if (!fp) { if (!fp) {
switch (errno) { switch (errno) {
@ -241,11 +244,8 @@ static int ReadSetting(const char *restrict const name)
break; break;
} }
} else { } else {
if (iobuf)
setvbuf(fp, iobuf, _IOFBF, IOBUFSIZ);
errno = 0; errno = 0;
if (fgets(inbuf, sizeof inbuf - 1, fp)) { if ((rlen = getline(&iobuf, &iolen, fp)) > 0) {
/* this loop is required, see /* this loop is required, see
* /sbin/sysctl -a | egrep -6 dev.cdrom.info * /sbin/sysctl -a | egrep -6 dev.cdrom.info
*/ */
@ -254,23 +254,23 @@ static int ReadSetting(const char *restrict const name)
if (PrintName) { if (PrintName) {
fprintf(stdout, "%s = ", outname); fprintf(stdout, "%s = ", outname);
do { do {
fprintf(stdout, "%s", inbuf); fprintf(stdout, "%s", iobuf);
nlptr = &inbuf[strlen(inbuf) - 1]; nlptr = &iobuf[strlen(iobuf) - 1];
/* already has the \n in it */ /* already has the \n in it */
if (*nlptr == '\n') if (*nlptr == '\n')
break; break;
} while (fgets(inbuf, sizeof inbuf - 1, fp)); } while ((rlen = getline(&iobuf, &iolen, fp)) > 0);
if (*nlptr != '\n') if (*nlptr != '\n')
putchar('\n'); putchar('\n');
} else { } else {
if (!PrintNewline) { if (!PrintNewline) {
nlptr = strchr(inbuf, '\n'); nlptr = strchr(iobuf, '\n');
if (nlptr) if (nlptr)
*nlptr = '\0'; *nlptr = '\0';
} }
fprintf(stdout, "%s", inbuf); fprintf(stdout, "%s", iobuf);
} }
} while (fgets(inbuf, sizeof inbuf - 1, fp)); } while ((rlen = getline(&iobuf, &iolen, fp)) > 0);
} else { } else {
switch (errno) { switch (errno) {
case EACCES: case EACCES:
@ -437,10 +437,7 @@ static int WriteSetting(const char *setting)
goto out; goto out;
} }
fp = fopen(tmpname, "w"); fp = fprocopen(tmpname, "w");
if (iobuf)
setvbuf(fp, iobuf, _IOFBF, IOBUFSIZ);
if (!fp) { if (!fp) {
switch (errno) { switch (errno) {
@ -501,20 +498,16 @@ static int pattern_match(const char *string, const char *pat)
return (1); return (1);
} }
#define LINELEN 4096
/* /*
* Preload the sysctl's from the conf file. We parse the file and then * Preload the sysctl's from the conf file. We parse the file and then
* reform it (strip out whitespace). * reform it (strip out whitespace).
*/ */
static int Preload(const char *restrict const filename) static int Preload(const char *restrict const filename)
{ {
char *oneline;
FILE *fp; FILE *fp;
char *t; char *t;
int n = 0; int n = 0;
int rc = 0; int rc = 0;
size_t blen = LINELEN;
ssize_t rlen; ssize_t rlen;
char *name, *value; char *name, *value;
glob_t globbuf; glob_t globbuf;
@ -522,8 +515,6 @@ static int Preload(const char *restrict const filename)
int globflg; int globflg;
int j; int j;
oneline = xmalloc(blen);
globflg = GLOB_NOCHECK; globflg = GLOB_NOCHECK;
#ifdef GLOB_BRACE #ifdef GLOB_BRACE
globflg |= GLOB_BRACE; globflg |= GLOB_BRACE;
@ -549,7 +540,7 @@ static int Preload(const char *restrict const filename)
goto out; goto out;
} }
while ((rlen = getline(&oneline, &blen, fp)) != -1) { while ((rlen = getline(&iobuf, &iolen, fp)) > 0) {
size_t offset; size_t offset;
n++; n++;
@ -557,7 +548,7 @@ static int Preload(const char *restrict const filename)
if (rlen < 2) if (rlen < 2)
continue; continue;
t = StripLeadingAndTrailingSpaces(oneline); t = StripLeadingAndTrailingSpaces(iobuf);
if (strlen(t) < 2) if (strlen(t) < 2)
continue; continue;
@ -577,8 +568,8 @@ static int Preload(const char *restrict const filename)
continue; continue;
offset = strlen(name); offset = strlen(name);
memmove(&oneline[0], name, offset); memmove(&iobuf[0], name, offset);
oneline[offset++] = '='; iobuf[offset++] = '=';
value = strtok(NULL, "\n\r"); value = strtok(NULL, "\n\r");
if (!value || !*value) { if (!value || !*value) {
@ -591,11 +582,11 @@ static int Preload(const char *restrict const filename)
value++; value++;
/* should NameOnly affect this? */ /* should NameOnly affect this? */
memmove(&oneline[offset], value, strlen(value)); memmove(&iobuf[offset], value, strlen(value));
offset += strlen(value); offset += strlen(value);
oneline[offset] = '\0'; iobuf[offset] = '\0';
rc |= WriteSetting(oneline); rc |= WriteSetting(iobuf);
} }
fclose(fp); fclose(fp);
@ -822,7 +813,7 @@ int main(int argc, char *argv[])
argc -= optind; argc -= optind;
argv += optind; argv += optind;
iobuf = (char*)malloc(IOBUFSIZ); /* Allow to fail */ iobuf = xmalloc(iolen);
if (DisplayAllOpt) if (DisplayAllOpt)
return DisplayAll(PROC_PATH); return DisplayAll(PROC_PATH);