aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2019-11-01 22:06:40 +0100
committerMattias Andrée <maandree@kth.se>2019-11-01 22:06:40 +0100
commitc57844b08bced71778f38f2346464c3e0836287c (patch)
treee3733b4c99818ee6c77ed3d4d37becf30f92268f
parentUse installed liberror (diff)
downloadliberror-libc-c57844b08bced71778f38f2346464c3e0836287c.tar.gz
liberror-libc-c57844b08bced71778f38f2346464c3e0836287c.tar.bz2
liberror-libc-c57844b08bced71778f38f2346464c3e0836287c.tar.xz
Add some functions and add functions with _failed suffix
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--Makefile8
-rw-r--r--abs.c14
-rw-r--r--calloc.c24
-rw-r--r--chdir.c54
-rw-r--r--imaxabs.c14
-rw-r--r--internal.h3
-rw-r--r--labs.c14
-rw-r--r--liberror-libc.h28
-rw-r--r--llabs.c14
-rw-r--r--malloc.c23
-rw-r--r--pipe.c28
-rw-r--r--putenv.c20
-rw-r--r--raise.c24
-rw-r--r--realloc.c24
-rw-r--r--recv.c124
-rw-r--r--send.c157
-rw-r--r--shutdown.c30
-rw-r--r--sockatmark.c37
-rw-r--r--unsetenv.c27
19 files changed, 622 insertions, 45 deletions
diff --git a/Makefile b/Makefile
index d59568f..9ce5639 100644
--- a/Makefile
+++ b/Makefile
@@ -19,14 +19,22 @@ HDR =\
OBJ =\
abs.o\
+ calloc.o\
+ chdir.o\
imaxabs.o\
labs.o\
llabs.o\
+ malloc.o\
pipe.o\
putenv.o\
+ raise.o\
+ realloc.o\
+ recv.o\
+ send.o\
set_error_one_file.o\
setenv.o\
shutdown.o\
+ sockatmark.o\
unsetenv.o
LOBJ = $(OBJ:.o=.lo)
diff --git a/abs.c b/abs.c
index 71d73b5..feac9a7 100644
--- a/abs.c
+++ b/abs.c
@@ -2,6 +2,16 @@
#include "internal.h"
+void
+liberror_abs_failed(int i)
+{
+ liberror_set_error_errno("The absolute value of largest negative integer "
+ "cannot be represented as a signed integer",
+ "abs", EOVERFLOW);
+ (void) i;
+}
+
+
int
liberror_abs(int i)
{
@@ -11,9 +21,7 @@ liberror_abs(int i)
if (i != INT_MIN)
return abs(i);
liberror_save_backtrace(NULL);
- liberror_set_error_errno("The absolute value of largest negative integer "
- "cannot be represented as a signed integer",
- "abs", EOVERFLOW);
+ liberror_abs_failed(i);
return i;
#endif
}
diff --git a/calloc.c b/calloc.c
new file mode 100644
index 0000000..86a939c
--- /dev/null
+++ b/calloc.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "internal.h"
+
+
+void
+liberror_calloc_failed(size_t n, size_t m)
+{
+ liberror_set_error_errno("Out of memory", "calloc", ENOMEM);
+ errno = ENOMEM;
+ (void) n;
+ (void) m;
+}
+
+
+void *
+liberror_calloc(size_t n, size_t m)
+{
+ void *ret = calloc(n, m);
+ if (ret || !n || !m)
+ return ret;
+ liberror_save_backtrace(NULL);
+ liberror_calloc_failed(n, m);
+ return NULL;
+}
diff --git a/chdir.c b/chdir.c
new file mode 100644
index 0000000..9ed27a4
--- /dev/null
+++ b/chdir.c
@@ -0,0 +1,54 @@
+/* See LICENSE file for copyright and license details. */
+#include "internal.h"
+
+
+void
+liberror_chdir_failed(const char *path)
+{
+ const char *desc;
+ switch (errno) {
+ case EFAULT:
+ if (!path)
+ desc = "Path parameter is NULL";
+ else
+ desc = "Path parameter is an invalid pointer";
+ break;
+ case EACCES:
+ desc = "Search permission is denied for any component of the path";
+ break;
+ case ELOOP:
+ desc = "A symbolic link chain in the path too long or circular";
+ break;
+ case ENAMETOOLONG:
+ desc = "The canonical path or intermediate result in pathname resolution is too long";
+ break;
+ case ENOENT:
+ if (!*path)
+ desc = "Path parameter is the empty string";
+ else
+ desc = "A component of path does not name an existing directory";
+ break;
+ case ENOTDIR:
+ desc = "A component of path is not a directory";
+ break;
+ case ENOMEM:
+ desc = "Insufficient kernel memory was available";
+ break;
+ case EIO:
+ default:
+ desc = "";
+ break;
+ }
+ liberror_libc_set_error_one_file(desc, "chdir", "Directory file", -1, path);
+}
+
+
+int
+liberror_chdir(const char *path)
+{
+ if (!chdir(path))
+ return 0;
+ liberror_save_backtrace(NULL);
+ liberror_chdir_failed(path);
+ return -1;
+}
diff --git a/imaxabs.c b/imaxabs.c
index 22d3d10..8100894 100644
--- a/imaxabs.c
+++ b/imaxabs.c
@@ -2,6 +2,16 @@
#include "internal.h"
+void
+liberror_imaxabs_failed(intmax_t i)
+{
+ liberror_set_error_errno("The absolute value of largest negative integer "
+ "cannot be represented as a signed integer",
+ "imaxabs", EOVERFLOW);
+ (void) i;
+}
+
+
intmax_t
liberror_imaxabs(intmax_t i)
{
@@ -11,9 +21,7 @@ liberror_imaxabs(intmax_t i)
if (i != INTMAX_MIN)
return imaxabs(i);
liberror_save_backtrace(NULL);
- liberror_set_error_errno("The absolute value of largest negative integer "
- "cannot be represented as a signed integer",
- "imaxabs", EOVERFLOW);
+ liberror_imaxabs_failed(i);
return i;
#endif
}
diff --git a/internal.h b/internal.h
index ccc4ebe..9f1119a 100644
--- a/internal.h
+++ b/internal.h
@@ -1,9 +1,12 @@
/* See LICENSE file for copyright and license details. */
#include "liberror-libc.h"
+#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
+#include <fcntl.h>
#include <inttypes.h>
+#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
diff --git a/labs.c b/labs.c
index 7e1ea0a..2a5f050 100644
--- a/labs.c
+++ b/labs.c
@@ -2,6 +2,16 @@
#include "internal.h"
+void
+liberror_labs_failed(long int i)
+{
+ liberror_set_error_errno("The absolute value of largest negative integer "
+ "cannot be represented as a signed integer",
+ "labs", EOVERFLOW);
+ (void) i;
+}
+
+
long int
liberror_labs(long int i)
{
@@ -11,9 +21,7 @@ liberror_labs(long int i)
if (i != LONG_MIN)
return labs(i);
liberror_save_backtrace(NULL);
- liberror_set_error_errno("The absolute value of largest negative integer "
- "cannot be represented as a signed integer",
- "labs", EOVERFLOW);
+ liberror_labs_failed(i);
return i;
#endif
}
diff --git a/liberror-libc.h b/liberror-libc.h
index fd67f3b..9a67245 100644
--- a/liberror-libc.h
+++ b/liberror-libc.h
@@ -2,18 +2,46 @@
#ifndef LIBERROR_LIBC_H
#define LIBERROR_LIBC_H
+#include <stddef.h>
#include <stdint.h>
+#include <unistd.h>
int liberror_abs(int);
+void liberror_abs_failed(int);
+/* void *liberror_aligned_alloc(size_t, size_t); TODO */
+void *liberror_calloc(size_t, size_t);
+void liberror_calloc_failed(size_t, size_t);
+int liberror_chdir(const char *);
+void liberror_chdir_failed(const char *);
intmax_t liberror_imaxabs(intmax_t);
+void liberror_imaxabs_failed(intmax_t);
long int liberror_labs(long int);
+void liberror_labs_failed(long int);
long long int liberror_llabs(long long int);
+void liberror_llabs_failed(long long int);
+void *liberror_malloc(size_t);
+void liberror_malloc_failed(size_t);
int liberror_pipe(int[2]);
+void liberror_pipe_failed(int[2]);
int liberror_putenv(char *);
+void liberror_putenv_failed(char *);
+int liberror_raise(int);
+void liberror_raise_failed(int);
+void *liberror_realloc(void *, size_t);
+void liberror_realloc_failed(void *, size_t);
+ssize_t liberror_recv(int, void *, size_t, int, const char *);
+void liberror_recv_failed(int, void *, size_t, int, const char *);
+/* void *liberror_posix_memalign(void **, size_t, size_t); TODO */
+ssize_t liberror_send(int, const void *, size_t, int, const char *);
+void liberror_send_failed(int, const void *, size_t, int, const char *);
int liberror_setenv(const char *, const char *, int);
int liberror_shutdown(int, int, const char *);
+void liberror_shutdown_failed(int, int, const char *);
+int liberror_sockatmark(int, const char *);
+void liberror_sockatmark_failed(int, const char *);
int liberror_unsetenv(const char *);
+void liberror_unsetenv_failed(const char *);
#endif
diff --git a/llabs.c b/llabs.c
index 6aa6362..539a0c4 100644
--- a/llabs.c
+++ b/llabs.c
@@ -2,6 +2,16 @@
#include "internal.h"
+void
+liberror_llabs_failed(long long int i)
+{
+ liberror_set_error_errno("The absolute value of largest negative integer "
+ "cannot be represented as a signed integer",
+ "llabs", EOVERFLOW);
+ (void) i;
+}
+
+
long long int
liberror_llabs(long long int i)
{
@@ -11,9 +21,7 @@ liberror_llabs(long long int i)
if (i != LLONG_MIN)
return llabs(i);
liberror_save_backtrace(NULL);
- liberror_set_error_errno("The absolute value of largest negative integer "
- "cannot be represented as a signed integer",
- "llabs", EOVERFLOW);
+ liberror_llabs(i);
return i;
#endif
}
diff --git a/malloc.c b/malloc.c
new file mode 100644
index 0000000..4d40572
--- /dev/null
+++ b/malloc.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "internal.h"
+
+
+void
+liberror_malloc_failed(size_t n)
+{
+ liberror_set_error_errno("Out of memory", "malloc", ENOMEM);
+ errno = ENOMEM;
+ (void) n;
+}
+
+
+void *
+liberror_malloc(size_t n)
+{
+ void *ret = malloc(n);
+ if (ret || !n)
+ return ret;
+ liberror_save_backtrace(NULL);
+ liberror_malloc_failed(n);
+ return NULL;
+}
diff --git a/pipe.c b/pipe.c
index 3c0fed5..a0cd32f 100644
--- a/pipe.c
+++ b/pipe.c
@@ -2,19 +2,16 @@
#include "internal.h"
-int
-liberror_pipe(int fds[2])
+void
+liberror_pipe_failed(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";
+ if (!fds)
+ desc = "Output parameter is NULL";
+ else
+ desc = "Output parameter is an invalid pointer";
break;
case EMFILE:
desc = "The process have too many file descriptors open";
@@ -26,8 +23,17 @@ liberror_pipe(int fds[2])
desc = "";
break;
}
-error:
- liberror_save_backtrace(NULL);
liberror_set_error_errno(desc, "pipe", errno);
+ (void) fds;
+}
+
+
+int
+liberror_pipe(int fds[2])
+{
+ if (!pipe(fds))
+ return 0;
+ liberror_save_backtrace(NULL);
+ liberror_pipe_failed(fds);
return -1;
}
diff --git a/putenv.c b/putenv.c
index 18cf2cf..ad9189f 100644
--- a/putenv.c
+++ b/putenv.c
@@ -2,6 +2,26 @@
#include "internal.h"
+void
+liberror_putenv_failed(char *string)
+{
+ const char *desc;
+ if (!string) {
+ errno = EINVAL;
+ desc = "Environment string is NULL";
+ } else if (*string == '=') {
+ errno = EINVAL;
+ desc = "Environment variable name is the empty string";
+ } else if (!strchr(string, '=')) {
+ errno = EINVAL;
+ desc = "Environment does not contain an '=' symbol";
+ } else {
+ desc = "";
+ }
+ liberror_set_error_errno(desc, "putenv", errno);
+}
+
+
int
liberror_putenv(char *string)
{
diff --git a/raise.c b/raise.c
new file mode 100644
index 0000000..fce51bd
--- /dev/null
+++ b/raise.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "internal.h"
+
+
+void
+liberror_raise_failed(int sig)
+{
+ const char *desc = "";
+ if (errno == EINVAL)
+ desc = "Invalid signal number";
+ liberror_set_error_errno(desc, "raise", errno);
+ (void) sig;
+}
+
+
+int
+liberror_raise(int sig)
+{
+ if (!raise(sig))
+ return 0;
+ liberror_save_backtrace(NULL);
+ liberror_raise_failed(sig);
+ return -1;
+}
diff --git a/realloc.c b/realloc.c
new file mode 100644
index 0000000..a029221
--- /dev/null
+++ b/realloc.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "internal.h"
+
+
+void
+liberror_realloc_failed(void *ptr, size_t n)
+{
+ liberror_set_error_errno("Out of memory", "realloc", ENOMEM);
+ errno = ENOMEM;
+ (void) ptr;
+ (void) n;
+}
+
+
+void *
+liberror_realloc(void *ptr, size_t n)
+{
+ void *ret = realloc(ptr, n);
+ if (ret || !n)
+ return ret;
+ liberror_save_backtrace(NULL);
+ liberror_realloc_failed(ptr, n);
+ return NULL;
+}
diff --git a/recv.c b/recv.c
new file mode 100644
index 0000000..03985ba
--- /dev/null
+++ b/recv.c
@@ -0,0 +1,124 @@
+/* See LICENSE file for copyright and license details. */
+#include "internal.h"
+
+
+void
+liberror_recv_failed(int fd, void *buf, size_t n, int flags, const char *fname)
+{
+ const char *desc;
+ int saved_errno, val;
+ struct timeval tv;
+ switch (errno) {
+#if defined(EAGAIN)
+ case EAGAIN:
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || EAGAIN != EWOULDBLOCK)
+ case EWOULDBLOCK:
+#endif
+#if defined(EAGAIN) || defined(EWOULDBLOCK)
+ saved_errno = errno;
+ if (flags & MSG_OOB) {
+ desc = "Attempting to receive in nonblocking mode but the operation would block, "
+ "attempting to receive with time out and the operation timed out "
+ "or the socket does not support blocking to await out-of-band data";
+ if (flags & MSG_DONTWAIT) {
+ msg_oob_nonblocking:
+ desc = "Attempting to receive in nonblocking mode but the operation would block or"
+ " the socket does not support blocking to await out-of-band data";
+ } else if ((val = fcntl(fd, F_GETFL)) < 0) {
+ /* Do nothing */
+ } else if (val & O_NONBLOCK) {
+ goto msg_oob_nonblocking;
+ } else if (getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &(socklen_t){(socklen_t)sizeof(tv)}) ||
+ tv.tv_sec || tv.tv_usec) {
+ desc = "Attempting to receive with time out and the operation timed out or"
+ " the socket does not support blocking to await out-of-band data";
+ } else {
+ desc = "The socket does not support blocking to await out-of-band data";
+ }
+ } else {
+ desc = "Attempting to receive in nonblocking mode but the operation would block "
+ "or attempting to receive with time out and the operation timed out";
+ if (flags & MSG_DONTWAIT) {
+ no_msg_oob_nonblocking:
+ desc = "Attempting to receive in nonblocking mode but the operation would block";
+ } else if ((val = fcntl(fd, F_GETFL)) < 0) {
+ /* Do nothing */
+ } else if (val & O_NONBLOCK) {
+ goto no_msg_oob_nonblocking;
+ } else if (!getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &(socklen_t){(socklen_t)sizeof(tv)}) &&
+ !tv.tv_sec && !tv.tv_usec) {
+ desc = "Attempting to receive with time out and the operation timed out";
+ }
+ }
+ errno = saved_errno;
+ break;
+#endif
+ case EBADF:
+ if (fd < 0)
+ desc = "Negative file descriptor number specified";
+ else
+ desc = "Unassigned file descriptor number specified";
+ break;
+ case ECONNREFUSED:
+ desc = "The remote host refused to allow the network connection";
+ break;
+ case ECONNRESET:
+ desc = "The connection was forcibly closed by a peer";
+ break;
+ case EFAULT:
+ desc = "Invalid user space address specified in the second argument";
+ break;
+ case EINTR:
+ desc = "System call was interrupted by a signal or machine suspension";
+ break;
+ case EINVAL:
+ if (fd < 0)
+ desc = "Negative file descriptor number specified";
+ else if ((flags & ~(MSG_PEEK | MSG_WAITALL)) == MSG_OOB)
+ desc = "No out-of-band data is available";
+ else if (flags & MSG_OOB)
+ desc = "No out-of-band data is available or non-existing flag is specified";
+ else
+ desc = "Non-existing flag is specified";
+ break;
+ case EIO:
+ desc = "An I/O error occurred while reading from or writing to the file system";
+ break;
+ case ENOBUFS:
+ desc = "Insufficient resource available in the system to perform the operation";
+ break;
+ case ENOMEM:
+ desc = "Out of memory";
+ break;
+ case ENOTCONN:
+ desc = "The socket is not connected";
+ break;
+ case ENOTSOCK:
+ desc = "The file descriptor refer to a non-socket file";
+ break;
+ case EOPNOTSUPP:
+ desc = "A flag that is not supported for the socket protocol is specified";
+ break;
+ case ETIMEDOUT:
+ desc = "The connection timed out during connection establishment, "
+ "or due to a transmission timeout on active connection";
+ break;
+ default:
+ desc = "";
+ break;
+ }
+ liberror_libc_set_error_one_file(desc, "recv", "Socket file", fd, fname);
+}
+
+
+ssize_t
+liberror_recv(int fd, void *buf, size_t n, int flags, const char *fname)
+{
+ ssize_t r = recv(fd, buf, n, flags);
+ if (r >= 0)
+ return r;
+ liberror_save_backtrace(NULL);
+ liberror_recv_failed(fd, buf, n, flags, fname);
+ return -1;
+}
diff --git a/send.c b/send.c
new file mode 100644
index 0000000..b902dbe
--- /dev/null
+++ b/send.c
@@ -0,0 +1,157 @@
+/* See LICENSE file for copyright and license details. */
+#include "internal.h"
+
+
+void
+liberror_send_failed(int fd, const void *buf, size_t n, int flags, const char *fname)
+{
+ const char *desc;
+ int saved_errno, val;
+ struct sockaddr_storage addr;
+ socklen_t len = 0;
+ switch (errno) {
+ case EACCES:
+ desc = "The calling process does not have appropriate privileges";
+ saved_errno = errno;
+ if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &val, &(socklen_t){(socklen_t)sizeof(val)})) {
+ /* Do nothing */
+ } else if (val == PF_LOCAL) {
+ desc = "Write or search permission to the destination socket file is denied";
+ } else if (val != PF_INET && val != PF_INET6) {
+ /* Do nothing */
+ } else if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &val, &(socklen_t){(socklen_t)sizeof(val)})) {
+ /* Do nothing */
+ } else if (val != SOCK_DGRAM) {
+ /* Do nothing */
+ } else if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &val, &(socklen_t){(socklen_t)sizeof(val)})) {
+ /* Do nothing */
+ } else if (val == IPPROTO_UDP) {
+ desc = "An attempt was made to send to a network/broadcast address as though it was a unicast address";
+ }
+ errno = saved_errno;
+ break;
+#if defined(EAGAIN)
+ case EAGAIN:
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || EAGAIN != EWOULDBLOCK)
+ case EWOULDBLOCK:
+#endif
+#if defined(EAGAIN) || defined(EWOULDBLOCK)
+ desc = "Attempting to send in nonblocking mode but the operation would block "
+ "or the socket is unbound and all ephemeral ports are currently in used";
+# if defined(EAGAIN)
+# if defined(EWOULDBLOCK) && (EAGAIN != EWOULDBLOCK)
+ if (errno == EAGAIN) {
+# endif
+ saved_errno = errno;
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &val, &(socklen_t){(socklen_t)sizeof(val)})) {
+ /* Do nothing */
+ } else if (val != SOCK_DGRAM) {
+ goto first_case_in_eagain;
+ } else if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &val, &(socklen_t){(socklen_t)sizeof(val)})) {
+ /* Do nothing */
+ } else if (val != PF_INET && val != PF_INET6) {
+ goto first_case_in_eagain;
+ } else if (len = 0, getsockname(fd, (void *)&addr, &len)) {
+ /* Do nothing */
+ } else if ((len && addr.ss_family == AF_INET && ((struct sockaddr_in *)&addr)->sin_port) ||
+ (len && addr.ss_family == AF_INET6 && ((struct sockaddr_in6 *)&addr)->sin6_port)) {
+ first_case_in_eagain:
+ desc = "Attempting to send in nonblocking mode but the operation would block";
+ }
+ errno = saved_errno;
+# if defined(EWOULDBLOCK) && (EAGAIN != EWOULDBLOCK)
+ } else {
+ goto first_case_in_eagain:
+ }
+# endif
+# endif
+ break;
+#endif
+ case EALREADY:
+ desc = "Another Fast Open is already in progress";
+ break;
+ case EBADF:
+ if (fd < 0)
+ desc = "Negative file descriptor number specified";
+ else
+ desc = "Unassigned file descriptor number specified";
+ break;
+ case ECONNRESET:
+ desc = "The peer has closed the connection without reading all received messages";
+ break;
+ case EDESTADDRREQ:
+ desc = "The no peer address is set";
+ break;
+ case EFAULT:
+ desc = "Invalid user space address specified in the second argument";
+ break;
+ case EINTR:
+ desc = "System call was interrupted by a signal or machine suspension";
+ break;
+ case EINVAL:
+ if (fd < 0)
+ desc = "Negative file descriptor number specified";
+ else
+ desc = "Non-existing flag is specified";
+ break;
+ case EIO:
+ desc = "An I/O error occurred while reading from or writing to the file system";
+ break;
+ case EISCONN:
+ desc = "The recipient is specified but the socket is already connected";
+ break;
+ case EMSGSIZE:
+ desc = "Message is to large to be sent atomically as required by the socket type";
+ break;
+ case ENETDOWN:
+ desc = "All local network interfaces that can be used to reach the destination are down";
+ break;
+ case ENETUNREACH:
+ desc = "No route to the network it present";
+ break;
+ case ENOBUFS:
+ desc = "Insufficient resource available in the system to perform the operation";
+ break;
+ case ENOMEM:
+ desc = "Out of memory";
+ break;
+ case ENOTCONN:
+ desc = "The socket is not connected";
+ break;
+ case ENOTSOCK:
+ desc = "The file descriptor refer to a non-socket file";
+ break;
+ case EOPNOTSUPP:
+ desc = "A flag that is not supported for the socket protocol is specified";
+ break;
+ case EPIPE:
+ desc = "The socket is shut down for writing or is no longer connected";
+ saved_errno = errno;
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &val, &(socklen_t){(socklen_t)sizeof(val)})) {
+ /* Do nothing */
+ } else if (val == SOCK_DGRAM) {
+ desc = "The socket is shut down";
+ } else if (getpeername(fd, (void *)&addr, &len) && errno == ENOTCONN) {
+ desc = "The socket is no longer connected";
+ }
+ errno = saved_errno;
+ break;
+ default:
+ desc = "";
+ break;
+ }
+ liberror_libc_set_error_one_file(desc, "send", "Socket file", fd, fname);
+}
+
+
+ssize_t
+liberror_send(int fd, const void *buf, size_t n, int flags, const char *fname)
+{
+ ssize_t r = send(fd, buf, n, flags);
+ if (r >= 0)
+ return r;
+ liberror_save_backtrace(NULL);
+ liberror_send_failed(fd, buf, n, flags, fname);
+ return -1;
+}
diff --git a/shutdown.c b/shutdown.c
index ca6049b..7ea4103 100644
--- a/shutdown.c
+++ b/shutdown.c
@@ -2,33 +2,43 @@
#include "internal.h"
-int
-liberror_shutdown(int fd, int how, const char *fname)
+void
+liberror_shutdown_failed(int fd, int how, const char *fname)
{
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";
+ if (fd < 0)
+ desc = "Negative file descriptor number specified";
+ else
+ desc = "Unassigned file descriptor number specified";
break;
case EINVAL:
desc = "Invalid value of second parameter";
break;
+ case ENOBUFS:
+ desc = "Insufficient resource available in the system to perform the operation";
+ 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";
+ desc = "The file descriptor refer to a non-socket file";
break;
default:
desc = "";
break;
}
- liberror_save_backtrace(NULL);
liberror_libc_set_error_one_file(desc, "shutdown", "Socket file", fd, fname);
+}
+
+
+int
+liberror_shutdown(int fd, int how, const char *fname)
+{
+ if (!shutdown(fd, how))
+ return 0;
+ liberror_save_backtrace(NULL);
+ liberror_shutdown_failed(fd, how, fname);
return -1;
}
diff --git a/sockatmark.c b/sockatmark.c
new file mode 100644
index 0000000..aa5a20e
--- /dev/null
+++ b/sockatmark.c
@@ -0,0 +1,37 @@
+/* See LICENSE file for copyright and license details. */
+#include "internal.h"
+
+
+void
+liberror_sockatmark_failed(int fd, const char *fname)
+{
+ const char *desc;
+ switch (errno) {
+ case EBADF:
+ if (fd < 0)
+ desc = "Negative file descriptor number specified";
+ else
+ desc = "Unassigned file descriptor number specified";
+ break;
+ case ENOTSOCK:
+ case ENOTTY:
+ case EINVAL:
+ desc = "Operation not supported by specified file";
+ break;
+ default:
+ desc = "";
+ break;
+ }
+ liberror_libc_set_error_one_file(desc, "sockatmark", "Socket file", fd, fname);
+}
+
+
+int
+liberror_sockatmark(int fd, const char *fname)
+{
+ if (!sockatmark(fd))
+ return 0;
+ liberror_save_backtrace(NULL);
+ liberror_sockatmark_failed(fd, fname);
+ return -1;
+}
diff --git a/unsetenv.c b/unsetenv.c
index 1462618..82eebcb 100644
--- a/unsetenv.c
+++ b/unsetenv.c
@@ -2,23 +2,26 @@
#include "internal.h"
-int
-liberror_unsetenv(const char *name)
+void
+liberror_unsetenv_failed(const char *name)
{
const char *desc = "";
- if (!name) {
- errno = EINVAL;
+ if (!name)
desc = "Environment variable name is NULL";
- goto error;
- } else if (!unsetenv(name)) {
- return 0;
- } else if (!*name) {
+ else if (!*name)
desc = "Environment variable name is the empty string";
- } else if (errno == EINVAL) {
+ else if (errno == EINVAL)
desc = "Environment variable name contains the '=' character";
- }
-error:
- liberror_save_backtrace(NULL);
liberror_set_error_errno(desc, "setenv", errno);
+}
+
+
+int
+liberror_unsetenv(const char *name)
+{
+ if (!unsetenv(name))
+ return 0;
+ liberror_save_backtrace(NULL);
+ liberror_unsetenv_failed(name);
return -1;
}