Commit | Line | Data |
---|---|---|
460b9539 | 1 | /* |
2 | * This file is part of DisOrder. | |
cca89d7c | 3 | * Copyright (C) 2004, 2005, 2007-9, 2013 Richard Kettlewell |
460b9539 | 4 | * |
e7eb3a27 | 5 | * This program is free software: you can redistribute it and/or modify |
460b9539 | 6 | * it under the terms of the GNU General Public License as published by |
e7eb3a27 | 7 | * the Free Software Foundation, either version 3 of the License, or |
460b9539 | 8 | * (at your option) any later version. |
e7eb3a27 RK |
9 | * |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
460b9539 | 15 | * You should have received a copy of the GNU General Public License |
e7eb3a27 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
460b9539 | 17 | */ |
132a5a4a RK |
18 | /** @file lib/syscalls.c |
19 | * @brief Error-checking library call wrappers | |
20 | */ | |
05b75f8d | 21 | #include "common.h" |
460b9539 | 22 | |
cca89d7c RK |
23 | #if HAVE_UNISTD_H |
24 | # include <unistd.h> | |
25 | #endif | |
460b9539 | 26 | #include <errno.h> |
27 | #include <fcntl.h> | |
28 | #include <sys/types.h> | |
cca89d7c RK |
29 | #if HAVE_SYS_SOCKET_H |
30 | # include <sys/socket.h> | |
31 | #endif | |
32 | #if HAVE_SYS_TIME_H | |
33 | # include <sys/time.h> | |
34 | #endif | |
460b9539 | 35 | #include <signal.h> |
5db8461a | 36 | #include <time.h> |
460b9539 | 37 | |
38 | #include "syscalls.h" | |
39 | #include "log.h" | |
40 | #include "printf.h" | |
41 | ||
42 | int mustnotbeminus1(const char *what, int ret) { | |
43 | if(ret == -1) | |
2e9ba080 | 44 | disorder_fatal(errno, "error calling %s", what); |
460b9539 | 45 | return ret; |
46 | } | |
47 | ||
9e42afcd | 48 | #if !_WIN32 |
460b9539 | 49 | pid_t xfork(void) { |
50 | pid_t pid; | |
51 | ||
2e9ba080 RK |
52 | if((pid = fork()) < 0) |
53 | disorder_fatal(errno, "error calling fork"); | |
460b9539 | 54 | return pid; |
55 | } | |
56 | ||
8bb67afe RK |
57 | void xclose_guts(const char *path, int line, int fd) { |
58 | if(close(fd) < 0) | |
2e9ba080 | 59 | disorder_fatal(errno, "%s:%d: close %d", path, line, fd); |
460b9539 | 60 | } |
61 | ||
62 | void xdup2(int fd1, int fd2) { | |
63 | mustnotbeminus1("dup2", dup2(fd1, fd2)); | |
64 | } | |
65 | ||
66 | void xpipe(int *fdp) { | |
67 | mustnotbeminus1("pipe", pipe(fdp)); | |
68 | } | |
69 | ||
70 | void nonblock(int fd) { | |
71 | mustnotbeminus1("fcntl F_SETFL", | |
72 | fcntl(fd, F_SETFL, | |
73 | mustnotbeminus1("fcntl F_GETFL", | |
74 | fcntl(fd, F_GETFL)) | O_NONBLOCK)); | |
75 | } | |
76 | ||
937be4c0 RK |
77 | void blocking(int fd) { |
78 | mustnotbeminus1("fcntl F_SETFL", | |
79 | fcntl(fd, F_SETFL, | |
80 | mustnotbeminus1("fcntl F_GETFL", | |
81 | fcntl(fd, F_GETFL)) & ~O_NONBLOCK)); | |
82 | } | |
83 | ||
460b9539 | 84 | void cloexec(int fd) { |
85 | mustnotbeminus1("fcntl F_SETFD", | |
86 | fcntl(fd, F_SETFD, | |
87 | mustnotbeminus1("fcntl F_GETFD", | |
88 | fcntl(fd, F_GETFD)) | FD_CLOEXEC)); | |
89 | } | |
9e42afcd | 90 | #endif |
460b9539 | 91 | |
9e42afcd | 92 | void xlisten(SOCKET fd, int q) { |
460b9539 | 93 | mustnotbeminus1("listen", listen(fd, q)); |
94 | } | |
95 | ||
9e42afcd | 96 | void xshutdown(SOCKET fd, int how) { |
460b9539 | 97 | mustnotbeminus1("shutdown", shutdown(fd, how)); |
98 | } | |
99 | ||
9e42afcd | 100 | void xsetsockopt(SOCKET fd, int l, int o, const void *v, socklen_t vl) { |
460b9539 | 101 | mustnotbeminus1("setsockopt", setsockopt(fd, l, o, v, vl)); |
102 | } | |
103 | ||
9e42afcd RK |
104 | SOCKET xsocket(int d, int t, int p) { |
105 | SOCKET s = socket(d, t, p); | |
106 | if(s == INVALID_SOCKET) | |
107 | disorder_fatal(errno, "error calling socket"); | |
108 | return s; | |
460b9539 | 109 | } |
110 | ||
9e42afcd | 111 | void xconnect(SOCKET fd, const struct sockaddr *sa, socklen_t sl) { |
460b9539 | 112 | mustnotbeminus1("connect", connect(fd, sa, sl)); |
113 | } | |
114 | ||
9e42afcd | 115 | #if !_WIN32 |
460b9539 | 116 | void xsigprocmask(int how, const sigset_t *set, sigset_t *oldset) { |
117 | mustnotbeminus1("sigprocmask", sigprocmask(how, set, oldset)); | |
118 | } | |
119 | ||
120 | void xsigaction(int sig, const struct sigaction *sa, struct sigaction *oldsa) { | |
121 | mustnotbeminus1("sigaction", sigaction(sig, sa, oldsa)); | |
122 | } | |
9e42afcd | 123 | #endif |
460b9539 | 124 | |
125 | int xprintf(const char *fmt, ...) { | |
126 | va_list ap; | |
127 | int n; | |
128 | ||
129 | va_start(ap, fmt); | |
130 | n = mustnotbeminus1("byte_vfprintf", byte_vfprintf(stdout, fmt, ap)); | |
131 | va_end(ap); | |
132 | return n; | |
133 | } | |
134 | ||
135 | void xfclose(FILE *fp) { | |
136 | mustnotbeminus1("fclose", fclose(fp)); | |
137 | } | |
138 | ||
139 | int xstrtol(long *n, const char *s, char **ep, int base) { | |
140 | errno = 0; | |
141 | *n = strtol(s, ep, base); | |
142 | return errno; | |
143 | } | |
144 | ||
145 | int xstrtoll(long_long *n, const char *s, char **ep, int base) { | |
146 | errno = 0; | |
147 | *n = strtoll(s, ep, base); | |
148 | return errno; | |
149 | } | |
150 | ||
9e42afcd | 151 | #if !_WIN32 |
460b9539 | 152 | int xnice(int inc) { |
153 | int ret; | |
154 | ||
155 | /* some versions of nice() return the new nice value which in principle could | |
156 | * be -1 */ | |
157 | errno = 0; | |
158 | ret = nice(inc); | |
2e9ba080 RK |
159 | if(errno) |
160 | disorder_fatal(errno, "error calling nice"); | |
460b9539 | 161 | return ret; |
162 | } | |
9e42afcd | 163 | #endif |
460b9539 | 164 | |
165 | void xgettimeofday(struct timeval *tv, struct timezone *tz) { | |
166 | mustnotbeminus1("gettimeofday", gettimeofday(tv, tz)); | |
167 | } | |
168 | ||
4265e5d3 RK |
169 | time_t xtime(time_t *whenp) { |
170 | struct timeval tv; | |
171 | ||
172 | xgettimeofday(&tv, NULL); | |
173 | if(whenp) | |
174 | *whenp = tv.tv_sec; | |
175 | return tv.tv_sec; | |
176 | } | |
177 | ||
9e42afcd | 178 | #if !_WIN32 |
5db8461a RK |
179 | void xnanosleep(const struct timespec *req, struct timespec *rem) { |
180 | mustnotbeminus1("nanosleep", nanosleep(req, rem)); | |
181 | } | |
9e42afcd | 182 | #endif |
5db8461a | 183 | |
460b9539 | 184 | /* |
185 | Local Variables: | |
186 | c-basic-offset:2 | |
187 | comment-column:40 | |
188 | End: | |
189 | */ |