Do not let sysctl abort due a missed file or directory under /proc. Inlcude signal.h for compiling w. Signed-off-by: Werner Fink <werner@xxxxxxx> diff --git a/sysctl.c b/sysctl.c index 1470df9..9be79ce 100644 --- a/sysctl.c +++ b/sysctl.c @@ -128,6 +128,7 @@ static int ReadSetting(const char *restrict const name) { char *restrict outname; char inbuf[1025]; FILE *restrict fp; + struct stat ts; if (!name || !*name) { fprintf(stderr, ERR_INVALID_KEY, name); @@ -144,6 +145,25 @@ static int ReadSetting(const char *restrict const name) { outname = strdup(name); slashdot(outname,'/','.'); /* change / to . */ + if (stat(tmpname, &ts) < 0) { + if (!IgnoreError) { + perror(tmpname); + rc = -1; + } + goto out; + } + if ((ts.st_mode & S_IRUSR) == 0) + goto out; + + if (S_ISDIR(ts.st_mode)) { + size_t len; + len = strlen(tmpname); + tmpname[len] = '/'; + tmpname[len+1] = '\0'; + rc = DisplayAll(tmpname); + goto out; + } + fp = fopen(tmpname, "r"); if (!fp) { @@ -164,6 +184,7 @@ static int ReadSetting(const char *restrict const name) { break; } } else { + errno = 0; if(fgets(inbuf, sizeof inbuf - 1, fp)) { // this loop is required, see // /sbin/sysctl -a | egrep -6 dev.cdrom.info @@ -194,18 +215,20 @@ static int ReadSetting(const char *restrict const name) { len = strlen(tmpname); tmpname[len] = '/'; tmpname[len+1] = '\0'; + fclose(fp); rc = DisplayAll(tmpname); - break; + goto out; } default: fprintf(stderr, ERR_UNKNOWN_READING, strerror(errno), outname); rc = -1; + case 0: break; } } fclose(fp); } - +out: free(tmpname); free(outname); return rc; @@ -265,8 +288,9 @@ static int WriteSetting(const char *setting) { const char *value; const char *equals; char *tmpname; - FILE *fp; char *outname; + FILE *fp; + struct stat ts; if (!name) { /* probably don't want to display this err */ return 0; @@ -299,6 +323,24 @@ static int WriteSetting(const char *setting) { outname[equals-name] = 0; slashdot(outname,'/','.'); /* change / to . */ + if (stat(tmpname, &ts) < 0) { + if (!IgnoreError) { + perror(tmpname); + rc = -1; + } + goto out; + } + + if ((ts.st_mode & S_IWUSR) == 0) { + fprintf(stderr, ERR_UNKNOWN_WRITING, strerror(EACCES), outname); + goto out; + } + + if (S_ISDIR(ts.st_mode)) { + fprintf(stderr, ERR_UNKNOWN_WRITING, strerror(EACCES), outname); + goto out; + } + fp = fopen(tmpname, "w"); if (!fp) { @@ -343,7 +385,7 @@ static int WriteSetting(const char *setting) { } } } - +out: free(tmpname); free(outname); return rc; diff --git a/w.c b/w.c index c2e996a..f479433 100644 --- a/w.c +++ b/w.c @@ -15,6 +15,7 @@ #include <ctype.h> #include <errno.h> #include <fcntl.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -- 1.6.0.2