Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libite for openSUSE:Factory checked in at 2023-09-21 22:14:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libite (Old) and /work/SRC/openSUSE:Factory/.libite.new.1770 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libite" Thu Sep 21 22:14:05 2023 rev:11 rq:1112555 version:2.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/libite/libite.changes 2023-04-28 16:24:31.130413152 +0200 +++ /work/SRC/openSUSE:Factory/.libite.new.1770/libite.changes 2023-09-21 22:15:06.283568055 +0200 @@ -1,0 +2,15 @@ +Mon Sep 18 14:53:04 UTC 2023 - Martin Hauke <[email protected]> + +- Update to 2.6.0: + Changes + * New APIs from the Infix Project: + + fexistf() + + vfopenf() + + popenf() + + vreadsnf(), readsnf(), writesf() + + vreadllf(), readllf(), readdf() + + writellf(), writedf() + Fixes + * Spellchecking of API docs + +------------------------------------------------------------------- Old: ---- libite-2.5.3.tar.gz New: ---- libite-2.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libite.spec ++++++ --- /var/tmp/diff_new_pack.gjgAB7/_old 2023-09-21 22:15:07.287604494 +0200 +++ /var/tmp/diff_new_pack.gjgAB7/_new 2023-09-21 22:15:07.291604639 +0200 @@ -2,7 +2,7 @@ # spec file for package libite # # Copyright (c) 2023 SUSE LLC -# Copyright (c) 2018-2021, Martin Hauke <[email protected]> +# Copyright (c) 2018-2023, Martin Hauke <[email protected]> # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %define sover 5 Name: libite -Version: 2.5.3 +Version: 2.6.0 Release: 0 Summary: BSD function library License: MIT AND X11 ++++++ libite-2.5.3.tar.gz -> libite-2.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/.github/workflows/build.yml new/libite-2.6.0/.github/workflows/build.yml --- old/libite-2.5.3/.github/workflows/build.yml 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/.github/workflows/build.yml 2023-09-17 16:59:24.000000000 +0200 @@ -28,7 +28,7 @@ run: | sudo apt-get -y update sudo apt-get -y install tree doxygen - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Configure run: | ./autogen.sh @@ -44,7 +44,7 @@ run: | make check || (cat test/test-suite.log; false) - name: Upload Test Results - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: libite-test-${{ matrix.compiler }} path: test/* @@ -55,7 +55,7 @@ env: MAKEFLAGS: -j3 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Installing dependencies run: | apt-get update diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/.github/workflows/coverity.yml new/libite-2.6.0/.github/workflows/coverity.yml --- old/libite-2.5.3/.github/workflows/coverity.yml 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/.github/workflows/coverity.yml 2023-09-17 16:59:24.000000000 +0200 @@ -15,7 +15,7 @@ coverity: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Fetch latest Coverity Scan MD5 id: var env: @@ -24,10 +24,8 @@ wget -q https://scan.coverity.com/download/cxx/linux64 \ --post-data "token=$TOKEN&project=${COVERITY_PROJ}&md5=1" \ -O coverity-latest.tar.gz.md5 - export MD5=$(cat coverity-latest.tar.gz.md5) - echo "Got MD5 $MD5" - echo ::set-output name=md5::${MD5} - - uses: actions/cache@v2 + echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT + - uses: actions/cache@v3 id: cache with: path: coverity-latest.tar.gz @@ -76,7 +74,7 @@ --form description="${PROJECT_NAME} $(git rev-parse HEAD)" \ https://scan.coverity.com/builds?project=${COVERITY_PROJ} - name: Upload build.log - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: coverity-build.log path: cov-int/build-log.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/.github/workflows/release.yml new/libite-2.6.0/.github/workflows/release.yml --- old/libite-2.5.3/.github/workflows/release.yml 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/.github/workflows/release.yml 2023-09-17 16:59:24.000000000 +0200 @@ -7,38 +7,11 @@ jobs: release: - name: Create GitHub release - runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/') - outputs: - upload_url: ${{ steps.create_release.outputs.upload_url }} - release_id: ${{ steps.create_release.outputs.id }} - steps: - - uses: actions/checkout@v2 - - name: Extract ChangeLog entry ... - # Hack to extract latest entry for body_path below - run: | - awk '/-----*/{if (x == 1) exit; x=1;next}x' ChangeLog.md \ - |head -n -1 > release.md - cat release.md - - name: Create release ... - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Libite (-lite) ${{ github.ref }} - body_path: release.md - draft: false - prerelease: false - tarball: name: Build and upload release tarball - needs: release if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Installing dependencies ... run: | sudo apt-get -y update @@ -46,17 +19,19 @@ - name: Creating Makefiles ... run: | ./autogen.sh - ./configure + ./configure --prefix= - name: Build release ... run: | - make release || (cat test/test-suite.log; false) - ls -lF ../ + make release mkdir -p artifacts/ mv ../*.tar.* artifacts/ - - name: Upload release artifacts ... - uses: skx/[email protected] - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Extract ChangeLog entry ... + run: | + awk '/-----*/{if (x == 1) exit; x=1;next}x' ChangeLog.md \ + |head -n -1 > release.md + cat release.md + - uses: ncipollo/release-action@v1 with: - releaseId: ${{ needs.release.outputs.release_id }} - args: artifacts/* + name: Libite (-lite) ${{ github.ref_name }} + bodyFile: "release.md" + artifacts: "artifacts/*" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/ChangeLog.md new/libite-2.6.0/ChangeLog.md --- old/libite-2.5.3/ChangeLog.md 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/ChangeLog.md 2023-09-17 16:59:24.000000000 +0200 @@ -4,6 +4,22 @@ All notable changes to the project are documented in this file. +[v2.6.0][] - 2023-09-17 +----------------------- + +### Changes +- New APIs from the [Infix Project](https://github.com/kernelkit/infix): + - `fexistf()` + - `vfopenf()` + - `popenf()` + - `vreadsnf()`, `readsnf()`, `writesf()` + - `vreadllf()`, `readllf()`, `readdf()` + - `writellf()`, `writedf()` + +### Fixes +- Spellchecking of API docs + + [v2.5.3][] - 2023-04-08 ----------------------- @@ -488,7 +504,9 @@ Initial extraction of frog DNA from [Finit][]. See [README][] for API details. -[UNRELEASED]: https://github.com/troglobit/libite/compare/v2.5.2...HEAD +[UNRELEASED]: https://github.com/troglobit/libite/compare/v2.5.3...HEAD +[v2.6.0]: https://github.com/troglobit/libite/compare/v2.5.3...v2.6.0 +[v2.5.3]: https://github.com/troglobit/libite/compare/v2.5.2...v2.5.3 [v2.5.2]: https://github.com/troglobit/libite/compare/v2.5.1...v2.5.2 [v2.5.1]: https://github.com/troglobit/libite/compare/v2.5.0...v2.5.1 [v2.5.0]: https://github.com/troglobit/libite/compare/v2.4.1...v2.5.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/LICENSE new/libite-2.6.0/LICENSE --- old/libite-2.5.3/LICENSE 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/LICENSE 2023-09-17 16:59:24.000000000 +0200 @@ -1,5 +1,5 @@ Copyright (c) 2008-2010 Claudio Matsuoka <[email protected]> -Copyright (c) 2008-2021 Joachim Wiberg <[email protected]> +Copyright (c) 2008-2023 Joachim Wiberg <[email protected]> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/TODO.org new/libite-2.6.0/TODO.org --- old/libite-2.5.3/TODO.org 1970-01-01 01:00:00.000000000 +0100 +++ new/libite-2.6.0/TODO.org 2023-09-17 16:59:24.000000000 +0200 @@ -0,0 +1 @@ +* TODO Write tests for new APIs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/configure.ac new/libite-2.6.0/configure.ac --- old/libite-2.5.3/configure.ac 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/configure.ac 2023-09-17 16:59:24.000000000 +0200 @@ -1,4 +1,4 @@ -AC_INIT(libite, 2.5.3, https://github.com/troglobit/libite/issues) +AC_INIT(libite, 2.6.0, https://github.com/troglobit/libite/issues) AC_CONFIG_AUX_DIR(aux) AM_INIT_AUTOMAKE([1.11 foreign dist-xz]) AM_SILENT_RULES([yes]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/debian/changelog new/libite-2.6.0/debian/changelog --- old/libite-2.5.3/debian/changelog 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/debian/changelog 2023-09-17 16:59:24.000000000 +0200 @@ -1,3 +1,16 @@ +libite (2.6.0) stable; urgency=medium + + * New APIs from Infix Project: + - fexistf() + - vfopenf() + - popenf() + - vreadsnf(), readsnf(), writesf() + - vreadllf(), readllf(), readdf() + - writellf(), writedf() + * Spellchecking of API docs + + -- Joachim Wiberg <[email protected]> Sun, 17 Sep 2023 12:16:47 +0200 + libite (2.5.3) stable; urgency=medium * rsync() does not copy single files correctly diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/doc/API.md new/libite-2.6.0/doc/API.md --- old/libite-2.5.3/doc/API.md 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/doc/API.md 2023-09-17 16:59:24.000000000 +0200 @@ -124,7 +124,7 @@ Check for the existence of a directory, returns True(1) or False(0). -- `fopenf(mode, fmt, ...)` +- `fopenf(mode, fmt, ...)` and `vfopenf(mode, fmt, ap)` Like `fopen()`, but takes a formatted string as argument. This greatly simplifies operations that usually consist of composing a @@ -249,6 +249,19 @@ `delete`, it is now called `opt`. The APIs are 100% compatible if the value `1` was used. +- `runbg(cmd, delay)` + + Run a command in the background, after delay microseconds, essentially + a background `execvp()` with a delay. The function employs double-fork + to prevent zombies and closes all open files, including stdio. + +```C + char *cmd[] = { "sh", "-c", "echo 'hej' >/tmp/foo", NULL}; + + runbg(cmd, 200000); /* Create /tmp/foo after 200 millisec */ + /* Execution continues here immediately */ +``` + - `strmatch(str, list)`, `strnmatch(str, list, len)` Find matching string in an array of strings. Returns index in array on @@ -307,6 +320,76 @@ yes (both `y` and `Y` are handled) and `FALSE` for everything else. +Procfile Functions +------------------ + +These functions can be used to simplify access to data in `/proc` and +`/sys` on a Linux system. + +### String Functions + +- `readsnf(line, len, fmt, ...)` + + Read first line from a file composed from `fmt`, with optional args. + At most `len` bytes from the file are stored in `line`. + + On success this function returns `line` with any trailing newlines + `chomp()`ed off. On error `NULL` is returned. + +- `vreadsnf(line, len, fmt, ap)` + + Similar to `readsnf()` but takes a `va_list` argument instead. + +- `writesf(str, mode, fmt, ...)` + + Write the string buffer `str`, with an additional newline, to a file + composed from `fmt`, with optional args. The file is opened with the + given `mode`, e.g. "w+", which allows for both replacing and appending + file content. + + The function returns POSIX OK(0) on success or -1 on failure with the + `errno` variable set to a value from either `fopen()` or `fclose()`. + +### Integer Functions + +Read and write 32-bit and 64-bit signed values from/to files. + +- `vreadllf(value, fmt, ap)` and `readllf(value, fmt, ...)` + + Only the first line is read. If the line has newline that is stripped + before calling `strtoll()` on the line. The arguments to the latter + function is such that it can convert also from a hexadecimal value. + + This function may fail and return -1 on opening the file, reading a + line, or if the `strtoll()` function fails. All of which set the + `errno` variable. Otherwise this function return POSIX OK(0). + +- `readdf(value, fmt, ...)` + + Read a signed 32-bit value from a file composed from `fmt`, with + optional args. This function use `vreadllf()` with an additional + range checking for `INT_MIN` and `INT_MAX`. Values outside that + cause this function to return -1 with `errno` set to `ERANGE`. + +- `writedf(value, mode, fmt, ...)` + + Write a signed 32-bit `value` to a file composed from `fmt`, with + optional args. The file is opened with the given `mode`, e.g. "w+", + which allows for both replacing and appending file content. + + The function returns POSIX OK(0) on success or -1 on failure with the + `errno` variable set to a value from either `fopen()` or `fclose()`. + +- `writellf(value, mode, fmt, ...)` + + Write a signed 64-bit `value` to a file composed from `fmt`, with + optional args. The file is opened with the given `mode`, e.g. "w+", + which allows for both replacing and appending file content. + + The function returns POSIX OK(0) on success or -1 on failure with the + `errno` variable set to a value from either `fopen()` or `fclose()`. + + GNU Functions ------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/src/Makefile.am new/libite-2.6.0/src/Makefile.am --- old/libite-2.5.3/src/Makefile.am 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/src/Makefile.am 2023-09-17 16:59:24.000000000 +0200 @@ -2,21 +2,21 @@ libite_la_CPPFLAGS = -D_GNU_SOURCE libite_la_CFLAGS = -W -Wall -Wextra -libite_la_LDFLAGS = $(AM_LDFLAGS) -version-info 8:2:3 +libite_la_LDFLAGS = $(AM_LDFLAGS) -version-info 9:0:4 libite_la_SOURCES = chomp.c copyfile.c \ conio.c conio.h dir.c \ erasef.c fopenf.c fremove.c \ fexist.c fisdir.c \ fparseln.c fsendfile.c \ ifconfig.c lfile.c \ - makepath.c progress.c \ - pidfile.c pidfilefn.c \ - reallocarray.c rsync.c strtrim.c \ + makepath.c procval.c progress.c \ + pidfile.c pidfilefn.c popenf.c \ + reallocarray.c rsync.c runbg.c \ strlcpy.c strlcat.c strtonum.c \ strdupa.h strndupa.h strnlen.h \ - strmatch.c systemf.c touchf.c \ + strmatch.c systemf.c strtrim.c \ telnet.c tempfile.c truncatef.c \ - yorn.c which.c \ + touchf.c yorn.c which.c \ lite.h strlite.h \ queue.h tree.h diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/src/fexist.c new/libite-2.6.0/src/fexist.c --- old/libite-2.5.3/src/fexist.c 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/src/fexist.c 2023-09-17 16:59:24.000000000 +0200 @@ -29,8 +29,13 @@ */ #include <errno.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> #include <unistd.h> +#include "lite.h" + /** * Check if a file exists in the file system. * @param file File to look for, with full path. @@ -51,6 +56,39 @@ } /** + * Like fexist() but with formatted string support + * @param fmt Formatted string to be composed into the file to look for. + * + * This is a wrapper for the fexist() function in lite.h, lessening the + * burden of having to compose the filename from parts in a seprate + * buffer. + * + * @returns @c TRUE(1) if the @a file exists, otherwise @c FALSE(0). + */ +int fexistf(const char *fmt, ...) +{ + va_list ap; + char *file; + int len; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + file = alloca(len + 1); + if (!file) { + errno = ENOMEM; + return -1; + } + + va_start(ap, fmt); + vsnprintf(file, len + 1, fmt, ap); + va_end(ap); + + return fexist(file); +} + +/** * Local Variables: * indent-tabs-mode: t * c-file-style: "linux" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/src/fopenf.c new/libite-2.6.0/src/fopenf.c --- old/libite-2.5.3/src/fopenf.c 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/src/fopenf.c 2023-09-17 16:59:24.000000000 +0200 @@ -28,26 +28,24 @@ #include <stdlib.h> /** - * Open a file based on the formatted string and optional arguments - * @param mode An fopen() mode string, e.g. "w+" - * @param fmt Formatted string to be composed into a pathname + * Similar to fopenf() except it takes a @a va_list argument + * @param mode An fopen() mode string, e.g. "w+". + * @param fmt Formatted string to be composed into a pathname. + * @param ap List of variable arguemnts from va_start(). * - * This function is an extension to the fopen() family, lessening the burden - * of first having to compose the filename from parts in a seprate buffer. + * See fopenf() for details. * - * @returns Upon successful completion, fopenf() returns a FILE pointer. - * Otherwise, @c NULL is returned and @a errno is set to indicate the - * error. + * @returns a FILE pointer, or @c NULL on error. */ -FILE *fopenf(const char *mode, const char *fmt, ...) +FILE *vfopenf(const char *mode, const char *fmt, va_list ap) { - va_list ap; + va_list apc; char *file; int len; - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap); - va_end(ap); + va_copy(apc, ap); + len = vsnprintf(NULL, 0, fmt, apc); + va_end(apc); file = alloca(len + 1); if (!file) { @@ -55,11 +53,37 @@ return NULL; } + va_copy(apc, ap); + vsnprintf(file, len + 1, fmt, apc); + va_end(apc); + + return fopen(file, mode); +} + +/** + * Open a file based on the formatted string and optional arguments + * @param mode An fopen() mode string, e.g. "w+". + * @param fmt Formatted string to be composed into a pathname. + * + * This function is an extension to the fopen() family, lessening the burden + * of first having to compose the filename from parts in a seprate buffer. + * + * @returns Upon successful completion, fopenf() returns a FILE pointer. + * Otherwise, @c NULL is returned and @a errno is set to indicate the + * error. + */ +FILE *fopenf(const char *mode, const char *fmt, ...) +{ + va_list ap; + FILE *fp; + va_start(ap, fmt); - vsnprintf(file, len + 1, fmt, ap); + fp = vfopenf(mode, fmt, ap); va_end(ap); + if (!fp) + return NULL; - return fopen(file, mode); + return fp; } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/src/lite.h new/libite-2.6.0/src/lite.h --- old/libite-2.5.3/src/lite.h 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/src/lite.h 2023-09-17 16:59:24.000000000 +0200 @@ -1,7 +1,7 @@ /* Collection of frog DNA * * Copyright (c) 2008-2010 Claudio Matsuoka <[email protected]> - * Copyright (c) 2008-2021 Joachim Wiberg <[email protected]> + * Copyright (c) 2008-2023 Joachim Wiberg <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,7 @@ * Collection of frog DNA * @file lite.h * @author Claudio Matsuoka (2008-2010) - * @author Joachim Wiberg (2008-2021) + * @author Joachim Wiberg (2008-2023) * @copyright MIT License * * The latest version of this manual and the libite (-lite) software @@ -77,8 +77,10 @@ char *fparseln (FILE *, size_t *, size_t *, const char[3], int); int fexist (const char *file); +int fexistf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));; int fisdir (const char *path); +FILE *vfopenf (const char *mode, const char *fmt, va_list ap); FILE *fopenf (const char *mode, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); int fremove (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); FILE *tempfile (void); @@ -88,6 +90,16 @@ 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); @@ -104,6 +116,8 @@ int dir (const char *dir, const char *type, int (*filter) (const char *file), char ***list, int strip); int rsync (char *src, char *dst, int opt, int (*filter) (const char *file)); +FILE *popenf (const char *type, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); + int pidfile (const char *basename); int pidfile_signal(const char *pidfile, int signal); pid_t pidfile_read (const char *pidfile); @@ -114,6 +128,7 @@ void progress (int percent, int max_width); void progress_simple(int percent); +int runbg (char *const cmd[], int delay); int systemf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); sdbuf_t*telnet_open (int addr, short port); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/src/popenf.c new/libite-2.6.0/src/popenf.c --- old/libite-2.5.3/src/popenf.c 1970-01-01 01:00:00.000000000 +0100 +++ new/libite-2.6.0/src/popenf.c 2023-09-17 16:59:24.000000000 +0200 @@ -0,0 +1,63 @@ +/* Formatted popen() + * + * Copyright (c) 2023 Tobias Waldekranz <[email protected]> + * Copyright (c) 2023 Joachim Wiberg <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> + +/** + * Formatted pipe stream to or from a process + * @param type A popen() type, "r" or "w", can also include "e" for @c O_CLOEXEC. + * @param fmt Formatted string to be composed into a shell command line. + * + * This function is an extension to popen(), lessening the burden of + * first having to compose the filename from parts in a seprate buffer. + * + * @returns Upon successful completion, popenf() returns a FILE pointer. + * Otherwise, @c NULL is returned and @a errno is set to indicate the + * error. + */ +FILE *popenf(const char *type, const char *fmt, ...) +{ + va_list ap; + char *cmd; + int len; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + cmd = alloca(len + 1); + if (!cmd) { + errno = ENOMEM; + return NULL; + } + + va_start(ap, fmt); + vsnprintf(cmd, len + 1, fmt, ap); + va_end(ap); + + return popen(cmd, type); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/src/procval.c new/libite-2.6.0/src/procval.c --- old/libite-2.5.3/src/procval.c 1970-01-01 01:00:00.000000000 +0100 +++ new/libite-2.6.0/src/procval.c 2023-09-17 16:59:24.000000000 +0200 @@ -0,0 +1,229 @@ +/* Reading and writing values/strings to/from /proc and /sys style files + * + * Copyright (c) 2023 Tobias Waldekranz <[email protected]> + * Copyright (c) 2023 Joachim Wiberg <[email protected]> + * + * 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, apc); + va_end(apc); + 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() except 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: + */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/src/runbg.c new/libite-2.6.0/src/runbg.c --- old/libite-2.5.3/src/runbg.c 1970-01-01 01:00:00.000000000 +0100 +++ new/libite-2.6.0/src/runbg.c 2023-09-17 16:59:24.000000000 +0200 @@ -0,0 +1,93 @@ +/* Run a command in the background: fork() + usleep() + execvp() + * + * Copyright (c) 2023 Joachim Wiberg <[email protected]> + * + * 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 runbg.c + * @author Joachim Wiberg + * @date 2023 + * @copyright ISC License + */ + +#include <errno.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +/** + * Run command in the background + * @param cmd NULL terminated list of command and optional arguments + * @param delay Microseconds after fork() to wait before calling cmd + * + * This function forks to run the given command @p cmd in the background. + * To ensure there are no lingering zombies the function actuall forks + * twice, and also calls setsid(), before it calls usleep() with the @p + * delay argument. The command @p cmd is handed over to execvp(). + * + * Since it runs in the background it is not possible to get the return + * code of the command. + * + * @returns on successful (first) fork(), this function returns POSIX + * OK(0), otherwise -1 and @a errno is set to indicate the error. + */ +int runbg(char *const cmd[], int delay) +{ + int pid = fork(); + int rc; + + if (!pid) { + int fd, maxfd; + + if (setsid() == -1) + _exit(errno); + + /* reparent to init */ + pid = fork(); + if (pid == -1) + _exit(errno); + if (pid > 0) + _exit(0); + + maxfd = sysconf(_SC_OPEN_MAX); + if (maxfd == -1) + maxfd = 8192; + for (fd = 0; fd < maxfd; fd++) + close(fd); + + usleep(delay); + _exit(execvp(cmd[0], cmd)); + } + + if (pid == -1) + return -1; + + if (waitpid(pid, &rc, 0) == -1) + return -1; + + if (WIFEXITED(rc)) { + errno = WEXITSTATUS(rc); + if (errno) + rc = -1; + else + rc = 0; + } else if (WIFSIGNALED(rc)) { + errno = EINTR; + rc = -1; + } else + rc = -1; + + return rc; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/test/.gitignore new/libite-2.6.0/test/.gitignore --- old/libite-2.5.3/test/.gitignore 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/test/.gitignore 2023-09-17 16:59:24.000000000 +0200 @@ -15,6 +15,7 @@ /printhdr /progress /rsync +/runbg /str /strmatch /systemf diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/test/Makefile.am new/libite-2.6.0/test/Makefile.am --- old/libite-2.5.3/test/Makefile.am 2023-04-08 07:05:58.000000000 +0200 +++ new/libite-2.6.0/test/Makefile.am 2023-09-17 16:59:24.000000000 +0200 @@ -30,6 +30,7 @@ TESTS += printhdr TESTS += progress TESTS += rsync +TESTS += runbg TESTS += str TESTS += strmatch TESTS += systemf diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libite-2.5.3/test/runbg.c new/libite-2.6.0/test/runbg.c --- old/libite-2.5.3/test/runbg.c 1970-01-01 01:00:00.000000000 +0100 +++ new/libite-2.6.0/test/runbg.c 2023-09-17 16:59:24.000000000 +0200 @@ -0,0 +1,23 @@ +#include "check.h" + +#define file "/tmp/runbg.txt" + +int main(void) +{ + char *cmd[] = { + "sh", "-c", "echo 'hello world' > " file, NULL + }; + + erase(file); + test(runbg(cmd, 100000), "Calling runbg"); + + if (test(fexist(file), "Verifying %s does not yet exist", file)) + return 1; + + test(sleep(1), "Waiting for runbg"); + + if (test(!fexist(file), "Verifying %s has been created", file)) + return 1; + + return 0; +}
