aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile2
-rw-r--r--internal.h13
-rw-r--r--liberror-libc.h2
-rw-r--r--liberror.h236
-rw-r--r--set_error_one_file.c17
-rw-r--r--shutdown.c4
6 files changed, 269 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 4cd8ae9..ca418c0 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,7 @@ LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR)
HDR =\
liberror-libc.h\
+ liberror.h\
internal.h
OBJ =\
@@ -24,6 +25,7 @@ OBJ =\
llabs.o\
pipe.o\
putenv.o\
+ set_error_one_file.o\
setenv.o\
shutdown.o\
unsetenv.o
diff --git a/internal.h b/internal.h
index e9b1ac3..80bf317 100644
--- a/internal.h
+++ b/internal.h
@@ -1,5 +1,6 @@
/* See LICENSE file for copyright and license details. */
#include "liberror-libc.h"
+#include "liberror.h"
#include <sys/socket.h>
#include <errno.h>
@@ -9,5 +10,13 @@
#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);
+#if defined(__GNUC__)
+# define GCC_ATTRIBUTES(...) __attribute__((__VA_ARGS__))
+#else
+# define GCC_ATTRIBUTES(...)
+#endif
+
+#define HIDDEN GCC_ATTRIBUTES(__visibility__("hidden"))
+
+
+HIDDEN void liberror_libc_set_error_one_file(const char[256], const char[64], const char *, int, const char *);
diff --git a/liberror-libc.h b/liberror-libc.h
index 0a8634c..fd67f3b 100644
--- a/liberror-libc.h
+++ b/liberror-libc.h
@@ -12,7 +12,7 @@ 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_shutdown(int, int, const char *);
int liberror_unsetenv(const char *);
diff --git a/liberror.h b/liberror.h
new file mode 100644
index 0000000..508dbac
--- /dev/null
+++ b/liberror.h
@@ -0,0 +1,236 @@
+/* See LICENSE file for copyright and license details. */
+#ifndef LIBERROR_H
+#define LIBERROR_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+
+/**
+ * Opaque backtrace structure
+ */
+struct liberror_backtrace;
+
+/**
+ * Value that specifies which feild in a
+ * `union liberror_details` that is used
+ */
+enum liberror_details_type {
+ LIBERROR_DETAILS_NONE,
+ LIBERROR_DETAILS_USER,
+ LIBERROR_DETAILS_ONE_FILE,
+ LIBERROR_DETAILS_TWO_FILES
+};
+
+/**
+ * Error details
+ */
+union liberror_details {
+ /**
+ * For `LIBERROR_DETAILS_USER`
+ */
+ struct {
+ const char *library;
+ void *data;
+ void (*free_data)(void *);
+ void *(*copy_data)(void *);
+ } user;
+
+ /**
+ * For `LIBERROR_DETAILS_ONE_FILE`
+ */
+ struct {
+ int fd;
+ char *name;
+ const char *role;
+ } one_file;
+
+ /**
+ * For `LIBERROR_DETAILS_TWO_FILES`
+ */
+ struct {
+ int fd1;
+ int fd2;
+ char *name1;
+ char *name2;
+ const char *role1;
+ const char *role2;
+ } two_files;
+};
+
+/**
+ * Error structure
+ */
+struct liberror_error {
+ /**
+ * Backtrace for the error, `NULL` if the it could
+ * not be allocated or if the program is not linked
+ * with `-lerror-backtrace`
+ */
+ struct liberror_backtrace *backtrace;
+
+ /**
+ * Description of the error
+ */
+ char description[256];
+
+ /**
+ * The function that failed
+ */
+ char source[64];
+
+ /**
+ * Name of error code group, for normal `errno`
+ * errors this is "error", for getaddrinfo(3) errors
+ * this is "addrinfo", for custom errors it is the
+ * name of the library or application
+ */
+ char code_group[64];
+
+ /**
+ * The error code
+ */
+ long long int code;
+
+ /**
+ * The error that caused this error, `NULL` if
+ * none or it could not be allocated (if and only
+ * if so, `.failed_to_allocate_cause` will be set
+ * to a non-zero value, specifically 1)
+ */
+ struct liberror_error *cause;
+
+ /**
+ * Whether allocation of `.cause` failed
+ */
+ int failed_to_allocate_cause;
+
+ /**
+ * Whether the error is physically allocated
+ */
+ int dynamically_allocated;
+
+ /**
+ * Which value in `.details` that is used
+ */
+ enum liberror_details_type details_type;
+
+ /**
+ * Error detail
+ */
+ union liberror_details details;
+};
+
+
+/**
+ * Get the current error for the thread
+ *
+ * @return The current error, `NULL` if none
+ */
+struct liberror_error *liberror_get_error(void);
+
+/**
+ * Create a copy of an error
+ *
+ * This function will only fail of enough memory
+ * cannot be allocated, however `errno` will not
+ * be changed
+ *
+ * @param error The error to copy
+ * @return Copy of the error, `NULL` on failure
+ */
+struct liberror_error *liberror_copy_error(struct liberror_error *);
+
+/**
+ * Deallocate and error and the error stored as
+ * its cause (recursively)
+ *
+ * @param error The error to deallocate
+ */
+void liberror_free_error(struct liberror_error *);
+
+/**
+ * Deallocate the current error for the thread
+ * and reset the error for the thread
+ *
+ * This function shall be called after handling
+ * the error
+ */
+void liberror_reset_error(void);
+
+/**
+ * Print the backtrace of an error
+ *
+ * If the backtrace could not be allocated,
+ * nothing will be printed
+ *
+ * This function will never change `errno`
+ *
+ * Note: this library does not actually save
+ * a backtrace, `-lerror-backtrace` is needed
+ * for that functionallity (it will replace
+ * some things in this library, so no other
+ * action is required)
+ *
+ * @param error The error
+ * @param fp The file to print the backtrace to
+ * @param indent Text to print at the beginning of each line
+ */
+void liberror_print_backtrace(struct liberror_error *, FILE *, const char *);
+
+/**
+ * Set the current error for the thread
+ *
+ * If the thread already has an error saved,
+ * it will be stored as the cause of the new
+ * error
+ *
+ * @param description Description of the error, empty for default description
+ * @param source The function that failed
+ * @param code_group Name of error code group, for normal `errno` errors
+ * this shall be "error", for getaddrinfo(3) errors
+ * this shall be "addrinfo", for custom errors it shall
+ * be the name of the library or application
+ * @param code The error code
+ */
+void liberror_set_error(const char[256], const char[64], const char[64], long long int);
+
+/**
+ * Set the current error for the thread
+ *
+ * This function can be used as an alternative
+ * to `liberror_set_error` for `errno` errors
+ *
+ * If the thread already has an error saved,
+ * it will be stored as the cause of the new
+ * error
+ *
+ * @param description Description of the error, empty for default description
+ * @param source The function that failed
+ * @param code The `errno` value
+ */
+void liberror_set_error_errno(const char[256], const char[64], int);
+
+/**
+ * The an error, its backtrace, and its
+ * cause (recursively)
+ *
+ * If `error` is `NULL` and the thread does
+ * not have any error set, this function
+ * will not do anything
+ *
+ * @param error The error, the thread's current error if `NULL`
+ * @param fp Output stream, standard error if `NULL`
+ * @param reset Whether `error` shall be deallocated, `error`
+ * is null and `reset` is non-zero, the thread's
+ * error will be reset
+ * @param prefix Prefix for each printed line, ": " will be
+ * appended to this prefix; if `NULL` or empty,
+ * no prefix is used; this should normally be
+ * `argv[0]` from the main() function
+ */
+void liberror_print_error(struct liberror_error *, FILE *, int, const char *);
+
+
+#endif
diff --git a/set_error_one_file.c b/set_error_one_file.c
new file mode 100644
index 0000000..f8061f8
--- /dev/null
+++ b/set_error_one_file.c
@@ -0,0 +1,17 @@
+/* See LICENSE file for copyright and license details. */
+#include "internal.h"
+
+
+void
+liberror_libc_set_error_one_file(const char desc[256], const char source[64], const char *frole, int fd, const char *fname)
+{
+ struct liberror_error *error;
+ int saved_errno = errno;
+ liberror_set_error_errno(desc, source, saved_errno);
+ error = liberror_get_error();
+ error->details_type = LIBERROR_DETAILS_ONE_FILE;
+ error->details.one_file.fd = fd;
+ error->details.one_file.name = fname ? strdup(fname) : NULL;
+ error->details.one_file.role = frole;
+ errno = saved_errno;
+}
diff --git a/shutdown.c b/shutdown.c
index 3ccdfd0..4e5f4cf 100644
--- a/shutdown.c
+++ b/shutdown.c
@@ -3,7 +3,7 @@
int
-liberror_shutdown(int fd, int how)
+liberror_shutdown(int fd, int how, const char *fname)
{
const char *desc;
if (!shutdown(fd, how))
@@ -28,6 +28,6 @@ liberror_shutdown(int fd, int how)
desc = "";
break;
}
- liberror_set_error_errno(desc, "shutdown", errno);
+ liberror_libc_set_error_one_file(desc, "shutdown", "Socket file", fd, fname);
return -1;
}