132
* This makes sure any loggers are flushed and will later also work the
133
* termination callback chain.
135
static void rtR3ExitCallback(void)
139
PRTLOGGER pLogger = RTLogGetDefaultInstance();
143
pLogger = RTLogRelDefaultInstance();
127
150
#ifndef RT_OS_WINDOWS
135
158
#endif /* RT_OS_WINDOWS */
161
/** Fork completion callback for OS/2. Only called in the child. */
162
static void rtR3ForkOs2ChildCompletionCallback(void *pvArg, int rc, __LIBC_FORKCTX enmCtx)
164
Assert(enmCtx == __LIBC_FORK_CTX_CHILD); NOREF(enmCtx);
168
rtR3ForkChildCallback();
138
171
/** Low-level fork callback for OS/2. */
139
172
int rtR3ForkOs2Child(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation)
141
if (enmOperation == __LIBC_FORK_STAGE_COMPLETION_CHILD)
142
rtR3ForkChildCallback();
174
if (enmOperation == __LIBC_FORK_OP_EXEC_CHILD)
175
return pForkHandle->pfnCompletionCallback(pForkHandle, rtR3ForkOs2ChildCompletionCallback, NULL, __LIBC_FORK_CTX_CHILD);
183
216
return VINF_SUCCESS;
220
#ifdef IPRT_USE_SIG_CHILD_DUMMY
222
* Dummy SIGCHILD handler.
224
* Assigned on rtR3Init only when SIGCHILD handler is set SIGIGN or SIGDEF to
225
* ensure waitpid works properly for the terminated processes.
227
static void rtR3SigChildHandler(int iSignal)
231
#endif /* IPRT_USE_SIG_CHILD_DUMMY */
187
235
* rtR3Init worker.
268
316
/* Init C runtime locale. */
269
317
setlocale(LC_CTYPE, "");
271
/* Fork callbacks. */
319
/* Fork and exit callbacks. */
272
320
#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2)
273
321
rc = pthread_atfork(NULL, NULL, rtR3ForkChildCallback);
274
322
AssertMsg(rc == 0, ("%d\n", rc));
324
atexit(rtR3ExitCallback);
326
#ifdef IPRT_USE_SIG_CHILD_DUMMY
328
* SIGCHLD must not be ignored (that's default), otherwise posix compliant waitpid
329
* implementations won't work right.
333
struct sigaction saOld;
334
rc = sigaction(SIGCHLD, 0, &saOld); AssertMsg(rc == 0, ("%d/%d\n", rc, errno));
336
|| (saOld.sa_flags & SA_SIGINFO)
337
|| ( saOld.sa_handler != SIG_IGN
338
&& saOld.sa_handler != SIG_DFL)
342
/* Try install dummy handler. */
343
struct sigaction saNew = saOld;
344
saNew.sa_flags = SA_NOCLDSTOP | SA_RESTART;
345
saNew.sa_handler = rtR3SigChildHandler;
346
rc = sigemptyset(&saNew.sa_mask); AssertMsg(rc == 0, ("%d/%d\n", rc, errno));
347
struct sigaction saOld2;
348
rc = sigaction(SIGCHLD, &saNew, &saOld2); AssertMsg(rc == 0, ("%d/%d\n", rc, errno));
350
|| ( saOld2.sa_handler == saOld.sa_handler
351
&& !(saOld2.sa_flags & SA_SIGINFO))
355
/* Race during dynamic load, restore and try again... */
356
sigaction(SIGCHLD, &saOld2, NULL);
359
#endif /* IPRT_USE_SIG_CHILD_DUMMY */
277
361
#ifdef IPRT_WITH_ALIGNMENT_CHECKS