Fix: lazily dlopen 2.12 lttng-ust from liblttng-ust-fd.so symbol overrides
[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 */
d0c8f180 266 lttng_ust_after_fork_child(&sigset);
aaa692c8
MD
267#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
268 if (_init_ust_after_fork_child()) {
269 __ust_after_fork_child(&sigset);
270 }
271#endif
e822f505 272 } else {
d0c8f180 273 lttng_ust_after_fork_parent(&sigset);
aaa692c8
MD
274#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
275 if (_init_ust_after_fork_parent()) {
276 __ust_after_fork_parent(&sigset);
277 }
278#endif
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 */
d0c8f180 312 lttng_ust_after_fork_child(&sigset);
aaa692c8
MD
313#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
314 if (_init_ust_after_fork_child()) {
315 __ust_after_fork_child(&sigset);
316 }
317#endif
2f6150e9
MD
318 } else {
319 /* on error in the parent */
d0c8f180 320 lttng_ust_after_fork_parent(&sigset);
aaa692c8
MD
321#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
322 if (_init_ust_after_fork_parent()) {
323 __ust_after_fork_parent(&sigset);
324 }
325#endif
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
d0c8f180 350 lttng_ust_after_setuid();
aaa692c8
MD
351#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
352 if (_init_ust_after_setuid()) {
353 __ust_after_setuid();
354 }
355#endif
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
d0c8f180 380 lttng_ust_after_setgid();
aaa692c8
MD
381#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
382 if (_init_ust_after_setgid()) {
383 __ust_after_setgid();
384 }
385#endif
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
d0c8f180 410 lttng_ust_after_seteuid();
aaa692c8
MD
411#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
412 if (_init_ust_after_seteuid()) {
413 __ust_after_seteuid();
414 }
415#endif
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
d0c8f180 440 lttng_ust_after_setegid();
aaa692c8
MD
441#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
442 if (_init_ust_after_setegid()) {
443 __ust_after_setegid();
444 }
445#endif
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
d0c8f180 470 lttng_ust_after_setreuid();
aaa692c8
MD
471#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
472 if (_init_ust_after_setreuid()) {
473 __ust_after_setreuid();
474 }
475#endif
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
d0c8f180 500 lttng_ust_after_setregid();
aaa692c8
MD
501#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
502 if (_init_ust_after_setregid()) {
503 __ust_after_setregid();
504 }
505#endif
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 */
d0c8f180 526 lttng_ust_after_fork_child(&info->sigset);
aaa692c8
MD
527#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
528 if (_init_ust_after_fork_child()) {
529 __ust_after_fork_child(&info->sigset);
530 }
531#endif
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. */
d0c8f180 586 lttng_ust_after_fork_parent(&info.sigset);
aaa692c8
MD
587#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
588 if (_init_ust_after_fork_parent()) {
589 __ust_after_fork_parent(&info.sigset);
590 }
591#endif
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
d0c8f180 616 lttng_ust_after_setns();
aaa692c8
MD
617#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
618 if (_init_ust_after_setns()) {
619 __ust_after_setns();
620 }
621#endif
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
d0c8f180 646 lttng_ust_after_unshare();
aaa692c8
MD
647#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
648 if (_init_ust_after_unshare()) {
649 __ust_after_unshare();
650 }
651#endif
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
d0c8f180 676 lttng_ust_after_setresuid();
aaa692c8
MD
677#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
678 if (_init_ust_after_setresuid()) {
679 __ust_after_setresuid();
680 }
681#endif
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
d0c8f180 706 lttng_ust_after_setresgid();
aaa692c8
MD
707#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
708 if (_init_ust_after_setresgid()) {
709 __ust_after_setresgid();
710 }
711#endif
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.079514 seconds and 5 git commands to generate.