• 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 
 19 #include "ucode/platform.h"
 20 
 21 const char *uc_system_signal_names[UC_SYSTEM_SIGNAL_COUNT] = {
 22 #if defined(SIGINT)
 23         [SIGINT] = "INT",
 24 #endif
 25 #if defined(SIGILL)
 26         [SIGILL] = "ILL",
 27 #endif
 28 #if defined(SIGABRT)
 29         [SIGABRT] = "ABRT",
 30 #endif
 31 #if defined(SIGFPE)
 32         [SIGFPE] = "FPE",
 33 #endif
 34 #if defined(SIGSEGV)
 35         [SIGSEGV] = "SEGV",
 36 #endif
 37 #if defined(SIGTERM)
 38         [SIGTERM] = "TERM",
 39 #endif
 40 #if defined(SIGHUP)
 41         [SIGHUP] = "HUP",
 42 #endif
 43 #if defined(SIGQUIT)
 44         [SIGQUIT] = "QUIT",
 45 #endif
 46 #if defined(SIGTRAP)
 47         [SIGTRAP] = "TRAP",
 48 #endif
 49 #if defined(SIGKILL)
 50         [SIGKILL] = "KILL",
 51 #endif
 52 #if defined(SIGPIPE)
 53         [SIGPIPE] = "PIPE",
 54 #endif
 55 #if defined(SIGALRM)
 56         [SIGALRM] = "ALRM",
 57 #endif
 58 #if defined(SIGSTKFLT)
 59         [SIGSTKFLT] = "STKFLT",
 60 #endif
 61 #if defined(SIGPWR)
 62         [SIGPWR] = "PWR",
 63 #endif
 64 #if defined(SIGBUS)
 65         [SIGBUS] = "BUS",
 66 #endif
 67 #if defined(SIGSYS)
 68         [SIGSYS] = "SYS",
 69 #endif
 70 #if defined(SIGURG)
 71         [SIGURG] = "URG",
 72 #endif
 73 #if defined(SIGSTOP)
 74         [SIGSTOP] = "STOP",
 75 #endif
 76 #if defined(SIGTSTP)
 77         [SIGTSTP] = "TSTP",
 78 #endif
 79 #if defined(SIGCONT)
 80         [SIGCONT] = "CONT",
 81 #endif
 82 #if defined(SIGCHLD)
 83         [SIGCHLD] = "CHLD",
 84 #endif
 85 #if defined(SIGTTIN)
 86         [SIGTTIN] = "TTIN",
 87 #endif
 88 #if defined(SIGTTOU)
 89         [SIGTTOU] = "TTOU",
 90 #endif
 91 #if defined(SIGPOLL)
 92         [SIGPOLL] = "POLL",
 93 #endif
 94 #if defined(SIGXFSZ)
 95         [SIGXFSZ] = "XFSZ",
 96 #endif
 97 #if defined(SIGXCPU)
 98         [SIGXCPU] = "XCPU",
 99 #endif
100 #if defined(SIGVTALRM)
101         [SIGVTALRM] = "VTALRM",
102 #endif
103 #if defined(SIGPROF)
104         [SIGPROF] = "PROF",
105 #endif
106 #if defined(SIGUSR1)
107         [SIGUSR1] = "USR1",
108 #endif
109 #if defined(SIGUSR2)
110         [SIGUSR2] = "USR2",
111 #endif
112 };
113 
114 
115 #ifdef __APPLE__
116 int
117 pipe2(int pipefd[2], int flags)
118 {
119         if (pipe(pipefd) != 0)
120                 return -1;
121 
122         if (flags & O_CLOEXEC) {
123                 if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) != 0 ||
124                     fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) != 0) {
125                         close(pipefd[0]);
126                         close(pipefd[1]);
127 
128                         return -1;
129                 }
130 
131                 flags &= ~O_CLOEXEC;
132         }
133 
134         if (fcntl(pipefd[0], F_SETFL, flags) != 0 ||
135             fcntl(pipefd[1], F_SETFL, flags) != 0) {
136                 close(pipefd[0]);
137                 close(pipefd[1]);
138 
139                 return -1;
140         }
141 
142         return 0;
143 }
144 
145 /*
146  * sigtimedwait() implementation based on
147  * https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation
148  * and
149  * https://github.com/wahern/lunix/blob/master/src/unix.c
150  */
151 static void
152 sigtimedwait_consume_signal(int signo)
153 {
154 }
155 
156 int
157 sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
158 {
159         struct timespec elapsed = { 0, 0 }, sleep, rem;
160         sigset_t pending, unblock, omask;
161         struct sigaction sa, osa;
162         int signo;
163         bool lt;
164 
165         while (true) {
166                 sigemptyset(&pending);
167                 sigpending(&pending);
168 
169                 for (signo = 1; signo < NSIG; signo++) {
170                         if (!sigismember(set, signo) || !sigismember(&pending, signo))
171                                 continue;
172 
173                         sa.sa_handler = sigtimedwait_consume_signal;
174                         sa.sa_flags = 0;
175                         sigfillset(&sa.sa_mask);
176 
177                         sigaction(signo, &sa, &osa);
178 
179                         sigemptyset(&unblock);
180                         sigaddset(&unblock, signo);
181                         sigprocmask(SIG_UNBLOCK, &unblock, &omask);
182                         sigprocmask(SIG_SETMASK, &omask, NULL);
183 
184                         sigaction(signo, &osa, NULL);
185 
186                         if (info) {
187                                 memset(info, 0, sizeof(*info));
188                                 info->si_signo = signo;
189                         }
190 
191                         return signo;
192                 }
193 
194                 sleep.tv_sec = 0;
195                 sleep.tv_nsec = 200000000L; /* 2/10th second */
196                 rem = sleep;
197 
198                 if (nanosleep(&sleep, &rem) == 0) {
199                         elapsed.tv_sec += sleep.tv_sec;
200                         elapsed.tv_nsec += sleep.tv_nsec;
201 
202                         if (elapsed.tv_nsec > 1000000000) {
203                                 elapsed.tv_sec++;
204                                 elapsed.tv_nsec -= 1000000000;
205                         }
206                 }
207                 else if (errno == EINTR) {
208                         sleep.tv_sec -= rem.tv_sec;
209                         sleep.tv_nsec -= rem.tv_nsec;
210 
211                         if (sleep.tv_nsec < 0) {
212                                 sleep.tv_sec--;
213                                 sleep.tv_nsec += 1000000000;
214                         }
215 
216                         elapsed.tv_sec += sleep.tv_sec;
217                         elapsed.tv_nsec += sleep.tv_nsec;
218 
219                         if (elapsed.tv_nsec > 1000000000) {
220                                 elapsed.tv_sec++;
221                                 elapsed.tv_nsec -= 1000000000;
222                         }
223                 }
224                 else {
225                         return errno;
226                 }
227 
228                 lt = timeout
229                         ? ((elapsed.tv_sec == timeout->tv_sec)
230                                 ? (elapsed.tv_nsec < timeout->tv_nsec)
231                                 : (elapsed.tv_sec < timeout->tv_sec))
232                         : true;
233 
234                 if (!lt)
235                         break;
236         }
237 
238         errno = EAGAIN;
239 
240         return -1;
241 }
242 #endif
243 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt