Merge branch 'bitstreamout/procps-procio'
References: procps-ng/procps!56
This commit is contained in:
commit
be6b048a41
@ -233,6 +233,8 @@ proc_libprocps_la_SOURCES = \
|
|||||||
proc/escape.h \
|
proc/escape.h \
|
||||||
proc/numa.c \
|
proc/numa.c \
|
||||||
proc/numa.h \
|
proc/numa.h \
|
||||||
|
proc/procio.c \
|
||||||
|
proc/procio.h \
|
||||||
proc/procps-private.h \
|
proc/procps-private.h \
|
||||||
proc/procps.h \
|
proc/procps.h \
|
||||||
proc/pwcache.c \
|
proc/pwcache.c \
|
||||||
@ -258,6 +260,7 @@ proc_libprocps_la_include_HEADERS = \
|
|||||||
proc/devname.h \
|
proc/devname.h \
|
||||||
proc/escape.h \
|
proc/escape.h \
|
||||||
proc/numa.h \
|
proc/numa.h \
|
||||||
|
proc/procio.h \
|
||||||
proc/procps.h \
|
proc/procps.h \
|
||||||
proc/pwcache.h \
|
proc/pwcache.h \
|
||||||
proc/readproc.h \
|
proc/readproc.h \
|
||||||
@ -269,6 +272,7 @@ proc_libprocps_la_include_HEADERS = \
|
|||||||
proc/whattime.h
|
proc/whattime.h
|
||||||
|
|
||||||
dist_man_MANS += \
|
dist_man_MANS += \
|
||||||
|
proc/procio.3 \
|
||||||
proc/openproc.3 \
|
proc/openproc.3 \
|
||||||
proc/readproc.3 \
|
proc/readproc.3 \
|
||||||
proc/readproctab.3
|
proc/readproctab.3
|
||||||
|
@ -8,6 +8,7 @@ global:
|
|||||||
escape_str;
|
escape_str;
|
||||||
escape_strlist;
|
escape_strlist;
|
||||||
escaped_copy;
|
escaped_copy;
|
||||||
|
fprocopen;
|
||||||
free_slabinfo;
|
free_slabinfo;
|
||||||
freeproc;
|
freeproc;
|
||||||
get_ns_id;
|
get_ns_id;
|
||||||
|
80
proc/procio.3
Normal file
80
proc/procio.3
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
'\" t -*- coding: UTF-8 -*-
|
||||||
|
.\"
|
||||||
|
.\" This file describes the readproc interface to the /proc filesystem
|
||||||
|
.\"
|
||||||
|
.\" Copyright 2018 Werner Fink <werner@suse.de>
|
||||||
|
.\"
|
||||||
|
.\" Permission is granted to make and distribute verbatim copies of this
|
||||||
|
.\" manual provided the copyright notice and this permission notice are
|
||||||
|
.\" preserved on all copies.
|
||||||
|
.\"
|
||||||
|
.\" Permission is granted to copy and distribute modified versions of this
|
||||||
|
.\" manual under the conditions for verbatim copying, provided that the
|
||||||
|
.\" entire resulting derived work is distributed under the terms of a
|
||||||
|
.\" permission notice identical to this one
|
||||||
|
.\"
|
||||||
|
.\" Formatted or processed versions of this manual, if unaccompanied by
|
||||||
|
.\" the source, must acknowledge the copyright and authors of this work.
|
||||||
|
.\"
|
||||||
|
.TH PROCIO 3 "16 January 2018" "Linux Manpage" "Linux Programmer's Manual"
|
||||||
|
.SH NAME
|
||||||
|
fprocopen \- stream open functions on files below /proc/##
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B #define _GNU_SOURCE
|
||||||
|
.br
|
||||||
|
.B #include <stdio.h>
|
||||||
|
.br
|
||||||
|
.B #include <proc/procio.h>
|
||||||
|
.sp
|
||||||
|
.BI "FILE *fprocopen(const char *path, const char *mode);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
|
||||||
|
The
|
||||||
|
.B fprocopen
|
||||||
|
function opens files below
|
||||||
|
.I /proc/##
|
||||||
|
whose name is the string to by path and associates a stream with it.
|
||||||
|
The argument
|
||||||
|
.I mode
|
||||||
|
points to a string beginning with one of the following sequences
|
||||||
|
.TP
|
||||||
|
.B r
|
||||||
|
Open a file below
|
||||||
|
.I /proc/##
|
||||||
|
for reading even large buffers. The stream is positioned at
|
||||||
|
the beginning of the file.
|
||||||
|
.TP
|
||||||
|
.BR w [ <del> ]
|
||||||
|
Open a file below
|
||||||
|
.I /proc/##
|
||||||
|
for writing even large buffers. The optional delimeter character
|
||||||
|
can be one of the follwoing
|
||||||
|
.BR '\ ' ,\ ',' ,\ '.' ,\ and\ ':'
|
||||||
|
where the default is the colon
|
||||||
|
.BR ',' .
|
||||||
|
This allows to split very large input lines into pieces at this
|
||||||
|
delimeter and write each of them to the opened file below
|
||||||
|
.IR /proc/## .
|
||||||
|
.TP
|
||||||
|
.B e
|
||||||
|
The underlying file descriptor will be closed if you use any
|
||||||
|
of the ‘exec...’ functions within your code.
|
||||||
|
.PP
|
||||||
|
The internal API allows to use stdio functions to read and write
|
||||||
|
large buffers below
|
||||||
|
.IR /proc/## .
|
||||||
|
.PP
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR fopen (3),
|
||||||
|
.br
|
||||||
|
.BR fopencookie (3)
|
||||||
|
.br
|
||||||
|
.BR setvbuf (3)
|
||||||
|
.br
|
||||||
|
.BR lseek (3)
|
||||||
|
.PP
|
||||||
|
.SH COPYRIGHT
|
||||||
|
2018 Werner Fink,
|
||||||
|
.SH AUTHOR
|
||||||
|
Werner Fink <werner@suse.de>
|
293
proc/procio.c
Normal file
293
proc/procio.c
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
/*
|
||||||
|
* procio.c -- Replace stdio for read and write on files below
|
||||||
|
* proc to be able to read and write large buffers as well.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Werner Fink
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
# define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <libio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
typedef struct pcookie {
|
||||||
|
char *buf;
|
||||||
|
size_t count;
|
||||||
|
size_t length;
|
||||||
|
off_t offset;
|
||||||
|
int fd;
|
||||||
|
int delim;
|
||||||
|
int final:1;
|
||||||
|
} pcookie_t;
|
||||||
|
|
||||||
|
static ssize_t proc_read(void *, char *, size_t);
|
||||||
|
static ssize_t proc_write(void *, const char *, size_t);
|
||||||
|
static int proc_close(void *);
|
||||||
|
|
||||||
|
__extension__
|
||||||
|
static cookie_io_functions_t procio = {
|
||||||
|
.read = proc_read,
|
||||||
|
.write = proc_write,
|
||||||
|
.seek = NULL,
|
||||||
|
.close = proc_close,
|
||||||
|
};
|
||||||
|
|
||||||
|
FILE *fprocopen(const char *path, const char *mode)
|
||||||
|
{
|
||||||
|
pcookie_t *cookie = NULL;
|
||||||
|
FILE *handle = NULL;
|
||||||
|
mode_t flags = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
int c, delim;
|
||||||
|
|
||||||
|
if (!mode || !(len = strlen(mode))) {
|
||||||
|
errno = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No append mode possible */
|
||||||
|
switch (mode[0]) {
|
||||||
|
case 'r':
|
||||||
|
flags |= O_RDONLY;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
flags |= O_WRONLY|O_TRUNC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
delim = ','; /* default delimeter is the colon */
|
||||||
|
for (c = 1; c < len; c++) {
|
||||||
|
switch (mode[c]) {
|
||||||
|
case '\0':
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
errno = EINVAL;
|
||||||
|
goto out;
|
||||||
|
case 'e':
|
||||||
|
flags |= O_CLOEXEC;
|
||||||
|
continue;
|
||||||
|
case 'b':
|
||||||
|
case 'm':
|
||||||
|
case 'x':
|
||||||
|
/* ignore this */
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
if (mode[c] == ' ' || (mode[c] >= ',' && mode[c] <= '.') || mode[c] == ':')
|
||||||
|
delim = mode[c];
|
||||||
|
else {
|
||||||
|
errno = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie = (pcookie_t *)malloc(sizeof(pcookie_t));
|
||||||
|
if (!cookie)
|
||||||
|
goto out;
|
||||||
|
cookie->count = BUFSIZ;
|
||||||
|
cookie->buf = (char *)malloc(cookie->count);
|
||||||
|
if (!cookie->buf) {
|
||||||
|
int errsv = errno;
|
||||||
|
free(cookie);
|
||||||
|
errno = errsv;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
cookie->final = 0;
|
||||||
|
cookie->offset = 0;
|
||||||
|
cookie->length = 0;
|
||||||
|
cookie->delim = delim;
|
||||||
|
|
||||||
|
cookie->fd = openat(AT_FDCWD, path, flags);
|
||||||
|
if (cookie->fd < 0) {
|
||||||
|
int errsv = errno;
|
||||||
|
free(cookie->buf);
|
||||||
|
free(cookie);
|
||||||
|
errno = errsv;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle = fopencookie(cookie, mode, procio);
|
||||||
|
if (!handle) {
|
||||||
|
int errsv = errno;
|
||||||
|
close(cookie->fd);
|
||||||
|
free(cookie->buf);
|
||||||
|
free(cookie);
|
||||||
|
errno = errsv;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ssize_t proc_read(void *c, char *buf, size_t count)
|
||||||
|
{
|
||||||
|
pcookie_t *cookie = c;
|
||||||
|
ssize_t len = -1;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
if (cookie->count < count) {
|
||||||
|
ptr = realloc(cookie->buf, count);
|
||||||
|
if (!ptr)
|
||||||
|
goto out;
|
||||||
|
cookie->buf = ptr;
|
||||||
|
cookie->count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!cookie->final) {
|
||||||
|
len = read(cookie->fd, cookie->buf, cookie->count);
|
||||||
|
|
||||||
|
if (len <= 0) {
|
||||||
|
if (len == 0) {
|
||||||
|
/* EOF */
|
||||||
|
cookie->final = 1;
|
||||||
|
cookie->buf[cookie->length] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
goto out; /* error or done */
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie->length = len;
|
||||||
|
|
||||||
|
if (cookie->length < cookie->count)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Likly to small buffer here */
|
||||||
|
|
||||||
|
lseek(cookie->fd, 0, SEEK_SET); /* reset for a retry */
|
||||||
|
|
||||||
|
ptr = realloc(cookie->buf, cookie->count += BUFSIZ);
|
||||||
|
if (!ptr)
|
||||||
|
goto out;
|
||||||
|
cookie->buf = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = count;
|
||||||
|
if (cookie->length - cookie->offset < len)
|
||||||
|
len = cookie->length - cookie->offset;
|
||||||
|
|
||||||
|
if (len < 0)
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
if (len) {
|
||||||
|
(void)memcpy(buf, cookie->buf+cookie->offset, len);
|
||||||
|
cookie->offset += len;
|
||||||
|
} else
|
||||||
|
len = EOF;
|
||||||
|
out:
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LINELEN 4096
|
||||||
|
|
||||||
|
static
|
||||||
|
ssize_t proc_write(void *c, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
pcookie_t *cookie = c;
|
||||||
|
ssize_t len = -1;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
if (!count) {
|
||||||
|
len = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NL is the final input */
|
||||||
|
cookie->final = memrchr(buf, '\n', count) ? 1 : 0;
|
||||||
|
|
||||||
|
while (cookie->count < cookie->offset + count) {
|
||||||
|
ptr = realloc(cookie->buf, cookie->count += count);
|
||||||
|
if (!ptr)
|
||||||
|
goto out;
|
||||||
|
cookie->buf = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = count;
|
||||||
|
(void)memcpy(cookie->buf+cookie->offset, buf, count);
|
||||||
|
cookie->offset += count;
|
||||||
|
|
||||||
|
if (cookie->final) {
|
||||||
|
len = write(cookie->fd, cookie->buf, cookie->offset);
|
||||||
|
if (len < 0 && errno == EINVAL) {
|
||||||
|
size_t offset;
|
||||||
|
off_t amount;
|
||||||
|
char *token;
|
||||||
|
/*
|
||||||
|
* Oops buffer might be to large, split buffer into
|
||||||
|
* pieces at delimeter if provided
|
||||||
|
*/
|
||||||
|
if (!cookie->delim)
|
||||||
|
goto out; /* Hey dude?! */
|
||||||
|
offset = 0;
|
||||||
|
do {
|
||||||
|
token = NULL;
|
||||||
|
if (cookie->offset > LINELEN)
|
||||||
|
token = (char*)memrchr(cookie->buf+offset, ',', LINELEN);
|
||||||
|
else
|
||||||
|
token = (char*)memrchr(cookie->buf+offset, '\n', LINELEN);
|
||||||
|
if (token)
|
||||||
|
*token = '\n';
|
||||||
|
else {
|
||||||
|
errno = EINVAL;
|
||||||
|
len = -1;
|
||||||
|
goto out; /* Wrong/Missing delimeter? */
|
||||||
|
}
|
||||||
|
if (offset > 0)
|
||||||
|
lseek(cookie->fd, 1, SEEK_CUR);
|
||||||
|
|
||||||
|
amount = token-(cookie->buf+offset)+1;
|
||||||
|
ptr = cookie->buf+offset;
|
||||||
|
|
||||||
|
len = write(cookie->fd, ptr, amount);
|
||||||
|
if (len < 1 || len >= cookie->offset)
|
||||||
|
break;
|
||||||
|
|
||||||
|
offset += len;
|
||||||
|
cookie->offset -= len;
|
||||||
|
|
||||||
|
} while (cookie->offset > 0);
|
||||||
|
}
|
||||||
|
if (len > 0)
|
||||||
|
len = count;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int proc_close(void *c)
|
||||||
|
{
|
||||||
|
pcookie_t *cookie = c;
|
||||||
|
close(cookie->fd);
|
||||||
|
free(cookie->buf);
|
||||||
|
free(cookie);
|
||||||
|
return 0;
|
||||||
|
}
|
11
proc/procio.h
Normal file
11
proc/procio.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef PROCPS_PROC_PROCIO_H
|
||||||
|
#define PROCPS_PROC_PROCIO_H
|
||||||
|
|
||||||
|
#include "procps.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
extern FILE *fprocopen(const char *, const char *);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
#endif
|
66
sysctl.c
66
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,17 @@ 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[LINELEN];
|
|
||||||
char buffer[LINELEN];
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *t;
|
char *t;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
ssize_t rlen;
|
||||||
char *name, *value;
|
char *name, *value;
|
||||||
glob_t globbuf;
|
glob_t globbuf;
|
||||||
int globerr;
|
int globerr;
|
||||||
@ -544,13 +538,19 @@ static int Preload(const char *restrict const filename)
|
|||||||
? stdin : fopen(globbuf.gl_pathv[j], "r");
|
? stdin : fopen(globbuf.gl_pathv[j], "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
xwarn(_("cannot open \"%s\""), globbuf.gl_pathv[j]);
|
xwarn(_("cannot open \"%s\""), globbuf.gl_pathv[j]);
|
||||||
return -1;
|
rc = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(oneline, sizeof oneline, fp)) {
|
while ((rlen = getline(&iobuf, &iolen, fp)) > 0) {
|
||||||
n++;
|
size_t offset;
|
||||||
t = StripLeadingAndTrailingSpaces(oneline);
|
|
||||||
|
|
||||||
|
n++;
|
||||||
|
|
||||||
|
if (rlen < 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
t = StripLeadingAndTrailingSpaces(iobuf);
|
||||||
if (strlen(t) < 2)
|
if (strlen(t) < 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -569,6 +569,10 @@ static int Preload(const char *restrict const filename)
|
|||||||
if (pattern && !pattern_match(name, pattern))
|
if (pattern && !pattern_match(name, pattern))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
offset = strlen(name);
|
||||||
|
memmove(&iobuf[0], name, offset);
|
||||||
|
iobuf[offset++] = '=';
|
||||||
|
|
||||||
value = strtok(NULL, "\n\r");
|
value = strtok(NULL, "\n\r");
|
||||||
if (!value || !*value) {
|
if (!value || !*value) {
|
||||||
xwarnx(_("%s(%d): invalid syntax, continuing..."),
|
xwarnx(_("%s(%d): invalid syntax, continuing..."),
|
||||||
@ -580,12 +584,16 @@ static int Preload(const char *restrict const filename)
|
|||||||
value++;
|
value++;
|
||||||
|
|
||||||
/* should NameOnly affect this? */
|
/* should NameOnly affect this? */
|
||||||
sprintf(buffer, "%s=%s", name, value);
|
memmove(&iobuf[offset], value, strlen(value));
|
||||||
rc |= WriteSetting(buffer);
|
offset += strlen(value);
|
||||||
|
iobuf[offset] = '\0';
|
||||||
|
|
||||||
|
rc |= WriteSetting(iobuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,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