From d33c5c0a18017ae658feb4a3344dd810cc87050b Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 5 May 2024 10:28:31 +0200 Subject: m + add ascii.h and exec.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 24 ++ bindtemp_un.c | 6 +- common.h | 4 + config.mk | 2 +- execlat.c | 27 +++ execleat.c | 27 +++ execlpe.c | 27 +++ execvat.c | 22 ++ execveat.c | 56 +++++ execvpe.c | 22 ++ fexecl.c | 27 +++ fexecle.c | 27 +++ fexecv.c | 22 ++ libsimple.c | 2 +- libsimple.h | 2 + libsimple/ascii.h | 657 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ libsimple/env.h | 7 + libsimple/exec.h | 99 ++++++++ vexecl.c | 22 ++ vexeclat.c | 28 +++ vexecle.c | 22 ++ vexecleat.c | 30 +++ vexeclp.c | 22 ++ vexeclpe.c | 22 ++ vfexecl.c | 22 ++ vfexecle.c | 28 +++ vxexecl.c | 35 +++ vxexecle.c | 28 +++ which.c | 92 ++++++++ xexecl.c | 27 +++ xexecv.c | 31 +++ 31 files changed, 1464 insertions(+), 5 deletions(-) create mode 100644 execlat.c create mode 100644 execleat.c create mode 100644 execlpe.c create mode 100644 execvat.c create mode 100644 execveat.c create mode 100644 execvpe.c create mode 100644 fexecl.c create mode 100644 fexecle.c create mode 100644 fexecv.c create mode 100644 libsimple/ascii.h create mode 100644 libsimple/exec.h create mode 100644 vexecl.c create mode 100644 vexeclat.c create mode 100644 vexecle.c create mode 100644 vexecleat.c create mode 100644 vexeclp.c create mode 100644 vexeclpe.c create mode 100644 vfexecl.c create mode 100644 vfexecle.c create mode 100644 vxexecl.c create mode 100644 vxexecle.c create mode 100644 which.c create mode 100644 xexecl.c create mode 100644 xexecv.c diff --git a/Makefile b/Makefile index d9c2b5a..84fb58c 100644 --- a/Makefile +++ b/Makefile @@ -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; diff --git a/common.h b/common.h index 7f84f59..81ad053 100644 --- a/common.h +++ b/common.h @@ -9,3 +9,7 @@ # pragma clang diagnostic ignored "-Wc++98-compat" # pragma clang diagnostic ignored "-Wcovered-switch-default" #endif + +#ifdef execveat +# undef execveat +#endif diff --git a/config.mk b/config.mk index 9bafe24..c7eb5ca 100644 --- a/config.mk +++ b/config.mk @@ -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 diff --git a/which.c b/which.c new file mode 100644 index 0000000..96a3ece --- /dev/null +++ b/which.c @@ -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 -- cgit v1.2.3-70-g09d2