extern "C" NS_EXPORT pid_t WRAP(fork)(void) { pid_t pid; for (std::vector<AtForkFuncs>::reverse_iterator it = atfork.rbegin(); it < atfork.rend(); ++it) if (it->prepare) it->prepare(); switch ((pid = __fork())) { case 0: cpuacct_add(getuid()); for (std::vector<AtForkFuncs>::iterator it = atfork.begin(); it < atfork.end(); ++it) if (it->child) it->child(); break; default: for (std::vector<AtForkFuncs>::iterator it = atfork.begin(); it < atfork.end(); ++it) if (it->parent) it->parent(); } return pid; }
int fork(void) { int ret; /* Posix mandates that the timers of a fork child process be * disarmed, but not destroyed. To avoid a race condition, we're * going to stop all timers now, and only re-start them in case * of error, or in the parent process */ __timer_table_start_stop(1); __bionic_atfork_run_prepare(); ret = __fork(); if (ret != 0) { /* not a child process */ __timer_table_start_stop(0); __bionic_atfork_run_parent(); } else { /* * Newly created process must update cpu accounting. * Call cpuacct_add passing in our uid, which will take * the current task id and add it to the uid group passed * as a parameter. */ cpuacct_add(getuid()); __bionic_atfork_run_child(); } return ret; }
int setuid(uid_t uid) { cpuacct_add(uid); return __setuid(uid); }