Skip to content

Commit

Permalink
New helper functions to read/write /proc and /sys style files
Browse files Browse the repository at this point in the history
From the Infix project.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
  • Loading branch information
troglobit committed Jun 11, 2023
1 parent 97a3d43 commit 4dd14da
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Makefile.am
Expand Up @@ -9,7 +9,7 @@ libite_la_SOURCES = chomp.c copyfile.c \
fexist.c fisdir.c \
fparseln.c fsendfile.c \
ifconfig.c lfile.c \
makepath.c progress.c \
makepath.c procval.c progress.c \
pidfile.c pidfilefn.c popenf.c \
reallocarray.c rsync.c strtrim.c \
strlcpy.c strlcat.c strtonum.c \
Expand Down
10 changes: 10 additions & 0 deletions src/lite.h
Expand Up @@ -90,6 +90,16 @@ int fcopyfile (FILE *src, FILE *dst);
ssize_t fsendfile (FILE *src, FILE *dst, size_t len);
int truncatef (off_t length, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));

char *vreadsnf (char *line, size_t len, const char *fmt, va_list ap);
char *readsnf (char *line, size_t len, const char *fmt, ...);
int writesf (const char *str, const char *mode, const char *fmt, ...);

int vreadllf (long long *value, const char *fmt, va_list ap);
int readllf (long long *value, const char *fmt, ...);
int readdf (int *value, const char *fmt, ...);
int writellf (long long value, const char *mode, const char *fmt, ...);
int writedf (int value, const char *mode, const char *fmt, ...);

int ifconfig (const char *ifname, const char *addr, const char *mask, int up);

lfile_t*lfopen (const char *file, const char *sep);
Expand Down
229 changes: 229 additions & 0 deletions src/procval.c
@@ -0,0 +1,229 @@
/* Reading and writing values/strings to/from /proc and /sys style files
*
* Copyright (c) 2023 Tobias Waldekranz <tobias@waldekranz.com>
* Copyright (c) 2023 Joachim Wiberg <troglobit@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
* @file procval.c
* @author Joachim Wiberg
* @date 2023
* @copyright ISC License
*/

#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

#include "lite.h"

/**
* Similar to readsnf() except it takes a @a va_list argument
* @param line Pointer to line buffer.
* @param len Size of line buffer.
* @param fmt Formatted string to be composed into a pathname.
* @param ap List of variable arguemnts from va_start().
*
* For details, see readsnf().
*
* @returns same as readsnf().
*/
char *vreadsnf(char *line, size_t len, const char *fmt, va_list ap)
{
va_list apc;
FILE *fp;

va_copy(apc, ap);
fp = vfopenf("r", fmt, ap);
va_end(ap);
if (!fp)
return NULL;

if (!fgets(line, len, fp)) {
fclose(fp);
return NULL;
}

fclose(fp);
return chomp(line);
}


/**
* Read first line from a file composed from fmt and optional args.
* @param line Pointer to line buffer.
* @param len Size of line buffer.
* @param fmt Formatted string to be composed into a pathname.
*
* @returns On success, this function returns the @p line read from the
* file, with any trailing '\n' chomp()ed out. On error, @c NULL.
*/
char *readsnf(char *line, size_t len, const char *fmt, ...)
{
va_list ap;
char *ln;

va_start(ap, fmt);
ln = vreadsnf(line, len, fmt, ap);
va_end(ap);

return ln;
}

/**
* Write a string buffer to a file composed from fmt and optional args.
* @param str Pointer to string buffer, may be multiple lines.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int writesf(const char *str, const char *mode, const char *fmt, ...)
{
va_list ap;
FILE *fp;

va_start(ap, fmt);
fp = vfopenf(mode, fmt, ap);
va_end(ap);
if (!fp)
return -1;

fprintf(fp, "%s\n", str);
return fclose(fp);
}

/**
* Same as readllf() exectp it takes a @a va_list argument.
*/
int vreadllf(long long *value, const char *fmt, va_list ap)
{
char line[0x100];

if (!vreadsnf(line, sizeof(line), fmt, ap))
return -1;

errno = 0;
*value = strtoll(line, NULL, 0);

return errno ? -1 : 0;
}

/**
* Read 64-bit integer value from a file composed from fmt and optional args.
* @param value Pointer to where to store read 64-bit integer value.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int readllf(long long *value, const char *fmt, ...)
{
va_list ap;
int rc;

va_start(ap, fmt);
rc = vreadllf(value, fmt, ap);
va_end(ap);

return rc;
}


/**
* Read integer value from a file composed from fmt and optional args.
* @param value Pointer to where to store read integer value.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int readdf(int *value, const char *fmt, ...)
{
long long tmp;
va_list ap;
int rc;

va_start(ap, fmt);
rc = vreadllf(&tmp, fmt, ap);
va_end(ap);

if (rc)
return rc;

if (tmp < INT_MIN || tmp > INT_MAX) {
errno = ERANGE;
return -1;
}

*value = tmp;
return 0;
}

/**
* Write 64-bit integer value to a file composed from fmt and optional args.
* @param value 64-bit integer value to write.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int writellf(long long value, const char *mode, const char *fmt, ...)
{
va_list ap;
FILE *fp;

va_start(ap, fmt);
fp = vfopenf(mode, fmt, ap);
va_end(ap);
if (!fp)
return -1;

fprintf(fp, "%lld\n", value);
return fclose(fp);
}


/**
* Write integer value to a file composed from fmt and optional args.
* @param value Integer value to write.
* @param mode An fopen() mode string, e.g. "w+".
* @param fmt Formatted string to be composed into a pathname.
*
* @returns result of operation, with @a errno set on error.
*/
int writedf(int value, const char *mode, const char *fmt, ...)
{
va_list ap;
FILE *fp;

va_start(ap, fmt);
fp = vfopenf(mode, fmt, ap);
va_end(ap);
if (!fp)
return -1;

fprintf(fp, "%d\n", value);
return fclose(fp);
}


/**
* Local Variables:
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/

0 comments on commit 4dd14da

Please sign in to comment.