]> git.sur5r.net Git - i3/i3/blob - libi3/safewrappers.c
04bbda44c8ae233d83a9fea4f0608a2b933e1bd7
[i3/i3] / libi3 / safewrappers.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
6  *
7  */
8 #include "libi3.h"
9
10 #include <string.h>
11 #include <stdlib.h>
12 #include <stdarg.h>
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <err.h>
16 #include <errno.h>
17
18 /*
19  * The s* functions (safe) are wrappers around malloc, strdup, …, which exits if one of
20  * the called functions returns NULL, meaning that there is no more memory available
21  *
22  */
23 void *smalloc(size_t size) {
24     void *result = malloc(size);
25     if (result == NULL)
26         err(EXIT_FAILURE, "malloc(%zd)", size);
27     return result;
28 }
29
30 void *scalloc(size_t num, size_t size) {
31     void *result = calloc(num, size);
32     if (result == NULL)
33         err(EXIT_FAILURE, "calloc(%zd, %zd)", num, size);
34     return result;
35 }
36
37 void *srealloc(void *ptr, size_t size) {
38     void *result = realloc(ptr, size);
39     if (result == NULL && size > 0)
40         err(EXIT_FAILURE, "realloc(%zd)", size);
41     return result;
42 }
43
44 char *sstrdup(const char *str) {
45     char *result = strdup(str);
46     if (result == NULL)
47         err(EXIT_FAILURE, "strdup()");
48     return result;
49 }
50
51 char *sstrndup(const char *str, size_t size) {
52     char *result = strndup(str, size);
53     if (result == NULL)
54         err(EXIT_FAILURE, "strndup()");
55     return result;
56 }
57
58 int sasprintf(char **strp, const char *fmt, ...) {
59     va_list args;
60     int result;
61
62     va_start(args, fmt);
63     if ((result = vasprintf(strp, fmt, args)) == -1)
64         err(EXIT_FAILURE, "asprintf(%s)", fmt);
65     va_end(args);
66     return result;
67 }
68
69 ssize_t writeall(int fd, const void *buf, size_t count) {
70     size_t written = 0;
71
72     while (written < count) {
73         const ssize_t n = write(fd, buf + written, count - written);
74         if (n == -1) {
75             if (errno == EINTR || errno == EAGAIN)
76                 continue;
77             return n;
78         }
79         written += (size_t)n;
80     }
81
82     return written;
83 }
84
85 ssize_t writeall_nonblock(int fd, const void *buf, size_t count) {
86     size_t written = 0;
87
88     while (written < count) {
89         const ssize_t n = write(fd, buf + written, count - written);
90         if (n == -1) {
91             if (errno == EAGAIN) {
92                 return written;
93             } else if (errno == EINTR) {
94                 continue;
95             } else {
96                 return n;
97             }
98         }
99         written += (size_t)n;
100     }
101     return written;
102 }
103
104 ssize_t swrite(int fd, const void *buf, size_t count) {
105     ssize_t n;
106
107     n = writeall(fd, buf, count);
108     if (n == -1)
109         err(EXIT_FAILURE, "Failed to write %d", fd);
110     else
111         return n;
112 }