From b3574527701dfb9ee25179e176fbd91b53d6b96a Mon Sep 17 00:00:00 2001 From: albert <> Date: Thu, 15 Jul 2004 15:22:23 +0000 Subject: [PATCH] sysctl -N --- NEWS | 12 ++++---- sysctl.8 | 4 +++ sysctl.c | 83 +++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 71 insertions(+), 28 deletions(-) diff --git a/NEWS b/NEWS index 068a4b34..66947a98 100644 --- a/NEWS +++ b/NEWS @@ -4,15 +4,15 @@ move striping from install command to CFLAGS now using gcc -fweb and -frename-registers options avoid warning about -lncurses when not linking -- thanks FLWM tolerate IA-64 headers without PAGE_SIZE -watch: allow sub-second intervals -- thanks Thomas Stewart -sysctl: -q option -sysctl: better error handling of failed writes -ps: personality-specific -x support (HP-UX and SVR4-MP) ps: k option, same as --sort -vmstat: fixed -d +ps: personality-specific -x support (HP-UX and SVR4-MP) +sysctl: -q and -N options +sysctl: better error handling of failed writes +top: tolerate sparse CPU numbering top: try to handle terminals lacking rmam and smam #235003 top: xterm dislikes clear-to-eol at eol (char lost) -top: tolerate sparse CPU numbering +vmstat: fixed -d +watch: allow sub-second intervals -- thanks Thomas Stewart procps-3.2.0 --> procps-3.2.1 diff --git a/sysctl.8 b/sysctl.8 index 7d0ed9fe..3407f7f6 100644 --- a/sysctl.8 +++ b/sysctl.8 @@ -46,6 +46,10 @@ Use this option to disable printing of the key name when printing values. Use this option to ignore errors about unknown keys. .TP .B "-q" +Use this option to only print the names. It may be useful with shells that +have programmable completion. +.TP +.B "-q" Use this option to not display the values set to stdout. .TP .B "-w" diff --git a/sysctl.c b/sysctl.c index 022694a7..5af54be2 100644 --- a/sysctl.c +++ b/sysctl.c @@ -45,6 +45,7 @@ static bool false = 0; static const char PROC_PATH[] = "/proc/sys/"; static const char DEFAULT_PRELOAD[] = "/etc/sysctl.conf"; +static bool NameOnly; static bool PrintName; static bool PrintNewline; static bool IgnoreError; @@ -115,7 +116,7 @@ static char *StripLeadingAndTrailingSpaces(char *oneline) { return t; } - +static int DisplayAll(const char *restrict const path); /* * Read a sysctl setting @@ -163,16 +164,43 @@ static int ReadSetting(const char *restrict const name) { break; } } else { - while(fgets(inbuf, 1024, fp)) { - /* already has the \n in it */ - if (PrintName) { - fprintf(stdout, "%s = %s", outname, inbuf); - } else { - if (!PrintNewline) { - char *nlptr = strchr(inbuf,'\n'); - if(nlptr) *nlptr='\0'; + if(fgets(inbuf, sizeof inbuf - 1, fp)) { + // this loop is required, see + // /sbin/sysctl -a | egrep -6 dev.cdrom.info + do { + if (NameOnly) { + fprintf(stdout, "%s\n", outname); + } else { + /* already has the \n in it */ + if (PrintName) { + fprintf(stdout, "%s = %s", outname, inbuf); + } else { + if (!PrintNewline) { + char *nlptr = strchr(inbuf,'\n'); + if(nlptr) *nlptr='\0'; + } + fprintf(stdout, "%s", inbuf); + } } - fprintf(stdout, "%s", inbuf); + } while(fgets(inbuf, sizeof inbuf - 1, fp)); + } else { + switch(errno) { + case EACCES: + fprintf(stderr, ERR_PERMISSION_DENIED, outname); + rc = -1; + break; + case EISDIR:{ + size_t len; + len = strlen(tmpname); + tmpname[len] = '/'; + tmpname[len+1] = '\0'; + rc = DisplayAll(tmpname); + break; + } + default: + fprintf(stderr, ERR_UNKNOWN_READING, errno, outname); + rc = -1; + break; } } fclose(fp); @@ -189,12 +217,11 @@ static int ReadSetting(const char *restrict const name) { * Display all the sysctl settings * */ -static int DisplayAll(const char *restrict const path, bool ShowTableUtil) { +static int DisplayAll(const char *restrict const path) { int rc = 0; int rc2; DIR *restrict dp; struct dirent *restrict de; - char *restrict tmpdir; struct stat ts; dp = opendir(path); @@ -203,17 +230,19 @@ static int DisplayAll(const char *restrict const path, bool ShowTableUtil) { fprintf(stderr, ERR_OPENING_DIR, path); rc = -1; } else { - readdir(dp); readdir(dp); /* skip . and .. */ + readdir(dp); // skip . + readdir(dp); // skip .. while (( de = readdir(dp) )) { + char *restrict tmpdir; tmpdir = (char *restrict)malloc(strlen(path)+strlen(de->d_name)+2); sprintf(tmpdir, "%s%s", path, de->d_name); - rc2 = stat(tmpdir, &ts); /* should check this return code */ + rc2 = stat(tmpdir, &ts); if (rc2 != 0) { perror(tmpdir); } else { if (S_ISDIR(ts.st_mode)) { strcat(tmpdir, "/"); - DisplayAll(tmpdir, ShowTableUtil); + DisplayAll(tmpdir); } else { rc |= ReadSetting(tmpdir+strlen(PROC_PATH)); } @@ -300,13 +329,17 @@ static int WriteSetting(const char *setting) { fprintf(stderr, ERR_UNKNOWN_WRITING, errno, outname); } if (rc==0 && !Quiet) { - if (PrintName) { - fprintf(stdout, "%s = %s\n", outname, value); + if (NameOnly) { + fprintf(stdout, "%s\n", outname); } else { - if (PrintNewline) - fprintf(stdout, "%s\n", value); - else - fprintf(stdout, "%s", value); + if (PrintName) { + fprintf(stdout, "%s = %s\n", outname, value); + } else { + if (PrintNewline) + fprintf(stdout, "%s\n", value); + else + fprintf(stdout, "%s", value); + } } } } @@ -364,6 +397,7 @@ static int Preload(const char *restrict const filename) { while ((*value == ' ' || *value == '\t') && *value != 0) value++; + // should NameOnly affect this? sprintf(buffer, "%s=%s", name, value); rc |= WriteSetting(buffer); } @@ -421,6 +455,9 @@ int main(int argc, char **argv) { case 'e': IgnoreError = true; break; + case 'N': + NameOnly = true; + break; case 'w': SwitchesAllowed = false; WriteMode = true; @@ -438,7 +475,7 @@ int main(int argc, char **argv) { case 'A': /* the above, including "opaques" (would be unprintable) */ case 'X': /* the above, with opaques completly printed in hex */ SwitchesAllowed = false; - return DisplayAll(PROC_PATH, ((*argv)[1] == 'a') ? false : true); + return DisplayAll(PROC_PATH); case 'V': fprintf(stdout, "sysctl (%s)\n",procps_version); exit(0); @@ -450,6 +487,8 @@ int main(int argc, char **argv) { return Usage(me); } } else { + if (NameOnly && Quiet) // nonsense + return Usage(me); SwitchesAllowed = false; if (WriteMode) ReturnCode = WriteSetting(*argv);