71c4b86c1189ff7f89e1f7edba541c5d69d98df5
2 * Copyright (C) 2009 Pierre-Marc Fournier
3 * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; version 2.1 of
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <lttng/ust-dlfcn.h>
29 #include <lttng/ust.h>
33 static pid_t (*plibc_func
)(void) = NULL
;
38 if (plibc_func
== NULL
) {
39 plibc_func
= dlsym(RTLD_NEXT
, "fork");
40 if (plibc_func
== NULL
) {
41 fprintf(stderr
, "libustfork: unable to find \"fork\" symbol\n");
47 ust_before_fork(&sigset
);
48 /* Do the real fork */
49 retval
= plibc_func();
53 ust_after_fork_child(&sigset
);
55 ust_after_fork_parent(&sigset
);
61 int daemon(int nochdir
, int noclose
)
63 static int (*plibc_func
)(int nochdir
, int noclose
) = NULL
;
68 if (plibc_func
== NULL
) {
69 plibc_func
= dlsym(RTLD_NEXT
, "daemon");
70 if (plibc_func
== NULL
) {
71 fprintf(stderr
, "libustfork: unable to find \"daemon\" symbol\n");
77 ust_before_fork(&sigset
);
78 /* Do the real daemon call */
79 retval
= plibc_func(nochdir
, noclose
);
82 /* child, parent called _exit() directly */
83 ust_after_fork_child(&sigset
);
85 /* on error in the parent */
86 ust_after_fork_parent(&sigset
);
96 struct ustfork_clone_info
{
102 static int clone_fn(void *arg
)
104 struct ustfork_clone_info
*info
= (struct ustfork_clone_info
*) arg
;
106 /* clone is now done and we are in child */
107 ust_after_fork_child(&info
->sigset
);
108 return info
->fn(info
->arg
);
111 int clone(int (*fn
)(void *), void *child_stack
, int flags
, void *arg
, ...)
113 static int (*plibc_func
)(int (*fn
)(void *), void *child_stack
,
114 int flags
, void *arg
, pid_t
*ptid
,
115 struct user_desc
*tls
, pid_t
*ctid
) = NULL
;
118 struct user_desc
*tls
;
120 /* end of var args */
126 ptid
= va_arg(ap
, pid_t
*);
127 tls
= va_arg(ap
, struct user_desc
*);
128 ctid
= va_arg(ap
, pid_t
*);
131 if (plibc_func
== NULL
) {
132 plibc_func
= dlsym(RTLD_NEXT
, "clone");
133 if (plibc_func
== NULL
) {
134 fprintf(stderr
, "libustfork: unable to find \"clone\" symbol.\n");
140 if (flags
& CLONE_VM
) {
142 * Creating a thread, no need to intervene, just pass on
145 retval
= plibc_func(fn
, child_stack
, flags
, arg
, ptid
,
149 /* Creating a real process, we need to intervene. */
150 struct ustfork_clone_info info
= { .fn
= fn
, .arg
= arg
};
152 ust_before_fork(&info
.sigset
);
153 retval
= plibc_func(clone_fn
, child_stack
, flags
, &info
,
156 /* The child doesn't get here. */
157 ust_after_fork_parent(&info
.sigset
);
163 #elif defined (__FreeBSD__)
165 pid_t
rfork(int flags
)
167 static pid_t (*plibc_func
)(void) = NULL
;
172 if (plibc_func
== NULL
) {
173 plibc_func
= dlsym(RTLD_NEXT
, "rfork");
174 if (plibc_func
== NULL
) {
175 fprintf(stderr
, "libustfork: unable to find \"rfork\" symbol\n");
181 ust_before_fork(&sigset
);
182 /* Do the real rfork */
183 retval
= plibc_func();
187 ust_after_fork_child(&sigset
);
189 ust_after_fork_parent(&sigset
);
196 * On BSD, no need to override vfork, because it runs in the context of
197 * the parent, with parent waiting until execve or exit is executed in
202 #warning "Unknown OS. You might want to ensure that fork/clone/vfork/fork handling is complete."
This page took 0.044344 seconds and 4 git commands to generate.