mirror of
https://github.com/troglobit/libite.git
synced 2026-10-19 10:59:32 +00:00
Add support for systemf(), formatted system() replacement
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
1 parent
7f3f4df9e9
commit
f1a1a21569
7 files changed
+116
-1
No files matched your search
@@ -304,6 +304,12 @@ Generic Functions
|
||||
Find matching string in an array of strings. Returns index in array
|
||||
on match, or `-1` on error or not found.
|
||||
|
||||
`systemf(fmt, ...)`
|
||||
|
||||
Like `system()`, but takes a formatted string as argument. This
|
||||
greatly simplifies operations that usually consist of composing a
|
||||
command from parts into a dynamic buffer before calling it.
|
||||
|
||||
- `telnet_open(), telnet_close(), telnet_expect()`
|
||||
|
||||
Poor mans telnet expect in C. Opens connection to a Telnet service;
|
||||
|
||||
+2
-1
@@ -14,7 +14,8 @@ libite_la_SOURCES = chomp.c copyfile.c \
|
||||
reallocarray.c rsync.c \
|
||||
strlcpy.c strlcat.c strtonum.c \
|
||||
strdupa.h strndupa.h strnlen.h \
|
||||
strmatch.c telnet.c tempfile.c \
|
||||
strmatch.c systemf.c \
|
||||
telnet.c tempfile.c \
|
||||
yorn.c which.c \
|
||||
lite.h strlite.h \
|
||||
queue.h tree.h
|
||||
|
||||
@@ -98,6 +98,8 @@ void *reallocarray(void *optr, size_t nmemb, size_t size);
|
||||
void progress (int percent, int max_width);
|
||||
void progress_simple(int percent);
|
||||
|
||||
int systemf (const char *fmt, ...);
|
||||
|
||||
sdbuf_t*telnet_open (int addr, short port);
|
||||
int telnet_close (sdbuf_t *ctx);
|
||||
int telnet_expect (sdbuf_t *ctx, char *script[], FILE *output);
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/* Formatted system() which returns actual return status of command
|
||||
*
|
||||
* Copyright (c) 2020 Joachim Nilsson <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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int systemf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *cmd;
|
||||
int len, status;
|
||||
int rc = -1;
|
||||
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(NULL, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
va_start(ap, fmt);
|
||||
cmd = alloca(++len);
|
||||
if (!cmd) {
|
||||
va_end(ap);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
vsnprintf(cmd, len, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
status = system(cmd);
|
||||
|
||||
rc = WEXITSTATUS(status);
|
||||
if (!WIFEXITED(status)) {
|
||||
if (WIFSIGNALED(status) &&
|
||||
(WTERMSIG(status) == SIGINT ||
|
||||
WTERMSIG(status) == SIGQUIT)) {
|
||||
errno = EINTR;
|
||||
rc = -1;
|
||||
} else if (!rc) {
|
||||
/*
|
||||
* Alert callee that command didn't complete
|
||||
* successfully. Some programs don't change
|
||||
* their exit code when signaled.
|
||||
*/
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Local Variables:
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
@@ -17,6 +17,7 @@ progress
|
||||
rsync
|
||||
str
|
||||
strmatch
|
||||
systemf
|
||||
tempfile
|
||||
touch
|
||||
tree
|
||||
|
||||
@@ -17,6 +17,7 @@ TESTS += progress
|
||||
TESTS += rsync
|
||||
TESTS += str
|
||||
TESTS += strmatch
|
||||
TESTS += systemf
|
||||
TESTS += touch
|
||||
TESTS += tempfile
|
||||
TESTS += which
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <err.h>
|
||||
#include "check.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct { char *cmd; int rc; } list[] = {
|
||||
{ "false", 1 },
|
||||
{ "true", 0 },
|
||||
{ "kill -9 $$", 1 },
|
||||
{ "kill -QUIT $$", -1 },
|
||||
{ "kill -INT $$", -1 }
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < NELEMS(list); i++) {
|
||||
int rc;
|
||||
|
||||
rc = systemf("%s", list[i].cmd);
|
||||
if (rc != list[i].rc)
|
||||
err(rc, "Failed command %s", list[i].cmd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Local Variables:
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user