diff options
-rw-r--r-- | Makefile | 24 | ||||
-rw-r--r-- | bindtemp_un.c | 6 | ||||
-rw-r--r-- | common.h | 4 | ||||
-rw-r--r-- | config.mk | 2 | ||||
-rw-r--r-- | execlat.c | 27 | ||||
-rw-r--r-- | execleat.c | 27 | ||||
-rw-r--r-- | execlpe.c | 27 | ||||
-rw-r--r-- | execvat.c | 22 | ||||
-rw-r--r-- | execveat.c | 56 | ||||
-rw-r--r-- | execvpe.c | 22 | ||||
-rw-r--r-- | fexecl.c | 27 | ||||
-rw-r--r-- | fexecle.c | 27 | ||||
-rw-r--r-- | fexecv.c | 22 | ||||
-rw-r--r-- | libsimple.c | 2 | ||||
-rw-r--r-- | libsimple.h | 2 | ||||
-rw-r--r-- | libsimple/ascii.h | 657 | ||||
-rw-r--r-- | libsimple/env.h | 7 | ||||
-rw-r--r-- | libsimple/exec.h | 99 | ||||
-rw-r--r-- | vexecl.c | 22 | ||||
-rw-r--r-- | vexeclat.c | 28 | ||||
-rw-r--r-- | vexecle.c | 22 | ||||
-rw-r--r-- | vexecleat.c | 30 | ||||
-rw-r--r-- | vexeclp.c | 22 | ||||
-rw-r--r-- | vexeclpe.c | 22 | ||||
-rw-r--r-- | vfexecl.c | 22 | ||||
-rw-r--r-- | vfexecle.c | 28 | ||||
-rw-r--r-- | vxexecl.c | 35 | ||||
-rw-r--r-- | vxexecle.c | 28 | ||||
-rw-r--r-- | which.c | 92 | ||||
-rw-r--r-- | xexecl.c | 27 | ||||
-rw-r--r-- | xexecv.c | 31 |
31 files changed, 1464 insertions, 5 deletions
@@ -28,9 +28,11 @@ SUBHDR =\ libsimple/aligned_wcsndup.h\ libsimple/aligned_wmemdup.h\ libsimple/array.h\ + libsimple/ascii.h\ libsimple/calloc.h\ libsimple/definitions.h\ libsimple/env.h\ + libsimple/exec.h\ libsimple/malloc.h\ libsimple/mallocz.h\ libsimple/mem.h\ @@ -236,6 +238,15 @@ OBJ =\ ewcsdup.o\ ewcsndup.o\ ewmemdup.o\ + execlat.o\ + execleat.o\ + execlpe.o\ + execvat.o\ + execveat.o\ + execvpe.o\ + fexecl.o\ + fexecle.o\ + fexecv.o\ generate_seed.o\ getcwd.o\ getenv_e.o\ @@ -501,6 +512,14 @@ OBJ =\ vcallocn.o\ venprintf.o\ veprintf.o\ + vexecl.o\ + vexeclat.o\ + vexecle.o\ + vexecleat.o\ + vexeclp.o\ + vexeclpe.o\ + vfexecl.o\ + vfexecle.o\ vmallocn.o\ vmemalignn.o\ vmemalignzn.o\ @@ -513,9 +532,14 @@ OBJ =\ vvallocn.o\ vvalloczn.o\ vweprintf.o\ + vxexecl.o\ + vxexecle.o\ wcsndup.o\ weprintf.o\ + which.o\ wmemdup.o\ + xexecl.o\ + xexecv.o\ zabs.o\ zdiff.o\ libsimple.o diff --git a/bindtemp_un.c b/bindtemp_un.c index 0362e47..5f0de05 100644 --- a/bindtemp_un.c +++ b/bindtemp_un.c @@ -57,8 +57,8 @@ libsimple_bindtemp_un(int fd, int dir_fd, struct sockaddr_un *addr, socklen_t *a len = snprintf(addr->sun_path, sizeof(addr->sun_path), "/dev/fd/%i/tmp", dir_fd); if (len < 0 || (size_t)len >= sizeof(addr->sun_path) || sizeof(addr->sun_path) - (size_t)len < 6) abort(); - rem = sizeof(addr->sun_path) - 1 - len; - addr->sun_path[sizeof(addr->sun_path) - 1] = 0; + rem = sizeof(addr->sun_path) - 1U - (size_t)len; + addr->sun_path[sizeof(addr->sun_path) - 1U] = 0; while (try_limit--) { again: @@ -67,7 +67,7 @@ libsimple_bindtemp_un(int fd, int dir_fd, struct sockaddr_un *addr, socklen_t *a errno = saved_errno; return 0; } else if (errno == ENAMETOOLONG && rem > 5) { - addr->sun_path[len + --rem] = 0; + addr->sun_path[(size_t)len + --rem] = 0; goto again; } else if (errno != EEXIST && errno != EADDRINUSE) { return -1; @@ -9,3 +9,7 @@ # pragma clang diagnostic ignored "-Wc++98-compat" # pragma clang diagnostic ignored "-Wcovered-switch-default" #endif + +#ifdef execveat +# undef execveat +#endif @@ -3,6 +3,6 @@ MANPREFIX = $(PREFIX)/share/man CC = cc -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE CFLAGS = -std=c11 -Wall -Wextra -O2 LDFLAGS = -s -lm diff --git a/execlat.c b/execlat.c new file mode 100644 index 0000000..37f7fbb --- /dev/null +++ b/execlat.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_execlat(int dirfd, const char *pathname, ... /* argv, NULL, int flags */) +{ + int ret; + va_list args; + va_start(args, pathname); + ret = libsimple_vexeclat(dirfd, pathname, args); + va_end(args); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/execleat.c b/execleat.c new file mode 100644 index 0000000..c72e1de --- /dev/null +++ b/execleat.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_execleat(int dirfd, const char *pathname, ... /* argv, NULL, char *const envp[], int flags */) +{ + int ret; + va_list args; + va_start(args, pathname); + ret = libsimple_vexecleat(dirfd, pathname, args); + va_end(args); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/execlpe.c b/execlpe.c new file mode 100644 index 0000000..034eb6e --- /dev/null +++ b/execlpe.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_execlpe(const char *file, ... /* argv, NULL, char *const envp[] */) +{ + int ret; + va_list args; + va_start(args, file); + ret = libsimple_vexeclpe(file, args); + va_end(args); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/execvat.c b/execvat.c new file mode 100644 index 0000000..ea5bb75 --- /dev/null +++ b/execvat.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_execvat(int dirfd, const char *pathname, char *const argv[], int flags) +{ + return execveat(dirfd, pathname, argv, environ, flags); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/execveat.c b/execveat.c new file mode 100644 index 0000000..ed7b11e --- /dev/null +++ b/execveat.c @@ -0,0 +1,56 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_execveat(int dirfd, const char *pathname, char *const argv[], char *const envp[], int flags) +{ + struct stat st; + int fd, saved_errno; + +#if defined(__linux__) + execveat(dirfd, pathname, argv, envp, flags); + if (errno != ENOSYS) + return -1; +#endif + + if (flags & AT_EMPTY_PATH) + return fexecve(dirfd, argv, envp); + +#ifndef O_PATH +# define O_PATH O_RDONLY +#endif + + fd = openat(dirfd, pathname, O_PATH | ((flags & AT_SYMLINK_NOFOLLOW) ? O_NOFOLLOW : 0)); + if (fd < 0) + return -1; + + if (flags & AT_SYMLINK_NOFOLLOW) { + if (fstat(fd, &st)) { + saved_errno = errno; + close(fd); + errno = saved_errno; + return -1; + } + if (S_ISLNK(st.st_mode)) { + close(fd); + errno = ELOOP; + return -1; + } + } + + return fexecve(fd, argv, envp); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/execvpe.c b/execvpe.c new file mode 100644 index 0000000..fe117a9 --- /dev/null +++ b/execvpe.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_execvpe(const char *file, char *const argv[], char *const envp[]) +{ + return libsimple_xexecv(-1, file, -1, NULL, envp, argv); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/fexecl.c b/fexecl.c new file mode 100644 index 0000000..4767fa4 --- /dev/null +++ b/fexecl.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_fexecl(int fd, ... /* argv, NULL */) +{ + int ret; + va_list args; + va_start(args, fd); + ret = libsimple_vfexecl(fd, args); + va_end(args); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/fexecle.c b/fexecle.c new file mode 100644 index 0000000..e70fbc2 --- /dev/null +++ b/fexecle.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_fexecle(int fd, ... /* argv, NULL, char *const envp[] */) +{ + int ret; + va_list args; + va_start(args, fd); + ret = libsimple_vfexecle(fd, args); + va_end(args); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/fexecv.c b/fexecv.c new file mode 100644 index 0000000..955ae58 --- /dev/null +++ b/fexecv.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_fexecv(int fd, char *const argv[]) +{ + return fexecve(fd, argv, environ); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/libsimple.c b/libsimple.c index 2bb5139..100a22c 100644 --- a/libsimple.c +++ b/libsimple.c @@ -70,7 +70,7 @@ test_timeval(double d, time_t sec, long int usec, double rd, const char *s, cons } #ifdef libsimple_vasprintfa -LIBSIMPLE_GCC_ONLY__(__attribute__((__format__(__printf__, 2, 0)))) +LIBSIMPLE_GCC_ONLY__(__attribute__((__format__(__printf__, 2, 3)))) static int test_vasprintfa(const char *expected, const char *format, ...) { diff --git a/libsimple.h b/libsimple.h index 2b45dfa..f1e479c 100644 --- a/libsimple.h +++ b/libsimple.h @@ -169,6 +169,8 @@ #include "libsimple/abs.h" #include "libsimple/net.h" #include "libsimple/path.h" +#include "libsimple/ascii.h" +#include "libsimple/exec.h" /** diff --git a/libsimple/ascii.h b/libsimple/ascii.h new file mode 100644 index 0000000..faaa99e --- /dev/null +++ b/libsimple/ascii.h @@ -0,0 +1,657 @@ +/* See LICENSE file for copyright and license details. */ + +/* TODO man, doc, test */ + + +#define LIBSIMPLE_CHAR_NUL '\x00' +#ifndef CHAR_NUL +# define CHAR_NUL LIBSIMPLE_CHAR_NUL +#endif +#define LIBSIMPLE_CHAR_NULL LIBSIMPLE_CHAR_NUL +#ifndef CHAR_NULL +# define CHAR_NULL LIBSIMPLE_CHAR_NULL +#endif + +#define LIBSIMPLE_CHAR_SOH '\x01' +#ifndef CHAR_SOH +# define CHAR_SOH LIBSIMPLE_CHAR_SOH +#endif +#define LIBSIMPLE_CHAR_START_OF_HEADING LIBSIMPLE_CHAR_SOH +#ifndef CHAR_START_OF_HEADING +# define CHAR_START_OF_HEADING LIBSIMPLE_CHAR_START_OF_HEADING +#endif + +#define LIBSIMPLE_CHAR_STX '\x02' +#ifndef CHAR_STX +# define CHAR_STX LIBSIMPLE_CHAR_STX +#endif +#define LIBSIMPLE_CHAR_START_OF_TEXT LIBSIMPLE_CHAR_STX +#ifndef CHAR_START_OF_TEXT +# define CHAR_START_OF_TEXT LIBSIMPLE_CHAR_START_OF_TEXT +#endif + +#define LIBSIMPLE_CHAR_ETX '\x03' +#ifndef CHAR_ETX +# define CHAR_ETX LIBSIMPLE_CHAR_ETX +#endif +#define LIBSIMPLE_CHAR_END_OF_TEXT LIBSIMPLE_CHAR_ETX +#ifndef CHAR_END_OF_TEXT +# define CHAR_END_OF_TEXT LIBSIMPLE_CHAR_END_OF_TEXT +#endif + +#define LIBSIMPLE_CHAR_EOT '\x04' +#ifndef CHAR_EOT +# define CHAR_EOT LIBSIMPLE_CHAR_EOT +#endif +#define LIBSIMPLE_CHAR_END_OF_TRANSMISSION LIBSIMPLE_CHAR_EOT +#ifndef CHAR_END_OF_TRANSMISSION +# define CHAR_END_OF_TRANSMISSION LIBSIMPLE_CHAR_END_OF_TRANSMISSION +#endif + +#define LIBSIMPLE_CHAR_ENQ '\x05' +#ifndef CHAR_ENQ +# define CHAR_ENQ LIBSIMPLE_CHAR_ENQ +#endif +#define LIBSIMPLE_CHAR_ENQUIRY LIBSIMPLE_CHAR_ENQ +#ifndef CHAR_ENQUIRY +# define CHAR_ENQUIRY LIBSIMPLE_CHAR_ENQUIRY +#endif + +#define LIBSIMPLE_CHAR_ACK '\x06' +#ifndef CHAR_ACK +# define CHAR_ACK LIBSIMPLE_CHAR_ACK +#endif +#define LIBSIMPLE_CHAR_ACKNOWLEDGE LIBSIMPLE_CHAR_ACK +#ifndef CHAR_ACKNOWLEDGE +# define CHAR_ACKNOWLEDGE LIBSIMPLE_CHAR_ACKNOWLEDGE +#endif + +#define LIBSIMPLE_CHAR_BEL '\x07' +#ifndef CHAR_BEL +# define CHAR_BEL LIBSIMPLE_CHAR_BEL +#endif +#define LIBSIMPLE_CHAR_BELL LIBSIMPLE_CHAR_BEL +#ifndef CHAR_BELL +# define CHAR_BELL LIBSIMPLE_CHAR_BELL +#endif + +#define LIBSIMPLE_CHAR_BS '\x08' +#ifndef CHAR_BS +# define CHAR_BS LIBSIMPLE_CHAR_BS +#endif +#define LIBSIMPLE_CHAR_BACKSPACE LIBSIMPLE_CHAR_BS +#ifndef CHAR_BACKSPACE +# define CHAR_BACKSPACE LIBSIMPLE_CHAR_BACKSPACE +#endif + +#define LIBSIMPLE_CHAR_HT '\x09' +#ifndef CHAR_HT +# define CHAR_HT LIBSIMPLE_CHAR_HT +#endif +#define LIBSIMPLE_CHAR_HORIZONTAL_TABULATION LIBSIMPLE_CHAR_HT +#ifndef CHAR_HORIZONTAL_TABULATION +# define CHAR_HORIZONTAL_TABULATION LIBSIMPLE_CHAR_HORIZONTAL_TABULATION +#endif + +#define LIBSIMPLE_CHAR_LF '\x0A' +#ifndef CHAR_LF +# define CHAR_LF LIBSIMPLE_CHAR_LF +#endif +#define LIBSIMPLE_CHAR_LINE_FEED LIBSIMPLE_CHAR_LF +#ifndef CHAR_LINE_FEED +# define CHAR_LINE_FEED LIBSIMPLE_CHAR_LINE_FEED +#endif + +#define LIBSIMPLE_CHAR_VT '\x0B' +#ifndef CHAR_VT +# define CHAR_VT LIBSIMPLE_CHAR_VT +#endif +#define LIBSIMPLE_CHAR_VERTICAL_TABULATION LIBSIMPLE_CHAR_VT +#ifndef CHAR_VERTICAL_TABULATION +# define CHAR_VERTICAL_TABULATION LIBSIMPLE_CHAR_VERTICAL_TABULATION +#endif + +#define LIBSIMPLE_CHAR_FF '\x0C' +#ifndef CHAR_FF +# define CHAR_FF LIBSIMPLE_CHAR_FF +#endif +#define LIBSIMPLE_CHAR_FORM_FEED LIBSIMPLE_CHAR_FF +#ifndef CHAR_FORM_FEED +# define CHAR_FORM_FEED LIBSIMPLE_CHAR_FORM_FEED +#endif + +#define LIBSIMPLE_CHAR_CR '\x0D' +#ifndef CHAR_CR +# define CHAR_CR LIBSIMPLE_CHAR_CR +#endif +#define LIBSIMPLE_CHAR_CARRIAGE_RETURN LIBSIMPLE_CHAR_CR +#ifndef CHAR_CARRIAGE_RETURN +# define CHAR_CARRIAGE_RETURN LIBSIMPLE_CHAR_CARRIAGE_RETURN +#endif + +#define LIBSIMPLE_CHAR_SO '\x0E' +#ifndef CHAR_SO +# define CHAR_SO LIBSIMPLE_CHAR_SO +#endif +#define LIBSIMPLE_CHAR_SHIFT_OUT LIBSIMPLE_CHAR_SO +#ifndef CHAR_SHIFT_OUT +# define CHAR_SHIFT_OUT LIBSIMPLE_CHAR_SHIFT_OUT +#endif + +#define LIBSIMPLE_CHAR_SI '\x0F' +#ifndef CHAR_SI +# define CHAR_SI LIBSIMPLE_CHAR_SI +#endif +#define LIBSIMPLE_CHAR_SHIFT_IN LIBSIMPLE_CHAR_SI +#ifndef CHAR_SHIFT_IN +# define CHAR_SHIFT_IN LIBSIMPLE_CHAR_SHIFT_IN +#endif + +#define LIBSIMPLE_CHAR_DLE '\x10' +#ifndef CHAR_DLE +# define CHAR_DLE LIBSIMPLE_CHAR_DLE +#endif +#define LIBSIMPLE_CHAR_DATA_LINK_ESCAPE LIBSIMPLE_CHAR_DLE +#ifndef CHAR_DATA_LINK_ESCAPE +# define CHAR_DATA_LINK_ESCAPE LIBSIMPLE_CHAR_DATA_LINK_ESCAPE +#endif + +#define LIBSIMPLE_CHAR_DC1 '\x11' +#ifndef CHAR_DC1 +# define CHAR_DC1 LIBSIMPLE_CHAR_DC1 +#endif +#define LIBSIMPLE_CHAR_DEVICE_CONTROL_1 LIBSIMPLE_CHAR_DC1 +#ifndef CHAR_DEVICE_CONTROL_1 +# define CHAR_DEVICE_CONTROL_1 LIBSIMPLE_CHAR_DEVICE_CONTROL_1 +#endif + +#define LIBSIMPLE_CHAR_DC2 '\x12' +#ifndef CHAR_DC2 +# define CHAR_DC2 LIBSIMPLE_CHAR_DC2 +#endif +#define LIBSIMPLE_CHAR_DEVICE_CONTROL_2 LIBSIMPLE_CHAR_DC2 +#ifndef CHAR_DEVICE_CONTROL_2 +# define CHAR_DEVICE_CONTROL_2 LIBSIMPLE_CHAR_DEVICE_CONTROL_2 +#endif + +#define LIBSIMPLE_CHAR_DC3 '\x13' +#ifndef CHAR_DC3 +# define CHAR_DC3 LIBSIMPLE_CHAR_DC3 +#endif +#define LIBSIMPLE_CHAR_DEVICE_CONTROL_3 LIBSIMPLE_CHAR_DC3 +#ifndef CHAR_DEVICE_CONTROL_3 +# define CHAR_DEVICE_CONTROL_3 LIBSIMPLE_CHAR_DEVICE_CONTROL_3 +#endif + +#define LIBSIMPLE_CHAR_DC4 '\x14' +#ifndef CHAR_DC4 +# define CHAR_DC4 LIBSIMPLE_CHAR_DC4 +#endif +#define LIBSIMPLE_CHAR_DEVICE_CONTROL_4 LIBSIMPLE_CHAR_DC4 +#ifndef CHAR_DEVICE_CONTROL_4 +# define CHAR_DEVICE_CONTROL_4 LIBSIMPLE_CHAR_DEVICE_CONTROL_4 +#endif + +#define LIBSIMPLE_CHAR_NAK '\x15' +#ifndef CHAR_NAK +# define CHAR_NAK LIBSIMPLE_CHAR_NAK +#endif +#define LIBSIMPLE_CHAR_NEGATIVE_ACKNOWLEDGE LIBSIMPLE_CHAR_NAK +#ifndef CHAR_NEGATIVE_ACKNOWLEDGE +# define CHAR_NEGATIVE_ACKNOWLEDGE LIBSIMPLE_CHAR_NEGATIVE_ACKNOWLEDGE +#endif + +#define LIBSIMPLE_CHAR_SYN '\x16' +#ifndef CHAR_SYN +# define CHAR_SYN LIBSIMPLE_CHAR_SYN +#endif +#define LIBSIMPLE_CHAR_SYNCHRONOUS_IDLE LIBSIMPLE_CHAR_SYN +#ifndef CHAR_SYNCHRONOUS_IDLE +# define CHAR_SYNCHRONOUS_IDLE LIBSIMPLE_CHAR_SYNCHRONOUS_IDLE +#endif + +#define LIBSIMPLE_CHAR_ETB '\x17' +#ifndef CHAR_ETB +# define CHAR_ETB LIBSIMPLE_CHAR_ETB +#endif +#define LIBSIMPLE_CHAR_END_OF_TRANSMISSION_BLOCK LIBSIMPLE_CHAR_ETB +#ifndef CHAR_END_OF_TRANSMISSION_BLOCK +# define CHAR_END_OF_TRANSMISSION_BLOCK LIBSIMPLE_CHAR_END_OF_TRANSMISSION_BLOCK +#endif + +#define LIBSIMPLE_CHAR_CAN '\x18' +#ifndef CHAR_CAN +# define CHAR_CAN LIBSIMPLE_CHAR_CAN +#endif +#define LIBSIMPLE_CHAR_CANCEL LIBSIMPLE_CHAR_CAN +#ifndef CHAR_CANCEL +# define CHAR_CANCEL LIBSIMPLE_CHAR_CANCEL +#endif + +#define LIBSIMPLE_CHAR_EM '\x19' +#ifndef CHAR_EM +# define CHAR_EM LIBSIMPLE_CHAR_EM +#endif +#define LIBSIMPLE_CHAR_END_OF_MEDIUM LIBSIMPLE_CHAR_EM +#ifndef CHAR_END_OF_MEDIUM +# define CHAR_END_OF_MEDIUM LIBSIMPLE_CHAR_END_OF_MEDIUM +#endif + +#define LIBSIMPLE_CHAR_SUB '\x1A' +#ifndef CHAR_SUB +# define CHAR_SUB LIBSIMPLE_CHAR_SUB +#endif +#define LIBSIMPLE_CHAR_SUBSTITUTE LIBSIMPLE_CHAR_SUB +#ifndef CHAR_SUBSTITUTE +# define CHAR_SUBSTITUTE LIBSIMPLE_CHAR_SUBSTITUTE +#endif + +#define LIBSIMPLE_CHAR_ESC '\x1B' +#ifndef CHAR_ESC +# define CHAR_ESC LIBSIMPLE_CHAR_ESC +#endif +#define LIBSIMPLE_CHAR_ESCAPE LIBSIMPLE_CHAR_ESC +#ifndef CHAR_ESCAPE +# define CHAR_ESCAPE LIBSIMPLE_CHAR_ESCAPE +#endif + +#define LIBSIMPLE_CHAR_FS '\x1C' +#ifndef CHAR_FS +# define CHAR_FS LIBSIMPLE_CHAR_FS +#endif +#define LIBSIMPLE_CHAR_FILE_SEPARATOR LIBSIMPLE_CHAR_FS +#ifndef CHAR_FILE_SEPARATOR +# define CHAR_FILE_SEPARATOR LIBSIMPLE_CHAR_FILE_SEPARATOR +#endif + +#define LIBSIMPLE_CHAR_GS '\x1D' +#ifndef CHAR_GS +# define CHAR_GS LIBSIMPLE_CHAR_GS +#endif +#define LIBSIMPLE_CHAR_GROUP_SEPARATOR LIBSIMPLE_CHAR_GS +#ifndef CHAR_GROUP_SEPARATOR +# define CHAR_GROUP_SEPARATOR LIBSIMPLE_CHAR_GROUP_SEPARATOR +#endif + +#define LIBSIMPLE_CHAR_RS '\x1E' +#ifndef CHAR_RS +# define CHAR_RS LIBSIMPLE_CHAR_RS +#endif +#define LIBSIMPLE_CHAR_RECORD_SEPARATOR LIBSIMPLE_CHAR_RS +#ifndef CHAR_RECORD_SEPARATOR +# define CHAR_RECORD_SEPARATOR LIBSIMPLE_CHAR_RECORD_SEPARATOR +#endif + +#define LIBSIMPLE_CHAR_US '\x1F' +#ifndef CHAR_US +# define CHAR_US LIBSIMPLE_CHAR_US +#endif +#define LIBSIMPLE_CHAR_UNIT_SEPARATOR LIBSIMPLE_CHAR_US +#ifndef CHAR_UNIT_SEPARATOR +# define CHAR_UNIT_SEPARATOR LIBSIMPLE_CHAR_UNIT_SEPARATOR +#endif + +#define LIBSIMPLE_CHAR_SP '\x20' +#ifndef CHAR_SP +# define CHAR_SP LIBSIMPLE_CHAR_SP +#endif +#define LIBSIMPLE_CHAR_SPACE LIBSIMPLE_CHAR_SP +#ifndef CHAR_SPACE +# define CHAR_SPACE LIBSIMPLE_CHAR_SPACE +#endif + +#define LIBSIMPLE_CHAR_DEL '\x7F' +#ifndef CHAR_DEL +# define CHAR_DEL LIBSIMPLE_CHAR_DEL +#endif +#define LIBSIMPLE_CHAR_DELETE LIBSIMPLE_CHAR_DEL +#ifndef CHAR_DELETE +# define CHAR_DELETE LIBSIMPLE_CHAR_DELETE +#endif + + +#define LIBSIMPLE_STR_CHAR_NUL "\x00" +#ifndef STR_CHAR_NUL +# define STR_CHAR_NUL LIBSIMPLE_STR_CHAR_NUL +#endif +#define LIBSIMPLE_STR_CHAR_NULL LIBSIMPLE_STR_CHAR_NUL +#ifndef STR_CHAR_NULL +# define STR_CHAR_NULL LIBSIMPLE_STR_CHAR_NULL +#endif + +#define LIBSIMPLE_STR_CHAR_SOH "\x01" +#ifndef STR_CHAR_SOH +# define STR_CHAR_SOH LIBSIMPLE_STR_CHAR_SOH +#endif +#define LIBSIMPLE_STR_CHAR_START_OF_HEADING LIBSIMPLE_STR_CHAR_SOH +#ifndef STR_CHAR_START_OF_HEADING +# define STR_CHAR_START_OF_HEADING LIBSIMPLE_STR_CHAR_START_OF_HEADING +#endif + +#define LIBSIMPLE_STR_CHAR_STX "\x02" +#ifndef STR_CHAR_STX +# define STR_CHAR_STX LIBSIMPLE_STR_CHAR_STX +#endif +#define LIBSIMPLE_STR_CHAR_START_OF_TEXT LIBSIMPLE_STR_CHAR_STX +#ifndef STR_CHAR_START_OF_TEXT +# define STR_CHAR_START_OF_TEXT LIBSIMPLE_STR_CHAR_START_OF_TEXT +#endif + +#define LIBSIMPLE_STR_CHAR_ETX "\x03" +#ifndef STR_CHAR_ETX +# define STR_CHAR_ETX LIBSIMPLE_STR_CHAR_ETX +#endif +#define LIBSIMPLE_STR_CHAR_END_OF_TEXT LIBSIMPLE_STR_CHAR_ETX +#ifndef STR_CHAR_END_OF_TEXT +# define STR_CHAR_END_OF_TEXT LIBSIMPLE_STR_CHAR_END_OF_TEXT +#endif + +#define LIBSIMPLE_STR_CHAR_EOT "\x04" +#ifndef STR_CHAR_EOT +# define STR_CHAR_EOT LIBSIMPLE_STR_CHAR_EOT +#endif +#define LIBSIMPLE_STR_CHAR_END_OF_TRANSMISSION LIBSIMPLE_STR_CHAR_EOT +#ifndef STR_CHAR_END_OF_TRANSMISSION +# define STR_CHAR_END_OF_TRANSMISSION LIBSIMPLE_STR_CHAR_END_OF_TRANSMISSION +#endif + +#define LIBSIMPLE_STR_CHAR_ENQ "\x05" +#ifndef STR_CHAR_ENQ +# define STR_CHAR_ENQ LIBSIMPLE_STR_CHAR_ENQ +#endif +#define LIBSIMPLE_STR_CHAR_ENQUIRY LIBSIMPLE_STR_CHAR_ENQ +#ifndef STR_CHAR_ENQUIRY +# define STR_CHAR_ENQUIRY LIBSIMPLE_STR_CHAR_ENQUIRY +#endif + +#define LIBSIMPLE_STR_CHAR_ACK "\x06" +#ifndef STR_CHAR_ACK +# define STR_CHAR_ACK LIBSIMPLE_STR_CHAR_ACK +#endif +#define LIBSIMPLE_STR_CHAR_ACKNOWLEDGE LIBSIMPLE_STR_CHAR_ACK +#ifndef STR_CHAR_ACKNOWLEDGE +# define STR_CHAR_ACKNOWLEDGE LIBSIMPLE_STR_CHAR_ACKNOWLEDGE +#endif + +#define LIBSIMPLE_STR_CHAR_BEL "\x07" +#ifndef STR_CHAR_BEL +# define STR_CHAR_BEL LIBSIMPLE_STR_CHAR_BEL +#endif +#define LIBSIMPLE_STR_CHAR_BELL LIBSIMPLE_STR_CHAR_BEL +#ifndef STR_CHAR_BELL +# define STR_CHAR_BELL LIBSIMPLE_STR_CHAR_BELL +#endif + +#define LIBSIMPLE_STR_CHAR_BS "\x08" +#ifndef STR_CHAR_BS +# define STR_CHAR_BS LIBSIMPLE_STR_CHAR_BS +#endif +#define LIBSIMPLE_STR_CHAR_BACKSPACE LIBSIMPLE_STR_CHAR_BS +#ifndef STR_CHAR_BACKSPACE +# define STR_CHAR_BACKSPACE LIBSIMPLE_STR_CHAR_BACKSPACE +#endif + +#define LIBSIMPLE_STR_CHAR_HT "\x09" +#ifndef STR_CHAR_HT +# define STR_CHAR_HT LIBSIMPLE_STR_CHAR_HT +#endif +#define LIBSIMPLE_STR_CHAR_HORIZONTAL_TABULATION LIBSIMPLE_STR_CHAR_HT +#ifndef STR_CHAR_HORIZONTAL_TABULATION +# define STR_CHAR_HORIZONTAL_TABULATION LIBSIMPLE_STR_CHAR_HORIZONTAL_TABULATION +#endif + +#define LIBSIMPLE_STR_CHAR_LF "\x0A" +#ifndef STR_CHAR_LF +# define STR_CHAR_LF LIBSIMPLE_STR_CHAR_LF +#endif +#define LIBSIMPLE_STR_CHAR_LINE_FEED LIBSIMPLE_STR_CHAR_LF +#ifndef STR_CHAR_LINE_FEED +# define STR_CHAR_LINE_FEED LIBSIMPLE_STR_CHAR_LINE_FEED +#endif + +#define LIBSIMPLE_STR_CHAR_VT "\x0B" +#ifndef STR_CHAR_VT +# define STR_CHAR_VT LIBSIMPLE_STR_CHAR_VT +#endif +#define LIBSIMPLE_STR_CHAR_VERTICAL_TABULATION LIBSIMPLE_STR_CHAR_VT +#ifndef STR_CHAR_VERTICAL_TABULATION +# define STR_CHAR_VERTICAL_TABULATION LIBSIMPLE_STR_CHAR_VERTICAL_TABULATION +#endif + +#define LIBSIMPLE_STR_CHAR_FF "\x0C" +#ifndef STR_CHAR_FF +# define STR_CHAR_FF LIBSIMPLE_STR_CHAR_FF +#endif +#define LIBSIMPLE_STR_CHAR_FORM_FEED LIBSIMPLE_STR_CHAR_FF +#ifndef STR_CHAR_FORM_FEED +# define STR_CHAR_FORM_FEED LIBSIMPLE_STR_CHAR_FORM_FEED +#endif + +#define LIBSIMPLE_STR_CHAR_CR "\x0D" +#ifndef STR_CHAR_CR +# define STR_CHAR_CR LIBSIMPLE_STR_CHAR_CR +#endif +#define LIBSIMPLE_STR_CHAR_CARRIAGE_RETURN LIBSIMPLE_STR_CHAR_CR +#ifndef STR_CHAR_CARRIAGE_RETURN +# define STR_CHAR_CARRIAGE_RETURN LIBSIMPLE_STR_CHAR_CARRIAGE_RETURN +#endif + +#define LIBSIMPLE_STR_CHAR_SO "\x0E" +#ifndef STR_CHAR_SO +# define STR_CHAR_SO LIBSIMPLE_STR_CHAR_SO +#endif +#define LIBSIMPLE_STR_CHAR_SHIFT_OUT LIBSIMPLE_STR_CHAR_SO +#ifndef STR_CHAR_SHIFT_OUT +# define STR_CHAR_SHIFT_OUT LIBSIMPLE_STR_CHAR_SHIFT_OUT +#endif + +#define LIBSIMPLE_STR_CHAR_SI "\x0F" +#ifndef STR_CHAR_SI +# define STR_CHAR_SI LIBSIMPLE_STR_CHAR_SI +#endif +#define LIBSIMPLE_STR_CHAR_SHIFT_IN LIBSIMPLE_STR_CHAR_SI +#ifndef STR_CHAR_SHIFT_IN +# define STR_CHAR_SHIFT_IN LIBSIMPLE_STR_CHAR_SHIFT_IN +#endif + +#define LIBSIMPLE_STR_CHAR_DLE "\x10" +#ifndef STR_CHAR_DLE +# define STR_CHAR_DLE LIBSIMPLE_STR_CHAR_DLE +#endif +#define LIBSIMPLE_STR_CHAR_DATA_LINK_ESCAPE LIBSIMPLE_STR_CHAR_DLE +#ifndef STR_CHAR_DATA_LINK_ESCAPE +# define STR_CHAR_DATA_LINK_ESCAPE LIBSIMPLE_STR_CHAR_DATA_LINK_ESCAPE +#endif + +#define LIBSIMPLE_STR_CHAR_DC1 "\x11" +#ifndef STR_CHAR_DC1 +# define STR_CHAR_DC1 LIBSIMPLE_STR_CHAR_DC1 +#endif +#define LIBSIMPLE_STR_CHAR_DEVICE_CONTROL_1 LIBSIMPLE_STR_CHAR_DC1 +#ifndef STR_CHAR_DEVICE_CONTROL_1 +# define STR_CHAR_DEVICE_CONTROL_1 LIBSIMPLE_STR_CHAR_DEVICE_CONTROL_1 +#endif + +#define LIBSIMPLE_STR_CHAR_DC2 "\x12" +#ifndef STR_CHAR_DC2 +# define STR_CHAR_DC2 LIBSIMPLE_STR_CHAR_DC2 +#endif +#define LIBSIMPLE_STR_CHAR_DEVICE_CONTROL_2 LIBSIMPLE_STR_CHAR_DC2 +#ifndef STR_CHAR_DEVICE_CONTROL_2 +# define STR_CHAR_DEVICE_CONTROL_2 LIBSIMPLE_STR_CHAR_DEVICE_CONTROL_2 +#endif + +#define LIBSIMPLE_STR_CHAR_DC3 "\x13" +#ifndef STR_CHAR_DC3 +# define STR_CHAR_DC3 LIBSIMPLE_STR_CHAR_DC3 +#endif +#define LIBSIMPLE_STR_CHAR_DEVICE_CONTROL_3 LIBSIMPLE_STR_CHAR_DC3 +#ifndef STR_CHAR_DEVICE_CONTROL_3 +# define STR_CHAR_DEVICE_CONTROL_3 LIBSIMPLE_STR_CHAR_DEVICE_CONTROL_3 +#endif + +#define LIBSIMPLE_STR_CHAR_DC4 "\x14" +#ifndef STR_CHAR_DC4 +# define STR_CHAR_DC4 LIBSIMPLE_STR_CHAR_DC4 +#endif +#define LIBSIMPLE_STR_CHAR_DEVICE_CONTROL_4 LIBSIMPLE_STR_CHAR_DC4 +#ifndef STR_CHAR_DEVICE_CONTROL_4 +# define STR_CHAR_DEVICE_CONTROL_4 LIBSIMPLE_STR_CHAR_DEVICE_CONTROL_4 +#endif + +#define LIBSIMPLE_STR_CHAR_NAK "\x15" +#ifndef STR_CHAR_NAK +# define STR_CHAR_NAK LIBSIMPLE_STR_CHAR_NAK +#endif +#define LIBSIMPLE_STR_CHAR_NEGATIVE_ACKNOWLEDGE LIBSIMPLE_STR_CHAR_NAK +#ifndef STR_CHAR_NEGATIVE_ACKNOWLEDGE +# define STR_CHAR_NEGATIVE_ACKNOWLEDGE LIBSIMPLE_STR_CHAR_NEGATIVE_ACKNOWLEDGE +#endif + +#define LIBSIMPLE_STR_CHAR_SYN "\x16" +#ifndef STR_CHAR_SYN +# define STR_CHAR_SYN LIBSIMPLE_STR_CHAR_SYN +#endif +#define LIBSIMPLE_STR_CHAR_SYNCHRONOUS_IDLE LIBSIMPLE_STR_CHAR_SYN +#ifndef STR_CHAR_SYNCHRONOUS_IDLE +# define STR_CHAR_SYNCHRONOUS_IDLE LIBSIMPLE_STR_CHAR_SYNCHRONOUS_IDLE +#endif + +#define LIBSIMPLE_STR_CHAR_ETB "\x17" +#ifndef STR_CHAR_ETB +# define STR_CHAR_ETB LIBSIMPLE_STR_CHAR_ETB +#endif +#define LIBSIMPLE_STR_CHAR_END_OF_TRANSMISSION_BLOCK LIBSIMPLE_STR_CHAR_ETB +#ifndef STR_CHAR_END_OF_TRANSMISSION_BLOCK +# define STR_CHAR_END_OF_TRANSMISSION_BLOCK LIBSIMPLE_STR_CHAR_END_OF_TRANSMISSION_BLOCK +#endif + +#define LIBSIMPLE_STR_CHAR_CAN "\x18" +#ifndef STR_CHAR_CAN +# define STR_CHAR_CAN LIBSIMPLE_STR_CHAR_CAN +#endif +#define LIBSIMPLE_STR_CHAR_CANCEL LIBSIMPLE_STR_CHAR_CAN +#ifndef STR_CHAR_CANCEL +# define STR_CHAR_CANCEL LIBSIMPLE_STR_CHAR_CANCEL +#endif + +#define LIBSIMPLE_STR_CHAR_EM "\x19" +#ifndef STR_CHAR_EM +# define STR_CHAR_EM LIBSIMPLE_STR_CHAR_EM +#endif +#define LIBSIMPLE_STR_CHAR_END_OF_MEDIUM LIBSIMPLE_STR_CHAR_EM +#ifndef STR_CHAR_END_OF_MEDIUM +# define STR_CHAR_END_OF_MEDIUM LIBSIMPLE_STR_CHAR_END_OF_MEDIUM +#endif + +#define LIBSIMPLE_STR_CHAR_SUB "\x1A" +#ifndef STR_CHAR_SUB +# define STR_CHAR_SUB LIBSIMPLE_STR_CHAR_SUB +#endif +#define LIBSIMPLE_STR_CHAR_SUBSTITUTE LIBSIMPLE_STR_CHAR_SUB +#ifndef STR_CHAR_SUBSTITUTE +# define STR_CHAR_SUBSTITUTE LIBSIMPLE_STR_CHAR_SUBSTITUTE +#endif + +#define LIBSIMPLE_STR_CHAR_ESC "\x1B" +#ifndef STR_CHAR_ESC +# define STR_CHAR_ESC LIBSIMPLE_STR_CHAR_ESC +#endif +#define LIBSIMPLE_STR_CHAR_ESCAPE LIBSIMPLE_STR_CHAR_ESC +#ifndef STR_CHAR_ESCAPE +# define STR_CHAR_ESCAPE LIBSIMPLE_STR_CHAR_ESCAPE +#endif + +#define LIBSIMPLE_STR_CHAR_FS "\x1C" +#ifndef STR_CHAR_FS +# define STR_CHAR_FS LIBSIMPLE_STR_CHAR_FS +#endif +#define LIBSIMPLE_STR_CHAR_FILE_SEPARATOR LIBSIMPLE_STR_CHAR_FS +#ifndef STR_CHAR_FILE_SEPARATOR +# define STR_CHAR_FILE_SEPARATOR LIBSIMPLE_STR_CHAR_FILE_SEPARATOR +#endif + +#define LIBSIMPLE_STR_CHAR_GS "\x1D" +#ifndef STR_CHAR_GS +# define STR_CHAR_GS LIBSIMPLE_STR_CHAR_GS +#endif +#define LIBSIMPLE_STR_CHAR_GROUP_SEPARATOR LIBSIMPLE_STR_CHAR_GS +#ifndef STR_CHAR_GROUP_SEPARATOR +# define STR_CHAR_GROUP_SEPARATOR LIBSIMPLE_STR_CHAR_GROUP_SEPARATOR +#endif + +#define LIBSIMPLE_STR_CHAR_RS "\x1E" +#ifndef STR_CHAR_RS +# define STR_CHAR_RS LIBSIMPLE_STR_CHAR_RS +#endif +#define LIBSIMPLE_STR_CHAR_RECORD_SEPARATOR LIBSIMPLE_STR_CHAR_RS +#ifndef STR_CHAR_RECORD_SEPARATOR +# define STR_CHAR_RECORD_SEPARATOR LIBSIMPLE_STR_CHAR_RECORD_SEPARATOR +#endif + +#define LIBSIMPLE_STR_CHAR_US "\x1F" +#ifndef STR_CHAR_US +# define STR_CHAR_US LIBSIMPLE_STR_CHAR_US +#endif +#define LIBSIMPLE_STR_CHAR_UNIT_SEPARATOR LIBSIMPLE_STR_CHAR_US +#ifndef STR_CHAR_UNIT_SEPARATOR +# define STR_CHAR_UNIT_SEPARATOR LIBSIMPLE_STR_CHAR_UNIT_SEPARATOR +#endif + +#define LIBSIMPLE_STR_CHAR_SP "\x20" +#ifndef STR_CHAR_SP +# define STR_CHAR_SP LIBSIMPLE_STR_CHAR_SP +#endif +#define LIBSIMPLE_STR_CHAR_SPACE LIBSIMPLE_STR_CHAR_SP +#ifndef STR_CHAR_SPACE +# define STR_CHAR_SPACE LIBSIMPLE_STR_CHAR_SPACE +#endif + +#define LIBSIMPLE_STR_CHAR_DEL "\x7F" +#ifndef STR_CHAR_DEL +# define STR_CHAR_DEL LIBSIMPLE_STR_CHAR_DEL +#endif +#define LIBSIMPLE_STR_CHAR_DELETE LIBSIMPLE_STR_CHAR_DEL +#ifndef STR_CHAR_DELETE +# define STR_CHAR_DELETE LIBSIMPLE_STR_CHAR_DELETE +#endif + + +#define LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, ABBR, FULL, NAME)\ + X(LIBSIMPLE_CHAR_##ABBR, LIBSIMPLE_STR_CHAR_##ABBR, #ABBR, ABBR, #FULL, FULL, NAME) + +#define LIBSIMPLE_LIST_ASCII_CONTROL_CHARS(X, D)\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, NUL, NULL, "null") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, SOH, START_OF_HEADING, "start of heading") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, STX, START_OF_TEXT, "start of text") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, ETX, END_OF_TEXT, "end of text") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, EOT, END_OF_TRANSMISSION, "end of transmission") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, ENQ, ENQUIRY, "enquiry") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, ACK, ACKNOWLEDGE, "acknowledge") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, BEL, BELL, "bell") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, BS, BACKSPACE, "backspace") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, HT, HORIZONTAL_TABULATION, "horizontal tabulation") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, LF, LINE_FEED, "line feed") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, VT, VERTICAL_TABULATION, "vertical tabulation") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, FF, FORM_FEED, "form feed") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, CR, CARRIAGE_RETURN, "carriage return") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, SO, SHIFT_OUT, "shift out") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, SI, SHIFT_IN, "shift in") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, DLE, DATA_LINK_ESCAPE, "data link escape") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, DC1, DEVICE_CONTROL_1, "device control 1") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, DC2, DEVICE_CONTROL_2, "device control 2") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, DC3, DEVICE_CONTROL_3, "device control 3") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, DC4, DEVICE_CONTROL_4, "device control 4") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, NAK, NEGATIVE_ACKNOWLEDGE, "negative acknowledge") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, SYN, SYNCHRONOUS_IDLE, "synchronous idle") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, ETB, END_OF_TRANSMISSION_BLOCK, "end of transmission block") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, CAN, CANCEL, "cancel") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, EM, END_OF_MEDIUM, "end of medium") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, SUB, SUBSTITUTE, "substitute") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, ESC, ESCAPE, "escape") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, FS, FILE_SEPARATOR, "file separator") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, GS, GROUP_SEPARATOR, "group separator") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, RS, RECORD_SEPARATOR, "record separator") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, US, UNIT_SEPARATOR, "unit separator") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, SP, SPACE, "space") D\ + LIBSIMPLE_LIST_ASCII_CONTROL_CHARS__(X, DEL, DELETE, "delete") diff --git a/libsimple/env.h b/libsimple/env.h index 98a3d9f..a39ae2a 100644 --- a/libsimple/env.h +++ b/libsimple/env.h @@ -194,3 +194,10 @@ libsimple_eputenvf(const char *fmt__, ...) #ifndef eputenvf # define eputenvf libsimple_eputenvf #endif + + +/* + * TODO add getenv_first, getenv_first_ne, getenv_first_e + * TODO add getenv_last, getenv_last_ne, getenv_last_e + * TODO add unsetenv_first, unsetenv_last, unsetenv_each + */ diff --git a/libsimple/exec.h b/libsimple/exec.h new file mode 100644 index 0000000..bc61628 --- /dev/null +++ b/libsimple/exec.h @@ -0,0 +1,99 @@ +/* See LICENSE file for copyright and license details. */ + +/* TODO man, doc, test */ + + +const char *libsimple_which(const char *file, int cwdfd, const char *path, char **free_this_out); + +int libsimple_xexecv(int dirfd, const char *file, int atflags, const char *path, char *const *envp, char *const *argv); + +int libsimple_vxexecl(int dirfd, const char *file, int atflags, const char *path, char *const *envp, va_list argv_null); + +int libsimple_xexecl(int dirfd, const char *file, int atflags, const char *path, char *const *envp, ... /* argv, NULL */); + +int libsimple_vxexecle(int dirfd, const char *file, int atflags, const char *path, va_list argv_null_envp); + +int libsimple_execlpe(const char *file, ... /* argv, NULL, char *const envp[] */); +#ifndef execlpe +# define execlpe libsimple_execlpe +#endif + +int libsimple_vexecl(const char *pathname, va_list argv_null); +#ifndef vexecl +# define vexecl libsimple_vexecl +#endif + +int libsimple_vexecle(const char *pathname, va_list argv_null_envp); +#ifndef vexecle +# define vexecle libsimple_vexecle +#endif + +int libsimple_vexeclp(const char *file, va_list argv_null); +#ifndef vexeclp +# define vexeclp libsimple_vexeclp +#endif + +int libsimple_vexeclpe(const char *file, va_list argv_null_envp); +#ifndef vexeclpe +# define vexeclpe libsimple_vexeclpe +#endif + +int libsimple_execvpe(const char *file, char *const argv[], char *const envp[]); +#ifndef execvpe +# define execvpe libsimple_execvpe +#endif + +int libsimple_vfexecl(int fd, va_list argv_null); +#ifndef vfexecl +# define vfexecl libsimple_vfexecl +#endif + +int libsimple_vfexecle(int fd, va_list argv_null_envp); +#ifndef vfexecle +# define vfexecle libsimple_vfexecle +#endif + +int libsimple_fexecl(int fd, ... /* argv, NULL */); +#ifndef fexecl +# define fexecl libsimple_fexecl +#endif + +int libsimple_fexecle(int fd, ... /* argv, NULL, char *const envp[] */); +#ifndef fexecle +# define fexecle libsimple_fexecle +#endif + +int libsimple_fexecv(int fd, char *const argv[]); +#ifndef fexecv +# define fexecv libsimple_fexecv +#endif + +int libsimple_execveat(int dirfd, const char *pathname, char *const argv[], char *const envp[], int flags); +#ifndef execveat +# define execveat libsimple_execveat +#endif + +int libsimple_execvat(int dirfd, const char *pathname, char *const argv[], int flags); +#ifndef execvat +# define execvat libsimple_execvat +#endif + +int libsimple_execleat(int dirfd, const char *pathname, ... /* argv, NULL, char *const envp[], int flags */); +#ifndef execleat +# define execleat libsimple_execleat +#endif + +int libsimple_execlat(int dirfd, const char *pathname, ... /* argv, NULL, int flags */); +#ifndef execlat +# define execlat libsimple_execlat +#endif + +int libsimple_vexecleat(int dirfd, const char *pathname, va_list argv_null_envp_flags); +#ifndef vexecleat +# define vexecleat libsimple_execlpe +#endif + +int libsimple_vexeclat(int dirfd, const char *pathname, va_list argv_null_flags); +#ifndef vexeclat +# define vexeclat libsimple_vexeclat +#endif diff --git a/vexecl.c b/vexecl.c new file mode 100644 index 0000000..50649ed --- /dev/null +++ b/vexecl.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vexecl(const char *pathname, va_list argv_null) +{ + return libsimple_vxexecl(-1, pathname, -1, "", environ, argv_null); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/vexeclat.c b/vexeclat.c new file mode 100644 index 0000000..97983d1 --- /dev/null +++ b/vexeclat.c @@ -0,0 +1,28 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vexeclat(int dirfd, const char *pathname, va_list argv_null_flags) +{ + int flags; + va_list args; + va_copy(args, argv_null_flags); + while (va_arg(args, char *)); + flags = va_arg(args, int); + va_end(args); + return libsimple_vxexecl(dirfd, pathname, flags, NULL, environ, argv_null_flags); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/vexecle.c b/vexecle.c new file mode 100644 index 0000000..2094bc1 --- /dev/null +++ b/vexecle.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vexecle(const char *pathname, va_list argv_null_envp) +{ + return libsimple_vxexecle(-1, pathname, -1, "", argv_null_envp); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/vexecleat.c b/vexecleat.c new file mode 100644 index 0000000..f9bda0e --- /dev/null +++ b/vexecleat.c @@ -0,0 +1,30 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vexecleat(int dirfd, const char *pathname, va_list argv_null_envp_flags) +{ + char *const *envp; + int flags; + va_list args; + va_copy(args, argv_null_envp_flags); + while (va_arg(args, char *)); + envp = va_arg(args, char *const *); + flags = va_arg(args, int); + va_end(args); + return libsimple_vxexecl(dirfd, pathname, flags, NULL, envp, argv_null_envp_flags); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/vexeclp.c b/vexeclp.c new file mode 100644 index 0000000..a1d6f1f --- /dev/null +++ b/vexeclp.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vexeclp(const char *file, va_list argv_null) +{ + return libsimple_vxexecl(-1, file, -1, NULL, environ, argv_null); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/vexeclpe.c b/vexeclpe.c new file mode 100644 index 0000000..5951fc9 --- /dev/null +++ b/vexeclpe.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vexeclpe(const char *file, va_list argv_null_envp) +{ + return libsimple_vxexecle(-1, file, -1, NULL, argv_null_envp); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/vfexecl.c b/vfexecl.c new file mode 100644 index 0000000..dd66b87 --- /dev/null +++ b/vfexecl.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vfexecl(int fd, va_list argv_null) +{ + return libsimple_vxexecl(fd, "", AT_EMPTY_PATH, "", environ, argv_null); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/vfexecle.c b/vfexecle.c new file mode 100644 index 0000000..31ee602 --- /dev/null +++ b/vfexecle.c @@ -0,0 +1,28 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vfexecle(int fd, va_list argv_null_envp) +{ + char *const *envp; + va_list args; + va_copy(args, argv_null_envp); + while (va_arg(args, char *)); + envp = va_arg(args, char *const *); + va_end(args); + return libsimple_vxexecl(fd, "", AT_EMPTY_PATH, "", envp, argv_null_envp); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/vxexecl.c b/vxexecl.c new file mode 100644 index 0000000..c8282a6 --- /dev/null +++ b/vxexecl.c @@ -0,0 +1,35 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vxexecl(int dirfd, const char *file, int atflags, const char *path, char *const *envp, va_list argv_null) +{ + char **argv; + size_t argc = 0; + va_list args; + va_copy(args, argv_null); + do { + argc += 1; + } while (va_arg(args, char *)); + va_end(args); + argv = alloca((argc + 1) * sizeof(*argv)); + argc = 0; + do { + argv[argc] = va_arg(args, char *); + } while (argv[argc++]); + return libsimple_xexecv(dirfd, file, atflags, path, envp, argv); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/vxexecle.c b/vxexecle.c new file mode 100644 index 0000000..61415ef --- /dev/null +++ b/vxexecle.c @@ -0,0 +1,28 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_vxexecle(int dirfd, const char *file, int atflags, const char *path, va_list argv_null_envp) +{ + char *const *envp; + va_list args; + va_copy(args, argv_null_envp); + while (va_arg(args, char *)); + envp = va_arg(args, char *const *); + va_end(args); + return libsimple_vxexecl(dirfd, file, atflags, path, envp, argv_null_envp); +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif @@ -0,0 +1,92 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +const char * +libsimple_which(const char *file, int cwdfd, const char *path, char **free_this_out) +{ + const char *p, *q; + char *buf = NULL; + size_t bufsize, len, filelen; + int got_eacces = 0, saved_errno = errno; + + free_this_out = NULL; + + if (!file || !free_this_out) { + errno = EINVAL; + return NULL; + } + + if (strchr(file, '/')) + return file; + + if (!path) { + path = getenv("PATH"); + if (!path) + path = ""; + } + if (!*path) { + errno = ENOENT; + return NULL; + } + + bufsize = 0; + for (p = path; p; p = q) { + q = strchr(p, ':'); + if (q) + len = (size_t)(q++ - p); + else + len = strlen(p); + if (len > bufsize) + bufsize = len; + } + if (bufsize) { + filelen = strlen(file) + 1U; + bufsize += 1U + filelen; + buf = malloc(bufsize); + if (!buf) + return NULL; + } + + for (p = path; p; p = q) { + q = strchr(p, ':'); + if (q) + len = (size_t)(q++ - p); + else + len = strlen(p); + if (len) { + memcpy(buf, p, len); + buf[len] = '/'; + memcpy(&buf[len + 1], file, filelen); + if (!faccessat(cwdfd, buf, X_OK, AT_EACCESS)) { + *free_this_out = buf; + errno = saved_errno; + return buf; + } + } else { + if (!faccessat(cwdfd, file, X_OK, AT_EACCESS)) { + errno = saved_errno; + return file; + } + } + if (errno == EACCES) + got_eacces = 1; + } + + free(buf); + errno = got_eacces ? EACCES : ENOENT; + return NULL; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/xexecl.c b/xexecl.c new file mode 100644 index 0000000..fa46725 --- /dev/null +++ b/xexecl.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_xexecl(int dirfd, const char *file, int atflags, const char *path, char *const *envp, ... /* argv, NULL */) +{ + int ret; + va_list args; + va_start(args, envp); + ret = libsimple_vxexecl(dirfd, file, atflags, path, envp, args); + va_end(args); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/xexecv.c b/xexecv.c new file mode 100644 index 0000000..68fd264 --- /dev/null +++ b/xexecv.c @@ -0,0 +1,31 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libsimple_xexecv(int dirfd, const char *file, int atflags, const char *path, char *const *envp, char *const *argv) +{ + char *free_this; + int ret; + if (dirfd == -1 && atflags == -1) { + file = libsimple_which(file, AT_FDCWD, path, &free_this); + ret = execve(file, argv, envp); + free(free_this); + return ret; + } else { + return execveat(dirfd, file, argv, envp, atflags); + } +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif |