• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucode/platform.c

  1 /*
  2  * Copyright (C) 2023 Jo-Philipp Wich <jo@mein.io>
  3  *
  4  * Permission to use, copy, modify, and/or distribute this software for any
  5  * purpose with or without fee is hereby granted, provided that the above
  6  * copyright notice and this permission notice appear in all copies.
  7  *
  8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15  */
 16 
 17 #include <errno.h>
 18 #include <fcntl.h>
 19 #include <unistd.h>
 20 
 21 #include "ucode/internal/platform.h"
 22 
 23 const char *uc_system_signal_names[UC_SYSTEM_SIGNAL_COUNT] = {
 24 #if defined(SIGINT)
 25         [SIGINT] = "INT",
 26 #endif
 27 #if defined(SIGILL)
 28         [SIGILL] = "ILL",
 29 #endif
 30 #if defined(SIGABRT)
 31         [SIGABRT] = "ABRT",
 32 #endif
 33 #if defined(SIGFPE)
 34         [SIGFPE] = "FPE",
 35 #endif
 36 #if defined(SIGSEGV)
 37         [SIGSEGV] = "SEGV",
 38 #endif
 39 #if defined(SIGTERM)
 40         [SIGTERM] = "TERM",
 41 #endif
 42 #if defined(SIGHUP)
 43         [SIGHUP] = "HUP",
 44 #endif
 45 #if defined(SIGQUIT)
 46         [SIGQUIT] = "QUIT",
 47 #endif
 48 #if defined(SIGTRAP)
 49         [SIGTRAP] = "TRAP",
 50 #endif
 51 #if defined(SIGKILL)
 52         [SIGKILL] = "KILL",
 53 #endif
 54 #if defined(SIGPIPE)
 55         [SIGPIPE] = "PIPE",
 56 #endif
 57 #if defined(SIGALRM)
 58         [SIGALRM] = "ALRM",
 59 #endif
 60 #if defined(SIGSTKFLT)
 61         [SIGSTKFLT] = "STKFLT",
 62 #endif
 63 #if defined(SIGPWR)
 64         [SIGPWR] = "PWR",
 65 #endif
 66 #if defined(SIGBUS)
 67         [SIGBUS] = "BUS",
 68 #endif
 69 #if defined(SIGSYS)
 70         [SIGSYS] = "SYS",
 71 #endif
 72 #if defined(SIGURG)
 73         [SIGURG] = "URG",
 74 #endif
 75 #if defined(SIGSTOP)
 76         [SIGSTOP] = "STOP",
 77 #endif
 78 #if defined(SIGTSTP)
 79         [SIGTSTP] = "TSTP",
 80 #endif
 81 #if defined(SIGCONT)
 82         [SIGCONT] = "CONT",
 83 #endif
 84 #if defined(SIGCHLD)
 85         [SIGCHLD] = "CHLD",
 86 #endif
 87 #if defined(SIGTTIN)
 88         [SIGTTIN] = "TTIN",
 89 #endif
 90 #if defined(SIGTTOU)
 91         [SIGTTOU] = "TTOU",
 92 #endif
 93 #if defined(SIGPOLL)
 94         [SIGPOLL] = "POLL",
 95 #endif
 96 #if defined(SIGXFSZ)
 97         [SIGXFSZ] = "XFSZ",
 98 #endif
 99 #if defined(SIGXCPU)
100         [SIGXCPU] = "XCPU",
101 #endif
102 #if defined(SIGVTALRM)
103         [SIGVTALRM] = "VTALRM",
104 #endif
105 #if defined(SIGPROF)
106         [SIGPROF] = "PROF",
107 #endif
108 #if defined(SIGUSR1)
109         [SIGUSR1] = "USR1",
110 #endif
111 #if defined(SIGUSR2)
112         [SIGUSR2] = "USR2",
113 #endif
114 #if defined(SIGWINCH)
115         [SIGWINCH] = "WINCH",
116 #endif
117 };
118 
119 
120 #ifdef __APPLE__
121 int
122 pipe2(int pipefd[2], int flags)
123 {
124         if (pipe(pipefd) != 0)
125                 return -1;
126 
127         if (flags & O_CLOEXEC) {
128                 if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) != 0 ||
129                     fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) != 0) {
130                         close(pipefd[0]);
131                         close(pipefd[1]);
132 
133                         return -1;
134                 }
135 
136                 flags &= ~O_CLOEXEC;
137         }
138 
139         if (fcntl(pipefd[0], F_SETFL, flags) != 0 ||
140             fcntl(pipefd[1], F_SETFL, flags) != 0) {
141                 close(pipefd[0]);
142                 close(pipefd[1]);
143 
144                 return -1;
145         }
146 
147         return 0;
148 }
149 
150 /*
151  * sigtimedwait() implementation based on
152  * https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation
153  * and
154  * https://github.com/wahern/lunix/blob/master/src/unix.c
155  */
156 static void
157 sigtimedwait_consume_signal(int signo)
158 {
159 }
160 
161 int
162 sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
163 {
164         struct timespec elapsed = { 0, 0 }, sleep, rem;
165         sigset_t pending, unblock, omask;
166         struct sigaction sa, osa;
167         int signo;
168         bool lt;
169 
170         while (true) {
171                 sigemptyset(&pending);
172                 sigpending(&pending);
173 
174                 for (signo = 1; signo < NSIG; signo++) {
175                         if (!sigismember(set, signo) || !sigismember(&pending, signo))
176                                 continue;
177 
178                         sa.sa_handler = sigtimedwait_consume_signal;
179                         sa.sa_flags = 0;
180                         sigfillset(&sa.sa_mask);
181 
182                         sigaction(signo, &sa, &osa);
183 
184                         sigemptyset(&unblock);
185                         sigaddset(&unblock, signo);
186                         sigprocmask(SIG_UNBLOCK, &unblock, &omask);
187                         sigprocmask(SIG_SETMASK, &omask, NULL);
188 
189                         sigaction(signo, &osa, NULL);
190 
191                         if (info) {
192                                 memset(info, 0, sizeof(*info));
193                                 info->si_signo = signo;
194                         }
195 
196                         return signo;
197                 }
198 
199                 sleep.tv_sec = 0;
200                 sleep.tv_nsec = 200000000L; /* 2/10th second */
201                 rem = sleep;
202 
203                 if (nanosleep(&sleep, &rem) == 0) {
204                         elapsed.tv_sec += sleep.tv_sec;
205                         elapsed.tv_nsec += sleep.tv_nsec;
206 
207                         if (elapsed.tv_nsec > 1000000000) {
208                                 elapsed.tv_sec++;
209                                 elapsed.tv_nsec -= 1000000000;
210                         }
211                 }
212                 else if (errno == EINTR) {
213                         sleep.tv_sec -= rem.tv_sec;
214                         sleep.tv_nsec -= rem.tv_nsec;
215 
216                         if (sleep.tv_nsec < 0) {
217                                 sleep.tv_sec--;
218                                 sleep.tv_nsec += 1000000000;
219                         }
220 
221                         elapsed.tv_sec += sleep.tv_sec;
222                         elapsed.tv_nsec += sleep.tv_nsec;
223 
224                         if (elapsed.tv_nsec > 1000000000) {
225                                 elapsed.tv_sec++;
226                                 elapsed.tv_nsec -= 1000000000;
227                         }
228                 }
229                 else {
230                         return errno;
231                 }
232 
233                 lt = timeout
234                         ? ((elapsed.tv_sec == timeout->tv_sec)
235                                 ? (elapsed.tv_nsec < timeout->tv_nsec)
236                                 : (elapsed.tv_sec < timeout->tv_sec))
237                         : true;
238 
239                 if (!lt)
240                         break;
241         }
242 
243         errno = EAGAIN;
244 
245         return -1;
246 }
247 #endif
248 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt