diff options
-rw-r--r-- | .gitignore | 10 | ||||
-rw-r--r-- | LICENSE | 15 | ||||
-rw-r--r-- | Makefile | 74 | ||||
-rw-r--r-- | abs.c | 18 | ||||
-rw-r--r-- | config.mk | 6 | ||||
-rw-r--r-- | imaxabs.c | 18 | ||||
-rw-r--r-- | internal.h | 13 | ||||
-rw-r--r-- | labs.c | 18 | ||||
-rw-r--r-- | liberror-libc.h | 19 | ||||
-rw-r--r-- | linux.mk | 5 | ||||
-rw-r--r-- | llabs.c | 18 | ||||
-rw-r--r-- | macos.mk | 5 | ||||
-rw-r--r-- | pipe.c | 32 | ||||
-rw-r--r-- | putenv.c | 27 | ||||
-rw-r--r-- | setenv.c | 30 | ||||
-rw-r--r-- | shutdown.c | 33 | ||||
-rw-r--r-- | unsetenv.c | 23 |
17 files changed, 364 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..983233b --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +*\#* +*~ +*.o +*.a +*.lo +*.so +*.so.* +*.su +*.dll +*.dylib @@ -0,0 +1,15 @@ +ISC License + +© 2019 Mattias Andrée <maandree@kth.se> + +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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4cd8ae9 --- /dev/null +++ b/Makefile @@ -0,0 +1,74 @@ +.POSIX: + +CONFIGFILE = config.mk +include $(CONFIGFILE) + +OS = linux +# linux = Linux +# macos = Mac OS +include $(OS).mk + +LIB_MAJOR = 1 +LIB_MINOR = 0 +LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR) + + +HDR =\ + liberror-libc.h\ + internal.h + +OBJ =\ + abs.o\ + imaxabs.o\ + labs.o\ + llabs.o\ + pipe.o\ + putenv.o\ + setenv.o\ + shutdown.o\ + unsetenv.o + +LOBJ = $(OBJ:.o=.lo) + + +all: liberror-libc.a liberror-libc.$(LIBEXT) +$(OBJ): $(@:.o=.c) $(HDR) +$(LOBJ): $(@:.lo=.c) $(HDR) + +liberror-libc.a: $(OBJ) + -rm -f -- $@ + $(AR) rc $@ $(OBJ) + $(AR) s $@ + +liberror-libc.$(LIBEXT): $(LOBJ) + $(CC) $(LIBFLAGS) -o $@ $(LOBJ) $(LDFLAGS) + +.c.o: + $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + +.c.lo: + $(CC) -c -o $@ $< -fPIC $(CFLAGS) $(CPPFLAGS) + +install: liberror-libc.a liberror-libc.$(LIBEXT) + mkdir -p -- "$(DESTDIR)$(PREFIX)/lib" + mkdir -p -- "$(DESTDIR)$(PREFIX)/include" + mkdir -p -- "$(DESTDIR)$(PREFIX)/licenses/liberror-libc" + cp -- liberror-libc.a "$(DESTDIR)$(PREFIX)/lib" + cp -- liberror-libc.$(LIBEXT) "$(DESTDIR)$(PREFIX)/lib/liberror-libc.$(LIBMINOREXT)" + ln -sf -- liberror-libc.$(LIBMINOREXT) "$(DESTDIR)$(PREFIX)/lib/liberror-libc.$(LIBMAJOREXT)" + ln -sf -- liberror-libc.$(LIBMINOREXT) "$(DESTDIR)$(PREFIX)/lib/liberror-libc.$(LIBEXT)" + cp -- liberror-libc.h "$(DESTDIR)$(PREFIX)/include" + cp -- LICENSE "$(DESTDIR)$(PREFIX)/licenses/liberror-libc" + +uninstall: + -rm -f -- "$(DESTDIR)$(PREFIX)/lib/liberror-libc."* + -rm -f -- "$(DESTDIR)$(PREFIX)/include/liberror-libc.h" + -rm -rf -- "$(DESTDIR)$(PREFIX)/licenses/liberror-libc" + +clean: + -rm -f -- *.o *.lo *.a *.so *.so.* *.su *.test + +.SUFFIXES: +.SUFFIXES: .c .o .lo .a + +.PHONY: all install uninstall clean @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +int +liberror_abs(int i) +{ +#if INT_MIN == -INT_MAX + return abs(i); +#else + if (i != INT_MIN) + return abs(i); + liberror_set_error_errno("The absolute value of largest negative integer " + "cannot be represented as a signed integer", + "abs", EOVERFLOW); + return i; +#endif +} diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..fdfd458 --- /dev/null +++ b/config.mk @@ -0,0 +1,6 @@ +PREFIX = /usr +MANPREFIX = $(PREFIX)/share/man + +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 +CFLAGS = -std=c11 -Wall -pedantic +LDFLAGS = -s diff --git a/imaxabs.c b/imaxabs.c new file mode 100644 index 0000000..cffacc2 --- /dev/null +++ b/imaxabs.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +intmax_t +liberror_imaxabs(intmax_t i) +{ +#if INTMAX_MIN == -INTMAX_MAX + return imaxabs(i); +#else + if (i != INTMAX_MIN) + return imaxabs(i); + liberror_set_error_errno("The absolute value of largest negative integer " + "cannot be represented as a signed integer", + "imaxabs", EOVERFLOW); + return i; +#endif +} diff --git a/internal.h b/internal.h new file mode 100644 index 0000000..e9b1ac3 --- /dev/null +++ b/internal.h @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "liberror-libc.h" + +#include <sys/socket.h> +#include <errno.h> +#include <inttypes.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +void liberror_set_error(const char[256], const char[64], const char[64], long long int); +void liberror_set_error_errno(const char[256], const char[64], int); @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +long int +liberror_labs(long int i) +{ +#if LONG_MIN == -LONG_MAX + return labs(i); +#else + if (i != LONG_MIN) + return labs(i); + liberror_set_error_errno("The absolute value of largest negative integer " + "cannot be represented as a signed integer", + "labs", EOVERFLOW); + return i; +#endif +} diff --git a/liberror-libc.h b/liberror-libc.h new file mode 100644 index 0000000..0a8634c --- /dev/null +++ b/liberror-libc.h @@ -0,0 +1,19 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef LIBERROR_LIBC_H +#define LIBERROR_LIBC_H + +#include <stdint.h> + + +int liberror_abs(int); +intmax_t liberror_imaxabs(intmax_t); +long int liberror_labs(long int); +long long int liberror_llabs(long long int); +int liberror_pipe(int[2]); +int liberror_putenv(char *); +int liberror_setenv(const char *, const char *, int); +int liberror_shutdown(int, int); +int liberror_unsetenv(const char *); + + +#endif diff --git a/linux.mk b/linux.mk new file mode 100644 index 0000000..c9f74a0 --- /dev/null +++ b/linux.mk @@ -0,0 +1,5 @@ +LIBEXT = so +LIBFLAGS = -shared -Wl,-soname,libkeccak.$(LIBEXT).$(LIB_MAJOR) + +LIBMAJOREXT = $(LIBEXT).$(LIB_MAJOR) +LIBMINOREXT = $(LIBEXT).$(LIB_VERSION) @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +long long int +liberror_llabs(long long int i) +{ +#if LLONG_MIN == -LLONG_MAX + return llabs(i); +#else + if (i != LLONG_MIN) + return llabs(i); + liberror_set_error_errno("The absolute value of largest negative integer " + "cannot be represented as a signed integer", + "llabs", EOVERFLOW); + return i; +#endif +} diff --git a/macos.mk b/macos.mk new file mode 100644 index 0000000..b475197 --- /dev/null +++ b/macos.mk @@ -0,0 +1,5 @@ +LIBEXT = dylib +LIBFLAGS = -dynamiclib + +LIBMAJOREXT = $(LIB_MAJOR).$(LIBEXT) +LIBMINOREXT = $(LIB_VERSION).$(LIBEXT) @@ -0,0 +1,32 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +int +liberror_pipe(int fds[2]) +{ + const char *desc; + if (!fds) { + desc = "Output parameter is NULL"; + goto error; + } + if (!pipe(fds)) + return 0; + switch (errno) { + case EFAULT: + desc = "Output parameter is an invalid pointer"; + break; + case EMFILE: + desc = "The process have too many file descriptors open"; + break; + case ENFILE: + desc = "The system have too many file descriptors open"; + break; + default: + desc = ""; + break; + } +error: + liberror_set_error_errno(desc, "pipe", errno); + return -1; +} diff --git a/putenv.c b/putenv.c new file mode 100644 index 0000000..b88b3cd --- /dev/null +++ b/putenv.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +int +liberror_putenv(char *string) +{ + const char *desc = ""; + if (!string) { + errno = EINVAL; + desc = "Environment string is NULL"; + goto error; + } else if (*string == '=') { + errno = EINVAL; + desc = "Environment variable name is the empty string"; + goto error; + } else if (!strchr(string, '=')) { + errno = EINVAL; + desc = "Environment does not contain an '=' symbol"; + goto error; + } else if (!putenv(string)) { + return 0; + } +error: + liberror_set_error_errno(desc, "putenv", errno); + return -1; +} diff --git a/setenv.c b/setenv.c new file mode 100644 index 0000000..157fea2 --- /dev/null +++ b/setenv.c @@ -0,0 +1,30 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +int +liberror_setenv(const char *envname, const char *envval, int overwrite) +{ + const char *desc = ""; + if (!envname) { + errno = EINVAL; + if (!envval) + desc = "Environment variable name and value are NULL"; + else + desc = "Environment variable name is NULL"; + goto error; + } else if (!envval) { + errno = EINVAL; + desc = "Environment variable value is NULL"; + goto error; + } else if (!setenv(envname, envval, overwrite)) { + return 0; + } else if (!*envname) { + desc = "Environment variable name is the empty string"; + } else if (errno == EINVAL) { + desc = "Environment variable name contains the '=' character"; + } +error: + liberror_set_error_errno(desc, "setenv", errno); + return -1; +} diff --git a/shutdown.c b/shutdown.c new file mode 100644 index 0000000..3ccdfd0 --- /dev/null +++ b/shutdown.c @@ -0,0 +1,33 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +int +liberror_shutdown(int fd, int how) +{ + const char *desc; + if (!shutdown(fd, how)) + return 0; + switch (errno) { + case EBADF: + desc = fd < 0 ? "Negative file descriptor number specified" : "Unassigned file descriptor number specified"; + break; + case EINVAL: + desc = "Invalid value of second parameter"; + break; + case ENOTCONN: + desc = "The socket is not connected"; + break; + case ENOTSOCK: + desc = "The specified file is not a socket"; + break; + case ENOBUFS: + desc = "Insufficient resource available in the system to perform the operation"; + break; + default: + desc = ""; + break; + } + liberror_set_error_errno(desc, "shutdown", errno); + return -1; +} diff --git a/unsetenv.c b/unsetenv.c new file mode 100644 index 0000000..6f7db37 --- /dev/null +++ b/unsetenv.c @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +int +liberror_unsetenv(const char *name) +{ + const char *desc = ""; + if (!name) { + errno = EINVAL; + desc = "Environment variable name is NULL"; + goto error; + } else if (!unsetenv(name)) { + return 0; + } else if (!*name) { + desc = "Environment variable name is the empty string"; + } else if (errno == EINVAL) { + desc = "Environment variable name contains the '=' character"; + } +error: + liberror_set_error_errno(desc, "setenv", errno); + return -1; +} |