Fix: ust-fork: reverse order of "after" callbacks
[lttng-ust.git] / src / lib / lttng-ust-fork / ustfork.c
CommitLineData
e822f505 1/*
c0c0989a
MJ
2 * SPDX-License-Identifier: LGPL-2.1-only
3 *
e822f505 4 * Copyright (C) 2009 Pierre-Marc Fournier
3678c8aa 5 * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2d99476b
PMF
6 */
7
9d315d6d
MJ
8/* Has to be included first to override dlfcn.h */
9#include <common/compat/dlfcn.h>
10
2d99476b
PMF
11#include <unistd.h>
12#include <stdio.h>
df793c55 13#include <signal.h>
616ed36a
PMF
14#include <sched.h>
15#include <stdarg.h>
e2a195a6 16#include <stdlib.h>
eb2b066f 17#include <errno.h>
2d99476b 18
d0c8f180 19#include <lttng/ust-fork.h>
e822f505 20
aaa692c8
MD
21#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
22static int (*__ust_before_fork)(sigset_t *save_sigset) = NULL;
23static int (*__ust_after_fork_child)(sigset_t *restore_sigset) = NULL;
24static int (*__ust_after_fork_parent)(sigset_t *restore_sigset) = NULL;
25
26static void (*__ust_after_setns)(void) = NULL;
27static void (*__ust_after_unshare)(void) = NULL;
28static void (*__ust_after_setuid)(void) = NULL;
29static void (*__ust_after_setgid)(void) = NULL;
30static void (*__ust_after_seteuid)(void) = NULL;
31static void (*__ust_after_setegid)(void) = NULL;
32static void (*__ust_after_setreuid)(void) = NULL;
33static void (*__ust_after_setregid)(void) = NULL;
34static void (*__ust_after_setresuid)(void) = NULL;
35static void (*__ust_after_setresgid)(void) = NULL;
36
37static
38void *_init_ust_before_fork(void)
39{
40 if (__ust_before_fork == NULL) {
41 __ust_before_fork = dlsym(RTLD_DEFAULT, "ust_before_fork");
42
43 if (__ust_before_fork == NULL) {
44 fprintf(stderr, "%s\n", dlerror());
45 }
46 }
47
48 return __ust_before_fork;
49}
50
51static
52void *_init_ust_after_fork_child(void)
53{
54 if (__ust_after_fork_child == NULL) {
55 __ust_after_fork_child = dlsym(RTLD_DEFAULT, "ust_after_fork_child");
56
57 if (__ust_after_fork_child == NULL) {
58 fprintf(stderr, "%s\n", dlerror());
59 }
60 }
61
62 return __ust_after_fork_child;
63}
64
65static
66void *_init_ust_after_fork_parent(void)
67{
68 if (__ust_after_fork_parent == NULL) {
69 __ust_after_fork_parent = dlsym(RTLD_DEFAULT, "ust_after_fork_parent");
70
71 if (__ust_after_fork_parent == NULL) {
72 fprintf(stderr, "%s\n", dlerror());
73 }
74 }
75
76 return __ust_after_fork_parent;
77}
78
79static
80void *_init_ust_after_setns(void)
81{
82 if (__ust_after_setns == NULL) {
83 __ust_after_setns = dlsym(RTLD_DEFAULT, "ust_after_setns");
84
85 if (__ust_after_setns == NULL) {
86 fprintf(stderr, "%s\n", dlerror());
87 }
88 }
89
90 return __ust_after_setns;
91}
92
93static
94void *_init_ust_after_unshare(void)
95{
96 if (__ust_after_unshare == NULL) {
97 __ust_after_unshare = dlsym(RTLD_DEFAULT, "ust_after_unshare");
98
99 if (__ust_after_unshare == NULL) {
100 fprintf(stderr, "%s\n", dlerror());
101 }
102 }
103
104 return __ust_after_unshare;
105}
106
107static
108void *_init_ust_after_setuid(void)
109{
110 if (__ust_after_setuid == NULL) {
111 __ust_after_setuid = dlsym(RTLD_DEFAULT, "ust_after_setuid");
112
113 if (__ust_after_setuid == NULL) {
114 fprintf(stderr, "%s\n", dlerror());
115 }
116 }
117
118 return __ust_after_setuid;
119}
120
121static
122void *_init_ust_after_setgid(void)
123{
124 if (__ust_after_setgid == NULL) {
125 __ust_after_setgid = dlsym(RTLD_DEFAULT, "ust_after_setgid");
126
127 if (__ust_after_setgid == NULL) {
128 fprintf(stderr, "%s\n", dlerror());
129 }
130 }
131
132 return __ust_after_setgid;
133}
134
135static
136void *_init_ust_after_seteuid(void)
137{
138 if (__ust_after_seteuid == NULL) {
139 __ust_after_seteuid = dlsym(RTLD_DEFAULT, "ust_after_seteuid");
140
141 if (__ust_after_seteuid == NULL) {
142 fprintf(stderr, "%s\n", dlerror());
143 }
144 }
145
146 return __ust_after_seteuid;
147}
148
149static
150void *_init_ust_after_setegid(void)
151{
152 if (__ust_after_setegid == NULL) {
153 __ust_after_setegid = dlsym(RTLD_DEFAULT, "ust_after_setegid");
154
155 if (__ust_after_setegid == NULL) {
156 fprintf(stderr, "%s\n", dlerror());
157 }
158 }
159
160 return __ust_after_setegid;
161}
162
163static
164void *_init_ust_after_setreuid(void)
165{
166 if (__ust_after_setreuid == NULL) {
167 __ust_after_setreuid = dlsym(RTLD_DEFAULT, "ust_after_setreuid");
168
169 if (__ust_after_setreuid == NULL) {
170 fprintf(stderr, "%s\n", dlerror());
171 }
172 }
173
174 return __ust_after_setreuid;
175}
176
177static
178void *_init_ust_after_setregid(void)
179{
180 if (__ust_after_setregid == NULL) {
181 __ust_after_setregid = dlsym(RTLD_DEFAULT, "ust_after_setregid");
182
183 if (__ust_after_setregid == NULL) {
184 fprintf(stderr, "%s\n", dlerror());
185 }
186 }
187
188 return __ust_after_setregid;
189}
190
191static
192void *_init_ust_after_setresuid(void)
193{
194 if (__ust_after_setresuid == NULL) {
195 __ust_after_setresuid = dlsym(RTLD_DEFAULT, "ust_after_setresuid");
196
197 if (__ust_after_setresuid == NULL) {
198 fprintf(stderr, "%s\n", dlerror());
199 }
200 }
201
202 return __ust_after_setresuid;
203}
204
205static
206void *_init_ust_after_setresgid(void)
207{
208 if (__ust_after_setresgid == NULL) {
209 __ust_after_setresgid = dlsym(RTLD_DEFAULT, "ust_after_setresgid");
210
211 if (__ust_after_setresgid == NULL) {
212 fprintf(stderr, "%s\n", dlerror());
213 }
214 }
215
216 return __ust_after_setresgid;
217}
218
219static
220void _lttng_ust_fork_ctor(void)
221 __attribute__((constructor));
222static
223void _lttng_ust_fork_ctor(void)
224{
225 void *handle = NULL;
226
227 /*
228 * Load ust-2.12 in the global symbol namespace.
229 */
230 handle = dlopen("liblttng-ust.so.0", RTLD_GLOBAL | RTLD_NOW);
231 if (!handle) {
232 fprintf(stderr, "liblttng-ust-fork.so.1: Failed to dlopen liblttng-ust.so.0: %s\n", dlerror());
233 abort();
234 }
235}
236#endif
237
2d99476b
PMF
238pid_t fork(void)
239{
240 static pid_t (*plibc_func)(void) = NULL;
7f0aeeba 241 sigset_t sigset;
2d99476b 242 pid_t retval;
111902ab 243 int saved_errno;
2d99476b 244
e822f505 245 if (plibc_func == NULL) {
2d99476b 246 plibc_func = dlsym(RTLD_NEXT, "fork");
e822f505
MD
247 if (plibc_func == NULL) {
248 fprintf(stderr, "libustfork: unable to find \"fork\" symbol\n");
3678c8aa 249 errno = ENOSYS;
2c10b7fd 250 return -1;
2d99476b
PMF
251 }
252 }
253
d0c8f180 254 lttng_ust_before_fork(&sigset);
aaa692c8
MD
255#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
256 if (_init_ust_before_fork()) {
257 __ust_before_fork(&sigset);
258 }
259#endif
260
df793c55 261 /* Do the real fork */
2d99476b 262 retval = plibc_func();
111902ab 263 saved_errno = errno;
e822f505 264 if (retval == 0) {
df793c55 265 /* child */
aaa692c8
MD
266#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
267 if (_init_ust_after_fork_child()) {
268 __ust_after_fork_child(&sigset);
269 }
270#endif
0cab898d 271 lttng_ust_after_fork_child(&sigset);
e822f505 272 } else {
aaa692c8
MD
273#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
274 if (_init_ust_after_fork_parent()) {
275 __ust_after_fork_parent(&sigset);
276 }
277#endif
0cab898d 278 lttng_ust_after_fork_parent(&sigset);
df793c55 279 }
111902ab 280 errno = saved_errno;
2d99476b
PMF
281 return retval;
282}
97b042a3 283
2f6150e9
MD
284int daemon(int nochdir, int noclose)
285{
286 static int (*plibc_func)(int nochdir, int noclose) = NULL;
287 sigset_t sigset;
288 int retval;
111902ab 289 int saved_errno;
2f6150e9
MD
290
291 if (plibc_func == NULL) {
292 plibc_func = dlsym(RTLD_NEXT, "daemon");
293 if (plibc_func == NULL) {
294 fprintf(stderr, "libustfork: unable to find \"daemon\" symbol\n");
295 errno = ENOSYS;
296 return -1;
297 }
298 }
299
d0c8f180 300 lttng_ust_before_fork(&sigset);
aaa692c8
MD
301#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
302 if (_init_ust_before_fork()) {
303 __ust_before_fork(&sigset);
304 }
305#endif
306
2f6150e9
MD
307 /* Do the real daemon call */
308 retval = plibc_func(nochdir, noclose);
111902ab 309 saved_errno = errno;
2f6150e9
MD
310 if (retval == 0) {
311 /* child, parent called _exit() directly */
aaa692c8
MD
312#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
313 if (_init_ust_after_fork_child()) {
314 __ust_after_fork_child(&sigset);
315 }
316#endif
0cab898d 317 lttng_ust_after_fork_child(&sigset);
2f6150e9
MD
318 } else {
319 /* on error in the parent */
aaa692c8
MD
320#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
321 if (_init_ust_after_fork_parent()) {
322 __ust_after_fork_parent(&sigset);
323 }
324#endif
0cab898d 325 lttng_ust_after_fork_parent(&sigset);
2f6150e9 326 }
111902ab 327 errno = saved_errno;
2f6150e9
MD
328 return retval;
329}
330
fca2f191
MJ
331int setuid(uid_t uid)
332{
333 static int (*plibc_func)(uid_t uid) = NULL;
334 int retval;
335 int saved_errno;
336
337 if (plibc_func == NULL) {
338 plibc_func = dlsym(RTLD_NEXT, "setuid");
339 if (plibc_func == NULL) {
340 fprintf(stderr, "libustfork: unable to find \"setuid\" symbol\n");
341 errno = ENOSYS;
342 return -1;
343 }
344 }
345
346 /* Do the real setuid */
347 retval = plibc_func(uid);
348 saved_errno = errno;
349
aaa692c8
MD
350#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
351 if (_init_ust_after_setuid()) {
352 __ust_after_setuid();
353 }
354#endif
0cab898d 355 lttng_ust_after_setuid();
fca2f191
MJ
356
357 errno = saved_errno;
358 return retval;
359}
360
361int setgid(gid_t gid)
362{
363 static int (*plibc_func)(gid_t gid) = NULL;
364 int retval;
365 int saved_errno;
366
367 if (plibc_func == NULL) {
368 plibc_func = dlsym(RTLD_NEXT, "setgid");
369 if (plibc_func == NULL) {
370 fprintf(stderr, "libustfork: unable to find \"setgid\" symbol\n");
371 errno = ENOSYS;
372 return -1;
373 }
374 }
375
376 /* Do the real setgid */
377 retval = plibc_func(gid);
378 saved_errno = errno;
379
aaa692c8
MD
380#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
381 if (_init_ust_after_setgid()) {
382 __ust_after_setgid();
383 }
384#endif
0cab898d 385 lttng_ust_after_setgid();
fca2f191
MJ
386
387 errno = saved_errno;
388 return retval;
389}
390
391int seteuid(uid_t euid)
392{
393 static int (*plibc_func)(uid_t euid) = NULL;
394 int retval;
395 int saved_errno;
396
397 if (plibc_func == NULL) {
398 plibc_func = dlsym(RTLD_NEXT, "seteuid");
399 if (plibc_func == NULL) {
400 fprintf(stderr, "libustfork: unable to find \"seteuid\" symbol\n");
401 errno = ENOSYS;
402 return -1;
403 }
404 }
405
406 /* Do the real seteuid */
407 retval = plibc_func(euid);
408 saved_errno = errno;
409
aaa692c8
MD
410#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
411 if (_init_ust_after_seteuid()) {
412 __ust_after_seteuid();
413 }
414#endif
0cab898d 415 lttng_ust_after_seteuid();
fca2f191
MJ
416
417 errno = saved_errno;
418 return retval;
419}
420
421int setegid(gid_t egid)
422{
423 static int (*plibc_func)(gid_t egid) = NULL;
424 int retval;
425 int saved_errno;
426
427 if (plibc_func == NULL) {
428 plibc_func = dlsym(RTLD_NEXT, "setegid");
429 if (plibc_func == NULL) {
430 fprintf(stderr, "libustfork: unable to find \"setegid\" symbol\n");
431 errno = ENOSYS;
432 return -1;
433 }
434 }
435
436 /* Do the real setegid */
437 retval = plibc_func(egid);
438 saved_errno = errno;
439
aaa692c8
MD
440#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
441 if (_init_ust_after_setegid()) {
442 __ust_after_setegid();
443 }
444#endif
0cab898d 445 lttng_ust_after_setegid();
fca2f191
MJ
446
447 errno = saved_errno;
448 return retval;
449}
450
451int setreuid(uid_t ruid, uid_t euid)
452{
453 static int (*plibc_func)(uid_t ruid, uid_t euid) = NULL;
454 int retval;
455 int saved_errno;
456
457 if (plibc_func == NULL) {
458 plibc_func = dlsym(RTLD_NEXT, "setreuid");
459 if (plibc_func == NULL) {
460 fprintf(stderr, "libustfork: unable to find \"setreuid\" symbol\n");
461 errno = ENOSYS;
462 return -1;
463 }
464 }
465
466 /* Do the real setreuid */
467 retval = plibc_func(ruid, euid);
468 saved_errno = errno;
469
aaa692c8
MD
470#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
471 if (_init_ust_after_setreuid()) {
472 __ust_after_setreuid();
473 }
474#endif
0cab898d 475 lttng_ust_after_setreuid();
fca2f191
MJ
476
477 errno = saved_errno;
478 return retval;
479}
480
481int setregid(gid_t rgid, gid_t egid)
482{
483 static int (*plibc_func)(gid_t rgid, gid_t egid) = NULL;
484 int retval;
485 int saved_errno;
486
487 if (plibc_func == NULL) {
488 plibc_func = dlsym(RTLD_NEXT, "setregid");
489 if (plibc_func == NULL) {
490 fprintf(stderr, "libustfork: unable to find \"setregid\" symbol\n");
491 errno = ENOSYS;
492 return -1;
493 }
494 }
495
496 /* Do the real setregid */
497 retval = plibc_func(rgid, egid);
498 saved_errno = errno;
499
aaa692c8
MD
500#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
501 if (_init_ust_after_setregid()) {
502 __ust_after_setregid();
503 }
504#endif
0cab898d 505 lttng_ust_after_setregid();
fca2f191
MJ
506
507 errno = saved_errno;
508 return retval;
509}
510
939c89cb
MD
511#ifdef __linux__
512
513struct user_desc;
514
e822f505 515struct ustfork_clone_info {
616ed36a
PMF
516 int (*fn)(void *);
517 void *arg;
7f0aeeba 518 sigset_t sigset;
616ed36a
PMF
519};
520
521static int clone_fn(void *arg)
522{
e822f505 523 struct ustfork_clone_info *info = (struct ustfork_clone_info *) arg;
616ed36a
PMF
524
525 /* clone is now done and we are in child */
aaa692c8
MD
526#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
527 if (_init_ust_after_fork_child()) {
528 __ust_after_fork_child(&info->sigset);
529 }
530#endif
0cab898d 531 lttng_ust_after_fork_child(&info->sigset);
616ed36a
PMF
532 return info->fn(info->arg);
533}
534
535int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...)
536{
e822f505
MD
537 static int (*plibc_func)(int (*fn)(void *), void *child_stack,
538 int flags, void *arg, pid_t *ptid,
539 struct user_desc *tls, pid_t *ctid) = NULL;
540 /* var args */
616ed36a
PMF
541 pid_t *ptid;
542 struct user_desc *tls;
543 pid_t *ctid;
e822f505 544 /* end of var args */
616ed36a 545 va_list ap;
e822f505 546 int retval;
111902ab 547 int saved_errno;
616ed36a
PMF
548
549 va_start(ap, arg);
550 ptid = va_arg(ap, pid_t *);
551 tls = va_arg(ap, struct user_desc *);
552 ctid = va_arg(ap, pid_t *);
553 va_end(ap);
554
e822f505 555 if (plibc_func == NULL) {
616ed36a 556 plibc_func = dlsym(RTLD_NEXT, "clone");
e822f505
MD
557 if (plibc_func == NULL) {
558 fprintf(stderr, "libustfork: unable to find \"clone\" symbol.\n");
3678c8aa 559 errno = ENOSYS;
616ed36a
PMF
560 return -1;
561 }
562 }
563
e822f505
MD
564 if (flags & CLONE_VM) {
565 /*
566 * Creating a thread, no need to intervene, just pass on
567 * the arguments.
568 */
569 retval = plibc_func(fn, child_stack, flags, arg, ptid,
570 tls, ctid);
111902ab 571 saved_errno = errno;
e822f505
MD
572 } else {
573 /* Creating a real process, we need to intervene. */
3fd2b913 574 struct ustfork_clone_info info = { .fn = fn, .arg = arg };
616ed36a 575
d0c8f180 576 lttng_ust_before_fork(&info.sigset);
aaa692c8
MD
577#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
578 if (_init_ust_before_fork()) {
579 __ust_before_fork(&info.sigset);
580 }
581#endif
e822f505
MD
582 retval = plibc_func(clone_fn, child_stack, flags, &info,
583 ptid, tls, ctid);
111902ab 584 saved_errno = errno;
e822f505 585 /* The child doesn't get here. */
aaa692c8
MD
586#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
587 if (_init_ust_after_fork_parent()) {
588 __ust_after_fork_parent(&info.sigset);
589 }
590#endif
0cab898d 591 lttng_ust_after_fork_parent(&info.sigset);
616ed36a 592 }
111902ab 593 errno = saved_errno;
616ed36a
PMF
594 return retval;
595}
939c89cb 596
735bef47
MJ
597int setns(int fd, int nstype)
598{
599 static int (*plibc_func)(int fd, int nstype) = NULL;
600 int retval;
601 int saved_errno;
602
603 if (plibc_func == NULL) {
604 plibc_func = dlsym(RTLD_NEXT, "setns");
605 if (plibc_func == NULL) {
606 fprintf(stderr, "libustfork: unable to find \"setns\" symbol\n");
607 errno = ENOSYS;
608 return -1;
609 }
610 }
611
612 /* Do the real setns */
613 retval = plibc_func(fd, nstype);
614 saved_errno = errno;
615
aaa692c8
MD
616#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
617 if (_init_ust_after_setns()) {
618 __ust_after_setns();
619 }
620#endif
0cab898d 621 lttng_ust_after_setns();
735bef47
MJ
622
623 errno = saved_errno;
624 return retval;
625}
626
627int unshare(int flags)
628{
629 static int (*plibc_func)(int flags) = NULL;
630 int retval;
631 int saved_errno;
632
633 if (plibc_func == NULL) {
634 plibc_func = dlsym(RTLD_NEXT, "unshare");
635 if (plibc_func == NULL) {
636 fprintf(stderr, "libustfork: unable to find \"unshare\" symbol\n");
637 errno = ENOSYS;
638 return -1;
639 }
640 }
641
642 /* Do the real setns */
643 retval = plibc_func(flags);
644 saved_errno = errno;
645
aaa692c8
MD
646#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
647 if (_init_ust_after_unshare()) {
648 __ust_after_unshare();
649 }
650#endif
0cab898d 651 lttng_ust_after_unshare();
735bef47
MJ
652
653 errno = saved_errno;
654 return retval;
655}
656
fca2f191
MJ
657int setresuid(uid_t ruid, uid_t euid, uid_t suid)
658{
659 static int (*plibc_func)(uid_t ruid, uid_t euid, uid_t suid) = NULL;
660 int retval;
661 int saved_errno;
662
663 if (plibc_func == NULL) {
664 plibc_func = dlsym(RTLD_NEXT, "setresuid");
665 if (plibc_func == NULL) {
666 fprintf(stderr, "libustfork: unable to find \"setresuid\" symbol\n");
667 errno = ENOSYS;
668 return -1;
669 }
670 }
671
672 /* Do the real setresuid */
673 retval = plibc_func(ruid, euid, suid);
674 saved_errno = errno;
675
aaa692c8
MD
676#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
677 if (_init_ust_after_setresuid()) {
678 __ust_after_setresuid();
679 }
680#endif
0cab898d 681 lttng_ust_after_setresuid();
fca2f191
MJ
682
683 errno = saved_errno;
684 return retval;
685}
686
687int setresgid(gid_t rgid, gid_t egid, gid_t sgid)
688{
689 static int (*plibc_func)(gid_t rgid, gid_t egid, gid_t sgid) = NULL;
690 int retval;
691 int saved_errno;
692
693 if (plibc_func == NULL) {
694 plibc_func = dlsym(RTLD_NEXT, "setresgid");
695 if (plibc_func == NULL) {
696 fprintf(stderr, "libustfork: unable to find \"setresgid\" symbol\n");
697 errno = ENOSYS;
698 return -1;
699 }
700 }
701
702 /* Do the real setresgid */
703 retval = plibc_func(rgid, egid, sgid);
704 saved_errno = errno;
705
aaa692c8
MD
706#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
707 if (_init_ust_after_setresgid()) {
708 __ust_after_setresgid();
709 }
710#endif
0cab898d 711 lttng_ust_after_setresgid();
fca2f191
MJ
712
713 errno = saved_errno;
714 return retval;
715}
716
939c89cb
MD
717#elif defined (__FreeBSD__)
718
719pid_t rfork(int flags)
720{
e2a195a6 721 static pid_t (*plibc_func)(int flags) = NULL;
939c89cb
MD
722 sigset_t sigset;
723 pid_t retval;
111902ab 724 int saved_errno;
939c89cb
MD
725
726 if (plibc_func == NULL) {
727 plibc_func = dlsym(RTLD_NEXT, "rfork");
728 if (plibc_func == NULL) {
729 fprintf(stderr, "libustfork: unable to find \"rfork\" symbol\n");
3678c8aa 730 errno = ENOSYS;
939c89cb
MD
731 return -1;
732 }
733 }
734
d0c8f180 735 lttng_ust_before_fork(&sigset);
939c89cb 736 /* Do the real rfork */
e2a195a6 737 retval = plibc_func(flags);
111902ab 738 saved_errno = errno;
939c89cb
MD
739 if (retval == 0) {
740 /* child */
d0c8f180 741 lttng_ust_after_fork_child(&sigset);
939c89cb 742 } else {
d0c8f180 743 lttng_ust_after_fork_parent(&sigset);
939c89cb 744 }
111902ab 745 errno = saved_errno;
939c89cb
MD
746 return retval;
747}
748
749/*
750 * On BSD, no need to override vfork, because it runs in the context of
751 * the parent, with parent waiting until execve or exit is executed in
752 * the child.
753 */
754
755#else
756#warning "Unknown OS. You might want to ensure that fork/clone/vfork/fork handling is complete."
757#endif
This page took 0.0896980000000001 seconds and 5 git commands to generate.