[f8565a] | 1 | /***************************************** |
---|
| 2 | * Computer Algebra System SINGULAR * |
---|
| 3 | *****************************************/ |
---|
| 4 | /* |
---|
| 5 | * ABSTRACT: wrappijng signal-interuptable system calls |
---|
[bc0d32] | 6 | * AUTHOR: Alexander Dreyer, The PolyBoRi Team, 2013 |
---|
[f8565a] | 7 | */ |
---|
| 8 | |
---|
| 9 | #include <signal.h> |
---|
| 10 | #include <errno.h> |
---|
| 11 | #include <sys/types.h> |
---|
| 12 | #include <sys/wait.h> |
---|
| 13 | |
---|
| 14 | #include <unistd.h> |
---|
| 15 | #include <sys/uio.h> |
---|
| 16 | #include <sys/stat.h> |
---|
| 17 | #include <fcntl.h> |
---|
| 18 | #include <sys/socket.h> |
---|
| 19 | #include <time.h> |
---|
[bc0d32] | 20 | #include <stdio.h> |
---|
| 21 | #include <semaphore.h> |
---|
| 22 | #include <stdarg.h> |
---|
[f8565a] | 23 | |
---|
| 24 | #ifndef SINGULAR_SI_SIGNALS_H |
---|
| 25 | #define SINGULAR_SI_SIGNALS_H |
---|
| 26 | |
---|
[bc0d32] | 27 | #define SI_EINTR_SAVE_FUNC_TEMPLATE(return_type, newfunc, func, decl, args, err_domain) \ |
---|
| 28 | static inline return_type newfunc decl \ |
---|
[f8565a] | 29 | { \ |
---|
| 30 | int res = -1; \ |
---|
| 31 | do \ |
---|
| 32 | { \ |
---|
| 33 | res = func args; \ |
---|
[bc0d32] | 34 | } while((res err_domain) && (errno == EINTR));\ |
---|
[f8565a] | 35 | return res; \ |
---|
| 36 | } |
---|
| 37 | |
---|
[bc0d32] | 38 | #define SI_EINTR_SAVE_FUNC(return_type, func, decl, args) \ |
---|
| 39 | SI_EINTR_SAVE_FUNC_TEMPLATE(return_type, si_##func, func, decl, args, < 0) |
---|
| 40 | |
---|
| 41 | #define SI_EINTR_SAVE_SCANF(return_type, func, decl, args) \ |
---|
| 42 | SI_EINTR_SAVE_FUNC_TEMPLATE(return_type, si_##func, func, decl, args, == EOF) |
---|
[f8565a] | 43 | |
---|
| 44 | SI_EINTR_SAVE_FUNC(int, select, |
---|
| 45 | (int nfds, fd_set *readfds, fd_set *writefds, |
---|
| 46 | fd_set *exceptfds, struct timeval *timeout), |
---|
| 47 | (nfds,readfds, writefds, exceptfds, timeout) |
---|
| 48 | ) |
---|
| 49 | |
---|
[bc0d32] | 50 | #ifdef HAVE_PSELECT |
---|
[f8565a] | 51 | SI_EINTR_SAVE_FUNC(int, pselect, |
---|
| 52 | (int nfds, fd_set *readfds, fd_set *writefds, |
---|
| 53 | fd_set *exceptfds, const struct timespec *timeout, |
---|
| 54 | const sigset_t *sigmask), |
---|
| 55 | (nfds, readfds, writefds, exceptfds, timeout,sigmask) |
---|
| 56 | ) |
---|
[bc0d32] | 57 | #endif |
---|
[f8565a] | 58 | |
---|
| 59 | SI_EINTR_SAVE_FUNC(pid_t, wait, (int *status), (status)) |
---|
| 60 | SI_EINTR_SAVE_FUNC(pid_t, waitpid, (pid_t pid, int *status, int options), |
---|
| 61 | (pid, status, options)) |
---|
| 62 | |
---|
[bc0d32] | 63 | //SI_EINTR_SAVE_FUNC(int, waitid, |
---|
| 64 | // (idtype_t idtype, id_t id, siginfo_t *infop, int options), |
---|
| 65 | // (idtype, id, infop, options)) |
---|
[f8565a] | 66 | |
---|
| 67 | SI_EINTR_SAVE_FUNC(ssize_t, read, (int fd, void *buf, size_t count), |
---|
| 68 | (fd, buf, count)) |
---|
| 69 | |
---|
| 70 | |
---|
| 71 | SI_EINTR_SAVE_FUNC(ssize_t, readv, |
---|
| 72 | (int fd, const struct iovec *iov, int iovcnt), |
---|
| 73 | (fd, iov,iovcnt)) |
---|
| 74 | |
---|
| 75 | SI_EINTR_SAVE_FUNC(ssize_t, write, (int fd, const void *buf, size_t count), |
---|
| 76 | (fd, buf, count)) |
---|
| 77 | |
---|
| 78 | SI_EINTR_SAVE_FUNC(ssize_t, writev, (int fd, const struct iovec *iov, int iovcnt), |
---|
| 79 | (fd, iov, iovcnt) ) |
---|
| 80 | |
---|
[bc0d32] | 81 | SI_EINTR_SAVE_FUNC_TEMPLATE(int, si_open1, open, (const char *pathname, int flags), |
---|
| 82 | (pathname, flags), < 0) |
---|
| 83 | SI_EINTR_SAVE_FUNC_TEMPLATE(int, si_open2, open, |
---|
| 84 | (const char *pathname, int flags, mode_t mode), |
---|
| 85 | (pathname, flags, mode), < 0) |
---|
| 86 | |
---|
| 87 | /* Enulate overloading usung preprocessor (we need to be C-compatible) */ |
---|
| 88 | #define SI_GET_FIFTH(_4,_3, _2, _1, N, ...) N |
---|
| 89 | #define si_open(...) SI_GET_FIFTH(X,##__VA_ARGS__, si_open2, si_open1)(__VA_ARGS__) |
---|
| 90 | |
---|
| 91 | SI_EINTR_SAVE_FUNC(int, creat, (const char *pathname, mode_t mode), |
---|
| 92 | (pathname, mode)) |
---|
| 93 | |
---|
[f8565a] | 94 | |
---|
| 95 | SI_EINTR_SAVE_FUNC(int, close, (int fd), (fd)) |
---|
| 96 | |
---|
| 97 | SI_EINTR_SAVE_FUNC(int, accept, |
---|
| 98 | (int sockfd, struct sockaddr *addr, socklen_t *addrlen), |
---|
| 99 | (sockfd, addr, addrlen)) |
---|
[bc0d32] | 100 | |
---|
[f8565a] | 101 | SI_EINTR_SAVE_FUNC(int, connect, |
---|
| 102 | (int sockfd, const struct sockaddr *addr, socklen_t addrlen), |
---|
| 103 | (sockfd, addr, addrlen)) |
---|
| 104 | |
---|
[bc0d32] | 105 | /* @note: We respect that the user may explictely deactivate the |
---|
| 106 | * restart feature by setting the second argumetn to NULL. |
---|
| 107 | */ |
---|
| 108 | static inline int |
---|
| 109 | si_nanosleep(const struct timespec *req, struct timespec *rem) { |
---|
| 110 | |
---|
| 111 | int res = -1; |
---|
| 112 | do |
---|
| 113 | { |
---|
| 114 | res = nanosleep(req, rem); |
---|
| 115 | } while((rem != NULL) && (res < 0) && (errno == EINTR)); |
---|
| 116 | return res; |
---|
| 117 | } |
---|
[f8565a] | 118 | |
---|
[bc0d32] | 119 | static inline unsigned int |
---|
| 120 | si_sleep(unsigned int seconds) |
---|
[f8565a] | 121 | { |
---|
| 122 | do |
---|
| 123 | { |
---|
| 124 | seconds = sleep(seconds); |
---|
| 125 | } while(seconds != 0); |
---|
| 126 | return 0; |
---|
| 127 | } |
---|
| 128 | |
---|
[bc0d32] | 129 | SI_EINTR_SAVE_FUNC(int, dup, (int oldfd), (oldfd)) |
---|
| 130 | SI_EINTR_SAVE_FUNC(int, dup2, (int oldfd, int newfd), (oldfd, newfd)) |
---|
| 131 | //SI_EINTR_SAVE_FUNC(int, dup3, (int oldfd, int newfd, int flags), |
---|
| 132 | // (oldfd, newfd, flags)) |
---|
| 133 | |
---|
| 134 | SI_EINTR_SAVE_FUNC(int, unlink, (const char *pathname), (pathname)) |
---|
| 135 | |
---|
| 136 | SI_EINTR_SAVE_SCANF(int, vscanf, |
---|
| 137 | (const char *format, va_list ap), |
---|
| 138 | (format, ap)) |
---|
| 139 | |
---|
| 140 | static inline |
---|
| 141 | int si_scanf(const char *format, ...) |
---|
| 142 | { |
---|
| 143 | va_list argptr; |
---|
| 144 | va_start(argptr, format); |
---|
| 145 | int res = si_vscanf(format, argptr); |
---|
| 146 | va_end(argptr); |
---|
| 147 | return res; |
---|
| 148 | } |
---|
| 149 | |
---|
| 150 | SI_EINTR_SAVE_SCANF(int, vfscanf, |
---|
| 151 | (FILE *stream, const char *format, va_list ap), |
---|
| 152 | (stream, format, ap)) |
---|
| 153 | |
---|
| 154 | static inline int |
---|
| 155 | si_fscanf(FILE *stream, const char *format, ...) |
---|
| 156 | { |
---|
| 157 | va_list argptr; |
---|
| 158 | va_start(argptr, format); |
---|
| 159 | int res = si_vfscanf(stream, format, argptr); |
---|
| 160 | va_end(argptr); |
---|
| 161 | return res; |
---|
| 162 | } |
---|
| 163 | |
---|
| 164 | SI_EINTR_SAVE_SCANF(int, vsscanf, |
---|
| 165 | (const char *str, const char *format, va_list ap), |
---|
| 166 | (str, format, ap)) |
---|
| 167 | |
---|
| 168 | static inline int |
---|
| 169 | si_sscanf(const char *str, const char *format, ...) |
---|
| 170 | { |
---|
| 171 | va_list argptr; |
---|
| 172 | va_start(argptr, format); |
---|
| 173 | int res = si_vsscanf(str, format, argptr); |
---|
| 174 | va_end(argptr); |
---|
| 175 | return res; |
---|
| 176 | } |
---|
| 177 | |
---|
| 178 | SI_EINTR_SAVE_FUNC(int, stat, (const char *path, struct stat *buf), |
---|
| 179 | (path, buf)) |
---|
| 180 | SI_EINTR_SAVE_FUNC(int, fstat, (int fd, struct stat *buf), |
---|
| 181 | (fd, buf)) |
---|
| 182 | SI_EINTR_SAVE_FUNC(int, lstat, (const char *path, struct stat *buf), |
---|
| 183 | (path, buf)) |
---|
| 184 | |
---|
[f8565a] | 185 | |
---|
[bc0d32] | 186 | SI_EINTR_SAVE_FUNC(int, sigaction, |
---|
| 187 | (int signum, const struct sigaction *act, |
---|
| 188 | struct sigaction *oldact), |
---|
| 189 | (signum, act, oldact)) |
---|
[f8565a] | 190 | |
---|
| 191 | |
---|
[bc0d32] | 192 | #ifdef HAVE_SIGINTERRUPT |
---|
| 193 | SI_EINTR_SAVE_FUNC(int, siginterrupt, (int sig, int flag), |
---|
| 194 | (sig, flag)) |
---|
| 195 | #else |
---|
| 196 | #define si_siginterrupt(arg1, arg2) |
---|
| 197 | #endif |
---|
[f8565a] | 198 | |
---|
| 199 | |
---|
[bc0d32] | 200 | SI_EINTR_SAVE_FUNC(int, sem_wait, (sem_t *sem), (sem)) |
---|
| 201 | SI_EINTR_SAVE_FUNC(int, sem_trywait, (sem_t *sem), (sem)) |
---|
| 202 | //SI_EINTR_SAVE_FUNC(int, sem_timedwait, |
---|
| 203 | // (sem_t *sem, const struct timespec *abs_timeout), |
---|
| 204 | // (sem, abs_timeout)) |
---|
[f8565a] | 205 | |
---|
| 206 | |
---|
| 207 | #undef SI_EINTR_SAVE_FUNC |
---|
| 208 | |
---|
| 209 | |
---|
| 210 | #endif /* SINGULAR_SI_SIGNALS_H */ |
---|