Skip to content

Commit

Permalink
system() avoidance: Add lib/proc.c for process manipulation
Browse files Browse the repository at this point in the history
- Add new functions `proc_runv()` and `proc_runl()`.
- Add new macro `PROC_CMD()`.
  • Loading branch information
IepIweidieng committed Oct 5, 2020
1 parent cafca07 commit 2e9c2df
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
6 changes: 6 additions & 0 deletions include/dao.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,17 @@ char *Ctime(const time_t *clock);
char *Etime(const time_t *clock);
char *Atime(const time_t *clock);
char *Now(void);
/* proc.c */
int proc_runv(const char *path, const char *argv[]);
GCC_CHECK_SENTINEL(0) int proc_runl(const char *path, const char *arg0, ...);
/* xwrite.c */
int xwrite(int fd, const char *data, int size);

#ifdef __cplusplus
} /* extern "C" */
#endif

/* `proc_runl` without the need of `arg0` and trailing `NULL` */
#define PROC_CMD(path, ...) proc_runl(path, path, __VA_ARGS__, NULL)

#endif /* DAO_H */
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ add_library(dao STATIC
acl.c chrono32.c file.c isnot.c radix32.c shm.c
archiv32.c dl_lib.c record.c splay.c date_str.c xsort.c
attr_lib.c dns.c header.c rfc2047.c string.c xwrite.c
proc.c
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
target_link_libraries(dao PRIVATE -m32)
Expand Down
6 changes: 4 additions & 2 deletions lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ HDR = dao.h dao.p

SRC = acl.c chrono32.c file.c isnot.c radix32.c shm.c \
archiv32.c dl_lib.c record.c splay.c date_str.c xsort.c \
attr_lib.c dns.c header.c rfc2047.c string.c xwrite.c
attr_lib.c dns.c header.c rfc2047.c string.c xwrite.c \
proc.c

OBJ = acl.o chrono32.o file.o isnot.o radix32.o shm.o \
archiv32.o dl_lib.o record.o splay.o date_str.o xsort.o \
attr_lib.o dns.o header.o rfc2047.o string.o xwrite.o
attr_lib.o dns.o header.o rfc2047.o string.o xwrite.o \
proc.o

.c.o: ;$(CC) $(CFLAGS) -c $*.c

Expand Down
78 changes: 78 additions & 0 deletions lib/proc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*-------------------------------------------------------*/
/* lib/proc.c ( NCKU CCNS WindTop-DreamBBS 3.0 ) */
/*-------------------------------------------------------*/
/* Author: [email protected]*/
/* Target: Process manipulation library for DreamBBS */
/* Create: 2020/02/24 */
/*-------------------------------------------------------*/

#include "config.h"

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
#include "dao.h"

/* `proc_run*()`: Run executable `path` in a child process */

int proc_runv(const char *path, const char *argv[])
{
const pid_t pid = fork();

switch (pid)
{
case 0: // Children
execv(path, (char **)argv);
exit(127); // `execv()` failed

case -1: // Error
return -1;

default:
waitpid(pid, &SINKVAL(int), 0);
return 0;
}
}

/* Variadic version for convenience */
GCC_CHECK_SENTINEL(0)
int proc_runl(const char *path, const char *arg0, ...)
{
/* Collect args first */

int argc = 0;
int argv_len = 8;
const char **argv = (const char **)malloc(sizeof(const char *) * argv_len);
const char *ptr;
int ret;

argv[argc++] = arg0;

if (arg0)
{
va_list args;
va_start(args, arg0);
while ((ptr = va_arg(args, const char *)))
{
argv[argc++] = ptr;
if (argc >= argv_len)
{
const char **argv_new = (const char **)realloc(argv, sizeof(const char *) * (argv_len *= 2));
if (!argv_new)
return -1; // `realloc()` failed
argv = argv_new;
}
}
va_end(args);

argv[argc++] = NULL;
}

/* And then invoke it */

ret = proc_runv(path, argv);
free(argv);
return ret;
}

0 comments on commit 2e9c2df

Please sign in to comment.