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:
parent
e0ab7cff1f
commit
8dd64c413e
55
sysctl.c
55
sysctl.c
@ -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"
|
||||||
#include "proc/procps.h"
|
#include "proc/procps.h"
|
||||||
#include "proc/version.h"
|
#include "proc/version.h"
|
||||||
|
|
||||||
@ -66,6 +67,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);
|
||||||
@ -158,14 +163,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;
|
||||||
|
|
||||||
@ -220,7 +223,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) {
|
||||||
@ -243,11 +246,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
|
||||||
*/
|
*/
|
||||||
@ -256,23 +256,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:
|
||||||
@ -439,10 +439,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) {
|
||||||
@ -503,20 +500,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;
|
||||||
@ -524,8 +517,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;
|
||||||
@ -551,7 +542,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++;
|
||||||
@ -559,7 +550,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;
|
||||||
|
|
||||||
@ -579,8 +570,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) {
|
||||||
@ -593,11 +584,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);
|
||||||
@ -824,7 +815,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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user