xref: /openbmc/openbmc-tools/adcapp/src/EINTR_wrappers.c (revision cf3c1e6773c0ea0346874da66a609d22cbf11ec3)
1*cf3c1e67SAndrew Jeffery 
2*cf3c1e67SAndrew Jeffery /*
3*cf3c1e67SAndrew Jeffery * File: EINTR_wrappers.c
4*cf3c1e67SAndrew Jeffery *
5*cf3c1e67SAndrew Jeffery * This file implements the wrapper functions for some of the System APIs
6*cf3c1e67SAndrew Jeffery *
7*cf3c1e67SAndrew Jeffery * Copyright (C) <2019>  <American Megatrends International LLC>
8*cf3c1e67SAndrew Jeffery *
9*cf3c1e67SAndrew Jeffery */
10*cf3c1e67SAndrew Jeffery 
11*cf3c1e67SAndrew Jeffery #include "EINTR_wrappers.h"
12*cf3c1e67SAndrew Jeffery #if defined(__linux__)
13*cf3c1e67SAndrew Jeffery #include <sys/msg.h>
14*cf3c1e67SAndrew Jeffery #include <sys/file.h>
15*cf3c1e67SAndrew Jeffery #endif
16*cf3c1e67SAndrew Jeffery #include <errno.h>
17*cf3c1e67SAndrew Jeffery #include <unistd.h>
18*cf3c1e67SAndrew Jeffery 
19*cf3c1e67SAndrew Jeffery static const int OneSecondasNS = 1000000000;
20*cf3c1e67SAndrew Jeffery 
21*cf3c1e67SAndrew Jeffery #ifndef bool
22*cf3c1e67SAndrew Jeffery typedef int bool;
23*cf3c1e67SAndrew Jeffery #endif
24*cf3c1e67SAndrew Jeffery 
25*cf3c1e67SAndrew Jeffery #ifndef TRUE
26*cf3c1e67SAndrew Jeffery #define TRUE (1)
27*cf3c1e67SAndrew Jeffery #endif
28*cf3c1e67SAndrew Jeffery 
29*cf3c1e67SAndrew Jeffery #ifndef FALSE
30*cf3c1e67SAndrew Jeffery #define FALSE (0)
31*cf3c1e67SAndrew Jeffery #endif
32*cf3c1e67SAndrew Jeffery 
33*cf3c1e67SAndrew Jeffery typedef struct
34*cf3c1e67SAndrew Jeffery {
35*cf3c1e67SAndrew Jeffery     bool OnePoll;
36*cf3c1e67SAndrew Jeffery     struct timespec EndTime, Timeout;
37*cf3c1e67SAndrew Jeffery } SIGWRAP_TIMEOUT;
38*cf3c1e67SAndrew Jeffery 
sigwrap_InitTimeout(SIGWRAP_TIMEOUT * pDst,const struct timespec * timeout)39*cf3c1e67SAndrew Jeffery static void sigwrap_InitTimeout(SIGWRAP_TIMEOUT *pDst, const struct timespec *timeout)
40*cf3c1e67SAndrew Jeffery {
41*cf3c1e67SAndrew Jeffery     pDst->Timeout = *timeout;
42*cf3c1e67SAndrew Jeffery 
43*cf3c1e67SAndrew Jeffery     if ((timeout->tv_sec == 0) && (timeout->tv_nsec == 0))                  // If both value are zero than only a single poll is requested!
44*cf3c1e67SAndrew Jeffery     {
45*cf3c1e67SAndrew Jeffery         pDst->OnePoll = 1;
46*cf3c1e67SAndrew Jeffery         return;
47*cf3c1e67SAndrew Jeffery     }
48*cf3c1e67SAndrew Jeffery 
49*cf3c1e67SAndrew Jeffery     pDst->OnePoll = 0;
50*cf3c1e67SAndrew Jeffery 
51*cf3c1e67SAndrew Jeffery     struct timespec Now;
52*cf3c1e67SAndrew Jeffery 
53*cf3c1e67SAndrew Jeffery     (void)clock_gettime(CLOCK_MONOTONIC_RAW, &Now);                         // CLOCK_MONOTONIC_RAW is not affected by NTP etc.
54*cf3c1e67SAndrew Jeffery 
55*cf3c1e67SAndrew Jeffery     pDst->EndTime.tv_sec = Now.tv_sec + pDst->Timeout.tv_sec;               // Check necessary in 2038 due to signed integer variables
56*cf3c1e67SAndrew Jeffery     pDst->EndTime.tv_nsec = Now.tv_nsec + pDst->Timeout.tv_nsec;
57*cf3c1e67SAndrew Jeffery 
58*cf3c1e67SAndrew Jeffery     if (pDst->EndTime.tv_nsec >= OneSecondasNS)
59*cf3c1e67SAndrew Jeffery     {
60*cf3c1e67SAndrew Jeffery         pDst->EndTime.tv_sec += (pDst->EndTime.tv_nsec / OneSecondasNS);
61*cf3c1e67SAndrew Jeffery         pDst->EndTime.tv_nsec = (pDst->EndTime.tv_nsec % OneSecondasNS);
62*cf3c1e67SAndrew Jeffery     }
63*cf3c1e67SAndrew Jeffery }
64*cf3c1e67SAndrew Jeffery 
65*cf3c1e67SAndrew Jeffery 
sigwrap_CheckTimeout(SIGWRAP_TIMEOUT * pTo)66*cf3c1e67SAndrew Jeffery static bool sigwrap_CheckTimeout(SIGWRAP_TIMEOUT *pTo)
67*cf3c1e67SAndrew Jeffery {
68*cf3c1e67SAndrew Jeffery     if (pTo->OnePoll == TRUE) // Make sure, that in the case that a single poll is requested at least one call is not terminated with EINTR
69*cf3c1e67SAndrew Jeffery         return FALSE;
70*cf3c1e67SAndrew Jeffery 
71*cf3c1e67SAndrew Jeffery     struct timespec Now;
72*cf3c1e67SAndrew Jeffery 
73*cf3c1e67SAndrew Jeffery     (void)clock_gettime(CLOCK_MONOTONIC_RAW, &Now);
74*cf3c1e67SAndrew Jeffery 
75*cf3c1e67SAndrew Jeffery     if (Now.tv_sec > pTo->EndTime.tv_sec) // Can become a problem already in 2038 due to signed integer variables
76*cf3c1e67SAndrew Jeffery         return TRUE;
77*cf3c1e67SAndrew Jeffery 
78*cf3c1e67SAndrew Jeffery     pTo->Timeout.tv_nsec = pTo->EndTime.tv_nsec - Now.tv_nsec;
79*cf3c1e67SAndrew Jeffery     pTo->Timeout.tv_sec = pTo->EndTime.tv_sec - Now.tv_sec;
80*cf3c1e67SAndrew Jeffery 
81*cf3c1e67SAndrew Jeffery     if (pTo->Timeout.tv_sec == 0)
82*cf3c1e67SAndrew Jeffery     {
83*cf3c1e67SAndrew Jeffery         if (pTo->Timeout.tv_nsec <= 0)
84*cf3c1e67SAndrew Jeffery             return TRUE;
85*cf3c1e67SAndrew Jeffery     }
86*cf3c1e67SAndrew Jeffery     else if (pTo->Timeout.tv_nsec < 0)
87*cf3c1e67SAndrew Jeffery     {
88*cf3c1e67SAndrew Jeffery         pTo->Timeout.tv_nsec += OneSecondasNS;
89*cf3c1e67SAndrew Jeffery         pTo->Timeout.tv_sec--;
90*cf3c1e67SAndrew Jeffery     }
91*cf3c1e67SAndrew Jeffery 
92*cf3c1e67SAndrew Jeffery     return FALSE;
93*cf3c1e67SAndrew Jeffery }
94*cf3c1e67SAndrew Jeffery 
95*cf3c1e67SAndrew Jeffery 
96*cf3c1e67SAndrew Jeffery 
sigwrap_semop(int semid,struct sembuf * sops,size_t nsops)97*cf3c1e67SAndrew Jeffery int sigwrap_semop(int semid, struct sembuf *sops, size_t nsops)
98*cf3c1e67SAndrew Jeffery {
99*cf3c1e67SAndrew Jeffery     while (1)
100*cf3c1e67SAndrew Jeffery     {
101*cf3c1e67SAndrew Jeffery         if (semop(semid, sops, nsops) == 0)
102*cf3c1e67SAndrew Jeffery             return 0;
103*cf3c1e67SAndrew Jeffery 
104*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
105*cf3c1e67SAndrew Jeffery             return -1;
106*cf3c1e67SAndrew Jeffery     }
107*cf3c1e67SAndrew Jeffery }
108*cf3c1e67SAndrew Jeffery 
109*cf3c1e67SAndrew Jeffery #if 0
110*cf3c1e67SAndrew Jeffery int sigwrap_semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout)
111*cf3c1e67SAndrew Jeffery {
112*cf3c1e67SAndrew Jeffery     SIGWRAP_TIMEOUT To;
113*cf3c1e67SAndrew Jeffery 
114*cf3c1e67SAndrew Jeffery     if (timeout == NULL)
115*cf3c1e67SAndrew Jeffery         return (sigwrap_semop(semid, sops, nsops));
116*cf3c1e67SAndrew Jeffery 
117*cf3c1e67SAndrew Jeffery     sigwrap_InitTimeout(&To, timeout);
118*cf3c1e67SAndrew Jeffery 
119*cf3c1e67SAndrew Jeffery     while (1)
120*cf3c1e67SAndrew Jeffery     {
121*cf3c1e67SAndrew Jeffery         if (semtimedop(semid, sops, nsops, &To.Timeout) == 0)
122*cf3c1e67SAndrew Jeffery             return 0;
123*cf3c1e67SAndrew Jeffery 
124*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
125*cf3c1e67SAndrew Jeffery             return -1;
126*cf3c1e67SAndrew Jeffery 
127*cf3c1e67SAndrew Jeffery         if (sigwrap_CheckTimeout(&To))
128*cf3c1e67SAndrew Jeffery         {
129*cf3c1e67SAndrew Jeffery             errno = EAGAIN;
130*cf3c1e67SAndrew Jeffery             return -1;
131*cf3c1e67SAndrew Jeffery         }
132*cf3c1e67SAndrew Jeffery     }
133*cf3c1e67SAndrew Jeffery }
134*cf3c1e67SAndrew Jeffery #endif
135*cf3c1e67SAndrew Jeffery 
sigwrap_epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)136*cf3c1e67SAndrew Jeffery int sigwrap_epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
137*cf3c1e67SAndrew Jeffery {
138*cf3c1e67SAndrew Jeffery     SIGWRAP_TIMEOUT To;
139*cf3c1e67SAndrew Jeffery 
140*cf3c1e67SAndrew Jeffery     if (timeout != -1)
141*cf3c1e67SAndrew Jeffery     {
142*cf3c1e67SAndrew Jeffery         struct timespec Timeout;
143*cf3c1e67SAndrew Jeffery 
144*cf3c1e67SAndrew Jeffery         Timeout.tv_sec = timeout / 1000;
145*cf3c1e67SAndrew Jeffery         Timeout.tv_nsec = (timeout % 1000) * 1000000; // Convert msec to nsec
146*cf3c1e67SAndrew Jeffery 
147*cf3c1e67SAndrew Jeffery         sigwrap_InitTimeout(&To, &Timeout);
148*cf3c1e67SAndrew Jeffery     }
149*cf3c1e67SAndrew Jeffery 
150*cf3c1e67SAndrew Jeffery     while (1)
151*cf3c1e67SAndrew Jeffery     {
152*cf3c1e67SAndrew Jeffery         int Result = epoll_wait(epfd, events, maxevents, timeout);
153*cf3c1e67SAndrew Jeffery 
154*cf3c1e67SAndrew Jeffery         if (Result != -1)
155*cf3c1e67SAndrew Jeffery             return Result;
156*cf3c1e67SAndrew Jeffery 
157*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
158*cf3c1e67SAndrew Jeffery             return Result;
159*cf3c1e67SAndrew Jeffery 
160*cf3c1e67SAndrew Jeffery         if (timeout == -1)
161*cf3c1e67SAndrew Jeffery             continue;
162*cf3c1e67SAndrew Jeffery 
163*cf3c1e67SAndrew Jeffery         if (sigwrap_CheckTimeout(&To))
164*cf3c1e67SAndrew Jeffery             return 0;
165*cf3c1e67SAndrew Jeffery 
166*cf3c1e67SAndrew Jeffery         timeout = To.Timeout.tv_sec * 1000 + To.Timeout.tv_nsec / 1000000;
167*cf3c1e67SAndrew Jeffery     }
168*cf3c1e67SAndrew Jeffery }
169*cf3c1e67SAndrew Jeffery 
170*cf3c1e67SAndrew Jeffery 
sigwrap_epoll_pwait(int epfd,struct epoll_event * events,int maxevents,int timeout,const sigset_t * sigmask)171*cf3c1e67SAndrew Jeffery int sigwrap_epoll_pwait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *sigmask)
172*cf3c1e67SAndrew Jeffery {
173*cf3c1e67SAndrew Jeffery     SIGWRAP_TIMEOUT To;
174*cf3c1e67SAndrew Jeffery 
175*cf3c1e67SAndrew Jeffery     if (timeout != -1)
176*cf3c1e67SAndrew Jeffery     {
177*cf3c1e67SAndrew Jeffery         struct timespec Timeout;
178*cf3c1e67SAndrew Jeffery 
179*cf3c1e67SAndrew Jeffery         Timeout.tv_sec = timeout / 1000;
180*cf3c1e67SAndrew Jeffery         Timeout.tv_nsec = (timeout % 1000) * 1000000; // Convert msec to nsec
181*cf3c1e67SAndrew Jeffery 
182*cf3c1e67SAndrew Jeffery         sigwrap_InitTimeout(&To, &Timeout);
183*cf3c1e67SAndrew Jeffery     }
184*cf3c1e67SAndrew Jeffery 
185*cf3c1e67SAndrew Jeffery     while (1)
186*cf3c1e67SAndrew Jeffery     {
187*cf3c1e67SAndrew Jeffery         int Result = epoll_pwait(epfd, events, maxevents, timeout, sigmask);
188*cf3c1e67SAndrew Jeffery 
189*cf3c1e67SAndrew Jeffery         if (Result != -1)
190*cf3c1e67SAndrew Jeffery             return Result;
191*cf3c1e67SAndrew Jeffery 
192*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
193*cf3c1e67SAndrew Jeffery             return Result;
194*cf3c1e67SAndrew Jeffery 
195*cf3c1e67SAndrew Jeffery         if (timeout == -1)
196*cf3c1e67SAndrew Jeffery             continue;
197*cf3c1e67SAndrew Jeffery 
198*cf3c1e67SAndrew Jeffery         if (sigwrap_CheckTimeout(&To))
199*cf3c1e67SAndrew Jeffery             return 0;
200*cf3c1e67SAndrew Jeffery 
201*cf3c1e67SAndrew Jeffery         timeout = To.Timeout.tv_sec * 1000 + To.Timeout.tv_nsec / 1000000;
202*cf3c1e67SAndrew Jeffery     }
203*cf3c1e67SAndrew Jeffery }
204*cf3c1e67SAndrew Jeffery 
205*cf3c1e67SAndrew Jeffery 
sigwrap_sigwaitinfo(const sigset_t * set,siginfo_t * info)206*cf3c1e67SAndrew Jeffery int sigwrap_sigwaitinfo(const sigset_t *set, siginfo_t *info)
207*cf3c1e67SAndrew Jeffery {
208*cf3c1e67SAndrew Jeffery     while (1)
209*cf3c1e67SAndrew Jeffery     {
210*cf3c1e67SAndrew Jeffery         int Result = sigwaitinfo(set, info);
211*cf3c1e67SAndrew Jeffery 
212*cf3c1e67SAndrew Jeffery         if (Result != -1)
213*cf3c1e67SAndrew Jeffery             return Result;
214*cf3c1e67SAndrew Jeffery 
215*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
216*cf3c1e67SAndrew Jeffery             return Result;
217*cf3c1e67SAndrew Jeffery     }
218*cf3c1e67SAndrew Jeffery }
219*cf3c1e67SAndrew Jeffery 
220*cf3c1e67SAndrew Jeffery 
sigwrap_sigtimedwait(const sigset_t * set,siginfo_t * info,const struct timespec * timeout)221*cf3c1e67SAndrew Jeffery int sigwrap_sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
222*cf3c1e67SAndrew Jeffery {
223*cf3c1e67SAndrew Jeffery     SIGWRAP_TIMEOUT To;
224*cf3c1e67SAndrew Jeffery 
225*cf3c1e67SAndrew Jeffery     sigwrap_InitTimeout(&To, timeout);
226*cf3c1e67SAndrew Jeffery 
227*cf3c1e67SAndrew Jeffery     while (1)
228*cf3c1e67SAndrew Jeffery     {
229*cf3c1e67SAndrew Jeffery         int Result = sigtimedwait(set, info, &To.Timeout);
230*cf3c1e67SAndrew Jeffery 
231*cf3c1e67SAndrew Jeffery         if (Result != -1)
232*cf3c1e67SAndrew Jeffery             return Result;
233*cf3c1e67SAndrew Jeffery 
234*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
235*cf3c1e67SAndrew Jeffery             return Result;
236*cf3c1e67SAndrew Jeffery 
237*cf3c1e67SAndrew Jeffery         if (sigwrap_CheckTimeout(&To))
238*cf3c1e67SAndrew Jeffery             return 0;
239*cf3c1e67SAndrew Jeffery     }
240*cf3c1e67SAndrew Jeffery }
241*cf3c1e67SAndrew Jeffery 
242*cf3c1e67SAndrew Jeffery 
sigwrap_nanosleep(const struct timespec * req,struct timespec * rem)243*cf3c1e67SAndrew Jeffery int sigwrap_nanosleep(const struct timespec *req, struct timespec *rem)
244*cf3c1e67SAndrew Jeffery {
245*cf3c1e67SAndrew Jeffery     struct timespec Wait, Remain;
246*cf3c1e67SAndrew Jeffery 
247*cf3c1e67SAndrew Jeffery     if (!rem)
248*cf3c1e67SAndrew Jeffery         rem = &Remain;
249*cf3c1e67SAndrew Jeffery 
250*cf3c1e67SAndrew Jeffery     Wait = *req;
251*cf3c1e67SAndrew Jeffery 
252*cf3c1e67SAndrew Jeffery     while (1)
253*cf3c1e67SAndrew Jeffery     {
254*cf3c1e67SAndrew Jeffery         if (nanosleep(&Wait, rem) == 0)
255*cf3c1e67SAndrew Jeffery             return 0;
256*cf3c1e67SAndrew Jeffery 
257*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
258*cf3c1e67SAndrew Jeffery             return -1;
259*cf3c1e67SAndrew Jeffery 
260*cf3c1e67SAndrew Jeffery         Wait = *rem;
261*cf3c1e67SAndrew Jeffery     }
262*cf3c1e67SAndrew Jeffery }
263*cf3c1e67SAndrew Jeffery 
264*cf3c1e67SAndrew Jeffery 
sigwrap_clock_nanosleep(clockid_t clock_id,int flags,const struct timespec * request,struct timespec * remain)265*cf3c1e67SAndrew Jeffery int sigwrap_clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *request, struct timespec *remain)
266*cf3c1e67SAndrew Jeffery {
267*cf3c1e67SAndrew Jeffery     struct timespec Wait, Remain;
268*cf3c1e67SAndrew Jeffery 
269*cf3c1e67SAndrew Jeffery     if (!remain)
270*cf3c1e67SAndrew Jeffery         remain = &Remain;
271*cf3c1e67SAndrew Jeffery 
272*cf3c1e67SAndrew Jeffery     Wait = *request;
273*cf3c1e67SAndrew Jeffery 
274*cf3c1e67SAndrew Jeffery     while (1)
275*cf3c1e67SAndrew Jeffery     {
276*cf3c1e67SAndrew Jeffery         int Result = clock_nanosleep(clock_id, flags, &Wait, remain);
277*cf3c1e67SAndrew Jeffery 
278*cf3c1e67SAndrew Jeffery         if (Result == 0)
279*cf3c1e67SAndrew Jeffery             return Result;
280*cf3c1e67SAndrew Jeffery 
281*cf3c1e67SAndrew Jeffery         if (Result != EINTR)
282*cf3c1e67SAndrew Jeffery             return Result;
283*cf3c1e67SAndrew Jeffery 
284*cf3c1e67SAndrew Jeffery         if (flags != TIMER_ABSTIME)
285*cf3c1e67SAndrew Jeffery             Wait = *remain;
286*cf3c1e67SAndrew Jeffery     }
287*cf3c1e67SAndrew Jeffery }
288*cf3c1e67SAndrew Jeffery 
289*cf3c1e67SAndrew Jeffery 
sigwrap_usleep(useconds_t usec)290*cf3c1e67SAndrew Jeffery int sigwrap_usleep(useconds_t usec)
291*cf3c1e67SAndrew Jeffery {
292*cf3c1e67SAndrew Jeffery     SIGWRAP_TIMEOUT To;
293*cf3c1e67SAndrew Jeffery 
294*cf3c1e67SAndrew Jeffery     struct timespec Timeout;
295*cf3c1e67SAndrew Jeffery 
296*cf3c1e67SAndrew Jeffery     Timeout.tv_sec = usec / 1000000;
297*cf3c1e67SAndrew Jeffery     Timeout.tv_nsec = (usec % 1000000) * 1000;
298*cf3c1e67SAndrew Jeffery 
299*cf3c1e67SAndrew Jeffery     sigwrap_InitTimeout(&To, &Timeout);
300*cf3c1e67SAndrew Jeffery 
301*cf3c1e67SAndrew Jeffery     while (1)
302*cf3c1e67SAndrew Jeffery     {
303*cf3c1e67SAndrew Jeffery         if (usleep(usec) == 0)
304*cf3c1e67SAndrew Jeffery             return 0;
305*cf3c1e67SAndrew Jeffery 
306*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
307*cf3c1e67SAndrew Jeffery             return -1;
308*cf3c1e67SAndrew Jeffery 
309*cf3c1e67SAndrew Jeffery         if (sigwrap_CheckTimeout(&To))
310*cf3c1e67SAndrew Jeffery             return 0;
311*cf3c1e67SAndrew Jeffery 
312*cf3c1e67SAndrew Jeffery         usec = To.Timeout.tv_sec * 1000000 + To.Timeout.tv_nsec / 1000;
313*cf3c1e67SAndrew Jeffery     }
314*cf3c1e67SAndrew Jeffery }
315*cf3c1e67SAndrew Jeffery 
316*cf3c1e67SAndrew Jeffery 
sigwrap_poll(struct pollfd * fds,nfds_t nfds,int timeout)317*cf3c1e67SAndrew Jeffery int sigwrap_poll(struct pollfd *fds, nfds_t nfds, int timeout)
318*cf3c1e67SAndrew Jeffery {
319*cf3c1e67SAndrew Jeffery     SIGWRAP_TIMEOUT To;
320*cf3c1e67SAndrew Jeffery 
321*cf3c1e67SAndrew Jeffery     if (timeout > 0)
322*cf3c1e67SAndrew Jeffery     {
323*cf3c1e67SAndrew Jeffery         struct timespec Timeout;
324*cf3c1e67SAndrew Jeffery 
325*cf3c1e67SAndrew Jeffery         Timeout.tv_sec = timeout / 1000;
326*cf3c1e67SAndrew Jeffery         Timeout.tv_nsec = (timeout % 1000) * 1000000;
327*cf3c1e67SAndrew Jeffery 
328*cf3c1e67SAndrew Jeffery         sigwrap_InitTimeout(&To, &Timeout);
329*cf3c1e67SAndrew Jeffery     }
330*cf3c1e67SAndrew Jeffery 
331*cf3c1e67SAndrew Jeffery     while (1)
332*cf3c1e67SAndrew Jeffery     {
333*cf3c1e67SAndrew Jeffery         int Result = poll(fds, nfds, timeout);
334*cf3c1e67SAndrew Jeffery 
335*cf3c1e67SAndrew Jeffery         if (Result != -1)
336*cf3c1e67SAndrew Jeffery             return Result;
337*cf3c1e67SAndrew Jeffery 
338*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
339*cf3c1e67SAndrew Jeffery             return Result;
340*cf3c1e67SAndrew Jeffery 
341*cf3c1e67SAndrew Jeffery         if (timeout < 0) // Specifying a negative value in timeout means an infinite/no timeout.
342*cf3c1e67SAndrew Jeffery             continue;
343*cf3c1e67SAndrew Jeffery         else if (timeout == 0)
344*cf3c1e67SAndrew Jeffery             continue; // We want to make sure that at least one check was not aborted with EINTR
345*cf3c1e67SAndrew Jeffery 
346*cf3c1e67SAndrew Jeffery         if (sigwrap_CheckTimeout(&To))
347*cf3c1e67SAndrew Jeffery             return 0;
348*cf3c1e67SAndrew Jeffery 
349*cf3c1e67SAndrew Jeffery         timeout = To.Timeout.tv_sec * 1000 + To.Timeout.tv_nsec / 1000000;
350*cf3c1e67SAndrew Jeffery     }
351*cf3c1e67SAndrew Jeffery }
352*cf3c1e67SAndrew Jeffery 
353*cf3c1e67SAndrew Jeffery #if 0
354*cf3c1e67SAndrew Jeffery int sigwrap_ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask)
355*cf3c1e67SAndrew Jeffery {
356*cf3c1e67SAndrew Jeffery     SIGWRAP_TIMEOUT To;
357*cf3c1e67SAndrew Jeffery 
358*cf3c1e67SAndrew Jeffery     if (tmo_p != NULL)
359*cf3c1e67SAndrew Jeffery     {
360*cf3c1e67SAndrew Jeffery         sigwrap_InitTimeout(&To, tmo_p);
361*cf3c1e67SAndrew Jeffery         tmo_p = &To.Timeout;
362*cf3c1e67SAndrew Jeffery     }
363*cf3c1e67SAndrew Jeffery 
364*cf3c1e67SAndrew Jeffery     while (1)
365*cf3c1e67SAndrew Jeffery     {
366*cf3c1e67SAndrew Jeffery         int Result = ppoll(fds, nfds, tmo_p, sigmask);
367*cf3c1e67SAndrew Jeffery 
368*cf3c1e67SAndrew Jeffery         if (Result != -1)
369*cf3c1e67SAndrew Jeffery             return Result;
370*cf3c1e67SAndrew Jeffery 
371*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
372*cf3c1e67SAndrew Jeffery             return Result;
373*cf3c1e67SAndrew Jeffery 
374*cf3c1e67SAndrew Jeffery         if (tmo_p == NULL)
375*cf3c1e67SAndrew Jeffery             continue;
376*cf3c1e67SAndrew Jeffery 
377*cf3c1e67SAndrew Jeffery         if (sigwrap_CheckTimeout(&To))
378*cf3c1e67SAndrew Jeffery             return 0;
379*cf3c1e67SAndrew Jeffery     }
380*cf3c1e67SAndrew Jeffery }
381*cf3c1e67SAndrew Jeffery #endif
382*cf3c1e67SAndrew Jeffery 
sigwrap_select(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout)383*cf3c1e67SAndrew Jeffery int sigwrap_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
384*cf3c1e67SAndrew Jeffery {
385*cf3c1e67SAndrew Jeffery     while (1)
386*cf3c1e67SAndrew Jeffery     {
387*cf3c1e67SAndrew Jeffery         int Result = select(nfds, readfds, writefds, exceptfds, timeout);
388*cf3c1e67SAndrew Jeffery 
389*cf3c1e67SAndrew Jeffery         if (Result != -1)
390*cf3c1e67SAndrew Jeffery             return Result;
391*cf3c1e67SAndrew Jeffery 
392*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
393*cf3c1e67SAndrew Jeffery             return Result;
394*cf3c1e67SAndrew Jeffery     }
395*cf3c1e67SAndrew Jeffery }
396*cf3c1e67SAndrew Jeffery 
397*cf3c1e67SAndrew Jeffery 
sigwrap_pselect(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,const struct timespec * timeout,const sigset_t * sigmask)398*cf3c1e67SAndrew Jeffery int sigwrap_pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout,
399*cf3c1e67SAndrew Jeffery                     const sigset_t *sigmask)
400*cf3c1e67SAndrew Jeffery {
401*cf3c1e67SAndrew Jeffery     SIGWRAP_TIMEOUT To;
402*cf3c1e67SAndrew Jeffery 
403*cf3c1e67SAndrew Jeffery     if (timeout != NULL)
404*cf3c1e67SAndrew Jeffery     {
405*cf3c1e67SAndrew Jeffery         sigwrap_InitTimeout(&To, timeout);
406*cf3c1e67SAndrew Jeffery         timeout = &To.Timeout;
407*cf3c1e67SAndrew Jeffery     }
408*cf3c1e67SAndrew Jeffery 
409*cf3c1e67SAndrew Jeffery     while (1)
410*cf3c1e67SAndrew Jeffery     {
411*cf3c1e67SAndrew Jeffery         int Result = pselect(nfds, readfds, writefds, exceptfds, timeout, sigmask);
412*cf3c1e67SAndrew Jeffery 
413*cf3c1e67SAndrew Jeffery         if (Result != -1)
414*cf3c1e67SAndrew Jeffery             return Result;
415*cf3c1e67SAndrew Jeffery 
416*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
417*cf3c1e67SAndrew Jeffery             return Result;
418*cf3c1e67SAndrew Jeffery 
419*cf3c1e67SAndrew Jeffery         if (timeout == NULL)
420*cf3c1e67SAndrew Jeffery             continue;
421*cf3c1e67SAndrew Jeffery 
422*cf3c1e67SAndrew Jeffery         if (sigwrap_CheckTimeout(&To))
423*cf3c1e67SAndrew Jeffery             return 0;
424*cf3c1e67SAndrew Jeffery     }
425*cf3c1e67SAndrew Jeffery }
426*cf3c1e67SAndrew Jeffery 
427*cf3c1e67SAndrew Jeffery 
sigwrap_msgsnd(int msqid,const void * msgp,size_t msgsz,int msgflg)428*cf3c1e67SAndrew Jeffery int sigwrap_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
429*cf3c1e67SAndrew Jeffery {
430*cf3c1e67SAndrew Jeffery     while (1)
431*cf3c1e67SAndrew Jeffery     {
432*cf3c1e67SAndrew Jeffery         int Result = msgsnd(msqid, msgp, msgsz, msgflg);
433*cf3c1e67SAndrew Jeffery 
434*cf3c1e67SAndrew Jeffery         if (Result != -1)
435*cf3c1e67SAndrew Jeffery             return Result;
436*cf3c1e67SAndrew Jeffery 
437*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
438*cf3c1e67SAndrew Jeffery             return Result;
439*cf3c1e67SAndrew Jeffery     }
440*cf3c1e67SAndrew Jeffery }
441*cf3c1e67SAndrew Jeffery 
442*cf3c1e67SAndrew Jeffery 
sigwrap_msgrcv(int msqid,void * msgp,size_t msgsz,long msgtyp,int msgflg)443*cf3c1e67SAndrew Jeffery ssize_t sigwrap_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
444*cf3c1e67SAndrew Jeffery {
445*cf3c1e67SAndrew Jeffery     while (1)
446*cf3c1e67SAndrew Jeffery     {
447*cf3c1e67SAndrew Jeffery         ssize_t Result = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
448*cf3c1e67SAndrew Jeffery 
449*cf3c1e67SAndrew Jeffery         if (Result != -1)
450*cf3c1e67SAndrew Jeffery             return Result;
451*cf3c1e67SAndrew Jeffery 
452*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
453*cf3c1e67SAndrew Jeffery             return Result;
454*cf3c1e67SAndrew Jeffery     }
455*cf3c1e67SAndrew Jeffery }
456*cf3c1e67SAndrew Jeffery 
457*cf3c1e67SAndrew Jeffery 
sigwrap_connect(int sockfd,const struct sockaddr * addr,socklen_t addrlen)458*cf3c1e67SAndrew Jeffery int sigwrap_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
459*cf3c1e67SAndrew Jeffery {
460*cf3c1e67SAndrew Jeffery     while (1)
461*cf3c1e67SAndrew Jeffery     {
462*cf3c1e67SAndrew Jeffery         int Result = connect(sockfd, addr, addrlen);
463*cf3c1e67SAndrew Jeffery 
464*cf3c1e67SAndrew Jeffery         if (Result != -1)
465*cf3c1e67SAndrew Jeffery             return Result;
466*cf3c1e67SAndrew Jeffery 
467*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
468*cf3c1e67SAndrew Jeffery             return Result;
469*cf3c1e67SAndrew Jeffery     }
470*cf3c1e67SAndrew Jeffery }
471*cf3c1e67SAndrew Jeffery 
472*cf3c1e67SAndrew Jeffery 
sigwrap_send(int sockfd,const void * buf,size_t len,int flags)473*cf3c1e67SAndrew Jeffery ssize_t sigwrap_send(int sockfd, const void *buf, size_t len, int flags)
474*cf3c1e67SAndrew Jeffery {
475*cf3c1e67SAndrew Jeffery     while (1)
476*cf3c1e67SAndrew Jeffery     {
477*cf3c1e67SAndrew Jeffery         ssize_t Result = send(sockfd, buf, len, flags);
478*cf3c1e67SAndrew Jeffery 
479*cf3c1e67SAndrew Jeffery         if (Result != -1)
480*cf3c1e67SAndrew Jeffery             return Result;
481*cf3c1e67SAndrew Jeffery 
482*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
483*cf3c1e67SAndrew Jeffery             return Result;
484*cf3c1e67SAndrew Jeffery     }
485*cf3c1e67SAndrew Jeffery }
486*cf3c1e67SAndrew Jeffery 
487*cf3c1e67SAndrew Jeffery 
sigwrap_sendto(int sockfd,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)488*cf3c1e67SAndrew Jeffery ssize_t sigwrap_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr,
489*cf3c1e67SAndrew Jeffery                        socklen_t addrlen)
490*cf3c1e67SAndrew Jeffery {
491*cf3c1e67SAndrew Jeffery     while (1)
492*cf3c1e67SAndrew Jeffery     {
493*cf3c1e67SAndrew Jeffery         ssize_t Result = sendto(sockfd, buf, len, flags, dest_addr, addrlen);
494*cf3c1e67SAndrew Jeffery 
495*cf3c1e67SAndrew Jeffery         if (Result != -1)
496*cf3c1e67SAndrew Jeffery             return Result;
497*cf3c1e67SAndrew Jeffery 
498*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
499*cf3c1e67SAndrew Jeffery             return Result;
500*cf3c1e67SAndrew Jeffery     }
501*cf3c1e67SAndrew Jeffery }
502*cf3c1e67SAndrew Jeffery 
503*cf3c1e67SAndrew Jeffery 
sigwrap_sendsendmsg(int sockfd,const struct msghdr * msg,int flags)504*cf3c1e67SAndrew Jeffery ssize_t sigwrap_sendsendmsg(int sockfd, const struct msghdr *msg, int flags)
505*cf3c1e67SAndrew Jeffery {
506*cf3c1e67SAndrew Jeffery     while (1)
507*cf3c1e67SAndrew Jeffery     {
508*cf3c1e67SAndrew Jeffery         ssize_t Result = sendmsg(sockfd, msg, flags);
509*cf3c1e67SAndrew Jeffery 
510*cf3c1e67SAndrew Jeffery         if (Result != -1)
511*cf3c1e67SAndrew Jeffery             return Result;
512*cf3c1e67SAndrew Jeffery 
513*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
514*cf3c1e67SAndrew Jeffery             return Result;
515*cf3c1e67SAndrew Jeffery     }
516*cf3c1e67SAndrew Jeffery }
517*cf3c1e67SAndrew Jeffery 
518*cf3c1e67SAndrew Jeffery 
sigwrap_accept(int sockfd,struct sockaddr * addr,socklen_t * addrlen)519*cf3c1e67SAndrew Jeffery int sigwrap_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
520*cf3c1e67SAndrew Jeffery {
521*cf3c1e67SAndrew Jeffery     while (1)
522*cf3c1e67SAndrew Jeffery     {
523*cf3c1e67SAndrew Jeffery         int Result = accept(sockfd, addr, addrlen);
524*cf3c1e67SAndrew Jeffery 
525*cf3c1e67SAndrew Jeffery         if (Result != -1)
526*cf3c1e67SAndrew Jeffery             return Result;
527*cf3c1e67SAndrew Jeffery 
528*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
529*cf3c1e67SAndrew Jeffery             return Result;
530*cf3c1e67SAndrew Jeffery     }
531*cf3c1e67SAndrew Jeffery }
532*cf3c1e67SAndrew Jeffery 
533*cf3c1e67SAndrew Jeffery #if 0
534*cf3c1e67SAndrew Jeffery int sigwrap_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
535*cf3c1e67SAndrew Jeffery {
536*cf3c1e67SAndrew Jeffery     while (1)
537*cf3c1e67SAndrew Jeffery     {
538*cf3c1e67SAndrew Jeffery         int Result = accept4(sockfd, addr, addrlen, flags);
539*cf3c1e67SAndrew Jeffery 
540*cf3c1e67SAndrew Jeffery         if (Result != -1)
541*cf3c1e67SAndrew Jeffery             return Result;
542*cf3c1e67SAndrew Jeffery 
543*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
544*cf3c1e67SAndrew Jeffery             return Result;
545*cf3c1e67SAndrew Jeffery     }
546*cf3c1e67SAndrew Jeffery }
547*cf3c1e67SAndrew Jeffery #endif
548*cf3c1e67SAndrew Jeffery 
549*cf3c1e67SAndrew Jeffery // EINTR wrapper for the standard read() function. Can be used for sockets that are the to non-blocking mode.
550*cf3c1e67SAndrew Jeffery // The length of the returned data can be shorter than the requested one!
551*cf3c1e67SAndrew Jeffery 
sigwrap_read(int fd,void * buf,size_t count)552*cf3c1e67SAndrew Jeffery ssize_t sigwrap_read(int fd, void *buf, size_t count)
553*cf3c1e67SAndrew Jeffery {
554*cf3c1e67SAndrew Jeffery     while (1)
555*cf3c1e67SAndrew Jeffery     {
556*cf3c1e67SAndrew Jeffery         ssize_t Result = read(fd, buf, count);
557*cf3c1e67SAndrew Jeffery 
558*cf3c1e67SAndrew Jeffery         if (Result != -1)
559*cf3c1e67SAndrew Jeffery             return (Result);
560*cf3c1e67SAndrew Jeffery 
561*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
562*cf3c1e67SAndrew Jeffery             return (Result);
563*cf3c1e67SAndrew Jeffery     }
564*cf3c1e67SAndrew Jeffery }
565*cf3c1e67SAndrew Jeffery 
566*cf3c1e67SAndrew Jeffery 
567*cf3c1e67SAndrew Jeffery // EINTR wrapper for the standard read() function. Waits until ALL requested data is available. Use the non-blocking version (sigwrap_read)
568*cf3c1e67SAndrew Jeffery // for sockets that are set to non-blocking mode or when partial data is okay
569*cf3c1e67SAndrew Jeffery // Although the description for the read() function describes it differently, it seems possible that the original function may already return
570*cf3c1e67SAndrew Jeffery // even though partial data has already been read. This implementation makes sure that all requested data have been read.
571*cf3c1e67SAndrew Jeffery // See the comment in the signal description https://linux.die.net/man/7/signal
572*cf3c1e67SAndrew Jeffery //* read(2), readv(2), write(2), writev(2), and ioctl(2) calls on "slow" devices.
573*cf3c1e67SAndrew Jeffery //* A "slow" device is one where the I/O call may block for an indefinite time, for example, a terminal, pipe, or socket.
574*cf3c1e67SAndrew Jeffery //* (A disk is not a slow device according to this definition.) If an I/O call on a slow device has already transferred
575*cf3c1e67SAndrew Jeffery //* some data by the time it is interrupted by a signal handler, then the call will return a success status (normally, the number of bytes transferred).
576*cf3c1e67SAndrew Jeffery 
sigwrap_blocking_read(int hFile,void * pData,size_t RdLen)577*cf3c1e67SAndrew Jeffery ssize_t sigwrap_blocking_read(int hFile, void *pData, size_t RdLen)
578*cf3c1e67SAndrew Jeffery {
579*cf3c1e67SAndrew Jeffery     ssize_t Transfered;
580*cf3c1e67SAndrew Jeffery     ssize_t Len = RdLen;
581*cf3c1e67SAndrew Jeffery 
582*cf3c1e67SAndrew Jeffery     while ((Transfered = read(hFile, pData, Len)) != Len)
583*cf3c1e67SAndrew Jeffery     {
584*cf3c1e67SAndrew Jeffery         if (Transfered == 0) // EOF reached?
585*cf3c1e67SAndrew Jeffery             return 0;
586*cf3c1e67SAndrew Jeffery 
587*cf3c1e67SAndrew Jeffery         if (Transfered != -1)
588*cf3c1e67SAndrew Jeffery         {
589*cf3c1e67SAndrew Jeffery             pData += Transfered;
590*cf3c1e67SAndrew Jeffery             Len -= Transfered;
591*cf3c1e67SAndrew Jeffery             continue;
592*cf3c1e67SAndrew Jeffery         }
593*cf3c1e67SAndrew Jeffery 
594*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
595*cf3c1e67SAndrew Jeffery             return -1;
596*cf3c1e67SAndrew Jeffery     }
597*cf3c1e67SAndrew Jeffery 
598*cf3c1e67SAndrew Jeffery     return RdLen;
599*cf3c1e67SAndrew Jeffery }
600*cf3c1e67SAndrew Jeffery 
601*cf3c1e67SAndrew Jeffery 
sigwrap_readv(int fd,const struct iovec * iov,int iovcnt)602*cf3c1e67SAndrew Jeffery ssize_t sigwrap_readv(int fd, const struct iovec *iov, int iovcnt)
603*cf3c1e67SAndrew Jeffery {
604*cf3c1e67SAndrew Jeffery     while (1)
605*cf3c1e67SAndrew Jeffery     {
606*cf3c1e67SAndrew Jeffery         ssize_t Result = readv(fd, iov, iovcnt);
607*cf3c1e67SAndrew Jeffery 
608*cf3c1e67SAndrew Jeffery         if (Result != -1)
609*cf3c1e67SAndrew Jeffery             return (Result);
610*cf3c1e67SAndrew Jeffery 
611*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
612*cf3c1e67SAndrew Jeffery             return (Result);
613*cf3c1e67SAndrew Jeffery     }
614*cf3c1e67SAndrew Jeffery }
615*cf3c1e67SAndrew Jeffery 
616*cf3c1e67SAndrew Jeffery 
sigwrap_recv(int sockfd,void * buf,size_t len,int flags)617*cf3c1e67SAndrew Jeffery ssize_t sigwrap_recv(int sockfd, void *buf, size_t len, int flags)
618*cf3c1e67SAndrew Jeffery {
619*cf3c1e67SAndrew Jeffery     while (1)
620*cf3c1e67SAndrew Jeffery     {
621*cf3c1e67SAndrew Jeffery         ssize_t Result = recv(sockfd, buf, len, flags);
622*cf3c1e67SAndrew Jeffery 
623*cf3c1e67SAndrew Jeffery         if (Result != -1)
624*cf3c1e67SAndrew Jeffery             return (Result);
625*cf3c1e67SAndrew Jeffery 
626*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
627*cf3c1e67SAndrew Jeffery             return (Result);
628*cf3c1e67SAndrew Jeffery     }
629*cf3c1e67SAndrew Jeffery }
630*cf3c1e67SAndrew Jeffery 
631*cf3c1e67SAndrew Jeffery 
sigwrap_recvfrom(int sockfd,void * buf,size_t len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)632*cf3c1e67SAndrew Jeffery ssize_t sigwrap_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
633*cf3c1e67SAndrew Jeffery {
634*cf3c1e67SAndrew Jeffery     while (1)
635*cf3c1e67SAndrew Jeffery     {
636*cf3c1e67SAndrew Jeffery         ssize_t Result = recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
637*cf3c1e67SAndrew Jeffery 
638*cf3c1e67SAndrew Jeffery         if (Result != -1)
639*cf3c1e67SAndrew Jeffery             return (Result);
640*cf3c1e67SAndrew Jeffery 
641*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
642*cf3c1e67SAndrew Jeffery             return (Result);
643*cf3c1e67SAndrew Jeffery     }
644*cf3c1e67SAndrew Jeffery }
645*cf3c1e67SAndrew Jeffery 
646*cf3c1e67SAndrew Jeffery 
sigwrap_recvmsg(int sockfd,struct msghdr * msg,int flags)647*cf3c1e67SAndrew Jeffery ssize_t sigwrap_recvmsg(int sockfd, struct msghdr *msg, int flags)
648*cf3c1e67SAndrew Jeffery {
649*cf3c1e67SAndrew Jeffery     while (1)
650*cf3c1e67SAndrew Jeffery     {
651*cf3c1e67SAndrew Jeffery         ssize_t Result = recvmsg(sockfd, msg, flags);
652*cf3c1e67SAndrew Jeffery 
653*cf3c1e67SAndrew Jeffery         if (Result != -1)
654*cf3c1e67SAndrew Jeffery             return (Result);
655*cf3c1e67SAndrew Jeffery 
656*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
657*cf3c1e67SAndrew Jeffery             return (Result);
658*cf3c1e67SAndrew Jeffery     }
659*cf3c1e67SAndrew Jeffery }
660*cf3c1e67SAndrew Jeffery 
661*cf3c1e67SAndrew Jeffery 
662*cf3c1e67SAndrew Jeffery // EINTR wrapper for the standard write() function. Can be used for sockets that are the to non-blocking mode.
663*cf3c1e67SAndrew Jeffery // The length of the effectively written data can be shorter than the length specified at the function call!
664*cf3c1e67SAndrew Jeffery 
sigwrap_write(int fd,const void * buf,size_t count)665*cf3c1e67SAndrew Jeffery ssize_t sigwrap_write(int fd, const void *buf, size_t count)
666*cf3c1e67SAndrew Jeffery {
667*cf3c1e67SAndrew Jeffery     while (1)
668*cf3c1e67SAndrew Jeffery     {
669*cf3c1e67SAndrew Jeffery         ssize_t Result = write(fd, buf, count);
670*cf3c1e67SAndrew Jeffery 
671*cf3c1e67SAndrew Jeffery         if (Result != -1)
672*cf3c1e67SAndrew Jeffery             return (Result);
673*cf3c1e67SAndrew Jeffery 
674*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
675*cf3c1e67SAndrew Jeffery             return (Result);
676*cf3c1e67SAndrew Jeffery     }
677*cf3c1e67SAndrew Jeffery }
678*cf3c1e67SAndrew Jeffery 
679*cf3c1e67SAndrew Jeffery // EINTR wrapper for the standard write() function. Waits until ALL data is written! Use the non-blocking version (sigwrap_write)
680*cf3c1e67SAndrew Jeffery // for sockets that are set to non-blocking mode, or when it is OK to write only partial data.
681*cf3c1e67SAndrew Jeffery // Although the description for the write() function describes it differently, it seems possible that the original function may already return
682*cf3c1e67SAndrew Jeffery // even though partial data has already been written. This implementation makes sure that all requested data have been written.
683*cf3c1e67SAndrew Jeffery // See the comment in the signal description https://linux.die.net/man/7/signal
684*cf3c1e67SAndrew Jeffery //* read(2), readv(2), write(2), writev(2), and ioctl(2) calls on "slow" devices.
685*cf3c1e67SAndrew Jeffery //* A "slow" device is one where the I/O call may block for an indefinite time, for example, a terminal, pipe, or socket.
686*cf3c1e67SAndrew Jeffery //* (A disk is not a slow device according to this definition.) If an I/O call on a slow device has already transferred
687*cf3c1e67SAndrew Jeffery //* some data by the time it is interrupted by a signal handler, then the call will return a success status (normally, the number of bytes transferred).
688*cf3c1e67SAndrew Jeffery 
sigwrap_blocking_write(int hFile,const void * pData,ssize_t WrtLen)689*cf3c1e67SAndrew Jeffery ssize_t sigwrap_blocking_write(int hFile, const void *pData, ssize_t WrtLen)
690*cf3c1e67SAndrew Jeffery {
691*cf3c1e67SAndrew Jeffery     ssize_t Written;
692*cf3c1e67SAndrew Jeffery     ssize_t Len = WrtLen;
693*cf3c1e67SAndrew Jeffery 
694*cf3c1e67SAndrew Jeffery     while ((Written = write(hFile, pData, Len)) != Len)
695*cf3c1e67SAndrew Jeffery     {
696*cf3c1e67SAndrew Jeffery         if (Written != -1)
697*cf3c1e67SAndrew Jeffery         {
698*cf3c1e67SAndrew Jeffery             pData += Written;
699*cf3c1e67SAndrew Jeffery             Len -= Written;
700*cf3c1e67SAndrew Jeffery             continue;
701*cf3c1e67SAndrew Jeffery         }
702*cf3c1e67SAndrew Jeffery 
703*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
704*cf3c1e67SAndrew Jeffery             return -1;
705*cf3c1e67SAndrew Jeffery     }
706*cf3c1e67SAndrew Jeffery 
707*cf3c1e67SAndrew Jeffery     return WrtLen;
708*cf3c1e67SAndrew Jeffery }
709*cf3c1e67SAndrew Jeffery 
710*cf3c1e67SAndrew Jeffery 
sigwrap_writev(int fd,const struct iovec * iov,int iovcnt)711*cf3c1e67SAndrew Jeffery ssize_t sigwrap_writev(int fd, const struct iovec *iov, int iovcnt)
712*cf3c1e67SAndrew Jeffery {
713*cf3c1e67SAndrew Jeffery     while (1)
714*cf3c1e67SAndrew Jeffery     {
715*cf3c1e67SAndrew Jeffery         ssize_t Result = writev(fd, iov, iovcnt);
716*cf3c1e67SAndrew Jeffery 
717*cf3c1e67SAndrew Jeffery         if (Result != -1)
718*cf3c1e67SAndrew Jeffery             return (Result);
719*cf3c1e67SAndrew Jeffery 
720*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
721*cf3c1e67SAndrew Jeffery             return (Result);
722*cf3c1e67SAndrew Jeffery     }
723*cf3c1e67SAndrew Jeffery }
724*cf3c1e67SAndrew Jeffery 
725*cf3c1e67SAndrew Jeffery 
sigwrap_close(int hFile)726*cf3c1e67SAndrew Jeffery int sigwrap_close(int hFile)
727*cf3c1e67SAndrew Jeffery {
728*cf3c1e67SAndrew Jeffery     while (close(hFile) == -1)
729*cf3c1e67SAndrew Jeffery     {
730*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
731*cf3c1e67SAndrew Jeffery             return -1;
732*cf3c1e67SAndrew Jeffery     }
733*cf3c1e67SAndrew Jeffery 
734*cf3c1e67SAndrew Jeffery     return 0;
735*cf3c1e67SAndrew Jeffery }
736*cf3c1e67SAndrew Jeffery 
737*cf3c1e67SAndrew Jeffery 
sigwrap_open_mode(const char * pathname,int flags,mode_t mode)738*cf3c1e67SAndrew Jeffery int sigwrap_open_mode(const char *pathname, int flags, mode_t mode)
739*cf3c1e67SAndrew Jeffery {
740*cf3c1e67SAndrew Jeffery     while (1)
741*cf3c1e67SAndrew Jeffery     {
742*cf3c1e67SAndrew Jeffery         int hFile = open(pathname, flags, mode);
743*cf3c1e67SAndrew Jeffery 
744*cf3c1e67SAndrew Jeffery         if(hFile != -1)
745*cf3c1e67SAndrew Jeffery             return hFile;
746*cf3c1e67SAndrew Jeffery 
747*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
748*cf3c1e67SAndrew Jeffery             return hFile;
749*cf3c1e67SAndrew Jeffery     }
750*cf3c1e67SAndrew Jeffery }
751*cf3c1e67SAndrew Jeffery 
sigwrap_open(const char * pathname,int flags)752*cf3c1e67SAndrew Jeffery int sigwrap_open(const char *pathname, int flags)
753*cf3c1e67SAndrew Jeffery {
754*cf3c1e67SAndrew Jeffery     while (1)
755*cf3c1e67SAndrew Jeffery     {
756*cf3c1e67SAndrew Jeffery         int hFile = open(pathname, flags);
757*cf3c1e67SAndrew Jeffery 
758*cf3c1e67SAndrew Jeffery         if(hFile != -1)
759*cf3c1e67SAndrew Jeffery             return hFile;
760*cf3c1e67SAndrew Jeffery 
761*cf3c1e67SAndrew Jeffery         if (errno != EINTR)
762*cf3c1e67SAndrew Jeffery             return hFile;
763*cf3c1e67SAndrew Jeffery     }
764*cf3c1e67SAndrew Jeffery }
765*cf3c1e67SAndrew Jeffery 
766*cf3c1e67SAndrew Jeffery 
sigwrap_wait(int * status)767*cf3c1e67SAndrew Jeffery pid_t sigwrap_wait(int *status)
768*cf3c1e67SAndrew Jeffery {
769*cf3c1e67SAndrew Jeffery     while(1)
770*cf3c1e67SAndrew Jeffery     {
771*cf3c1e67SAndrew Jeffery         pid_t Result = wait(status);
772*cf3c1e67SAndrew Jeffery 
773*cf3c1e67SAndrew Jeffery         if(Result != -1)
774*cf3c1e67SAndrew Jeffery             return Result;
775*cf3c1e67SAndrew Jeffery 
776*cf3c1e67SAndrew Jeffery         if(errno != EINTR)
777*cf3c1e67SAndrew Jeffery             return Result;
778*cf3c1e67SAndrew Jeffery     }
779*cf3c1e67SAndrew Jeffery }
780*cf3c1e67SAndrew Jeffery 
781*cf3c1e67SAndrew Jeffery 
sigwrap_waitpid(pid_t pid,int * status,int options)782*cf3c1e67SAndrew Jeffery pid_t sigwrap_waitpid(pid_t pid, int *status, int options)
783*cf3c1e67SAndrew Jeffery {
784*cf3c1e67SAndrew Jeffery     while(1)
785*cf3c1e67SAndrew Jeffery     {
786*cf3c1e67SAndrew Jeffery         pid_t Result = waitpid(pid, status, options);
787*cf3c1e67SAndrew Jeffery 
788*cf3c1e67SAndrew Jeffery         if(Result != -1)
789*cf3c1e67SAndrew Jeffery             return Result;
790*cf3c1e67SAndrew Jeffery 
791*cf3c1e67SAndrew Jeffery         if(errno != EINTR)
792*cf3c1e67SAndrew Jeffery             return Result;
793*cf3c1e67SAndrew Jeffery     }
794*cf3c1e67SAndrew Jeffery }
795*cf3c1e67SAndrew Jeffery 
796*cf3c1e67SAndrew Jeffery 
sigwrap_waitid(idtype_t idtype,id_t id,siginfo_t * infop,int options)797*cf3c1e67SAndrew Jeffery int sigwrap_waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
798*cf3c1e67SAndrew Jeffery {
799*cf3c1e67SAndrew Jeffery     while(1)
800*cf3c1e67SAndrew Jeffery     {
801*cf3c1e67SAndrew Jeffery         int Result = waitid(idtype, id, infop, options);
802*cf3c1e67SAndrew Jeffery 
803*cf3c1e67SAndrew Jeffery         if(Result != -1)
804*cf3c1e67SAndrew Jeffery             return Result;
805*cf3c1e67SAndrew Jeffery 
806*cf3c1e67SAndrew Jeffery         if(errno != EINTR)
807*cf3c1e67SAndrew Jeffery             return Result;
808*cf3c1e67SAndrew Jeffery     }
809*cf3c1e67SAndrew Jeffery }
810*cf3c1e67SAndrew Jeffery 
811*cf3c1e67SAndrew Jeffery 
sigwrap_flock(int fd,int operation)812*cf3c1e67SAndrew Jeffery int sigwrap_flock(int fd, int operation)
813*cf3c1e67SAndrew Jeffery {
814*cf3c1e67SAndrew Jeffery     while(1)
815*cf3c1e67SAndrew Jeffery     {
816*cf3c1e67SAndrew Jeffery         int Result = flock(fd, operation);
817*cf3c1e67SAndrew Jeffery 
818*cf3c1e67SAndrew Jeffery         if(Result != -1)
819*cf3c1e67SAndrew Jeffery             return Result;
820*cf3c1e67SAndrew Jeffery 
821*cf3c1e67SAndrew Jeffery         if(errno != EINTR)
822*cf3c1e67SAndrew Jeffery             return Result;
823*cf3c1e67SAndrew Jeffery     }
824*cf3c1e67SAndrew Jeffery }
825*cf3c1e67SAndrew Jeffery 
826*cf3c1e67SAndrew Jeffery 
827