| 2010 | } |
| 2011 | |
| 2012 | enum start_bg_result start_bg_command(struct child_process *cmd, |
| 2013 | start_bg_wait_cb *wait_cb, |
| 2014 | void *cb_data, |
| 2015 | unsigned int timeout_sec) |
| 2016 | { |
| 2017 | enum start_bg_result sbgr = SBGR_ERROR; |
| 2018 | int ret; |
| 2019 | int wait_status; |
| 2020 | pid_t pid_seen; |
| 2021 | time_t time_limit; |
| 2022 | |
| 2023 | /* |
| 2024 | * We do not allow clean-on-exit because the child process |
| 2025 | * should persist in the background and possibly/probably |
| 2026 | * after this process exits. So we don't want to kill the |
| 2027 | * child during our atexit routine. |
| 2028 | */ |
| 2029 | if (cmd->clean_on_exit) |
| 2030 | BUG("start_bg_command() does not allow non-zero clean_on_exit"); |
| 2031 | |
| 2032 | if (!cmd->trace2_child_class) |
| 2033 | cmd->trace2_child_class = "background"; |
| 2034 | |
| 2035 | ret = start_command(cmd); |
| 2036 | if (ret) { |
| 2037 | /* |
| 2038 | * We assume that if `start_command()` fails, we |
| 2039 | * either get a complete `trace2_child_start() / |
| 2040 | * trace2_child_exit()` pair or it fails before the |
| 2041 | * `trace2_child_start()` is emitted, so we do not |
| 2042 | * need to worry about it here. |
| 2043 | * |
| 2044 | * We also assume that `start_command()` does not add |
| 2045 | * us to the cleanup list. And that it calls |
| 2046 | * `child_process_clear()`. |
| 2047 | */ |
| 2048 | sbgr = SBGR_ERROR; |
| 2049 | goto done; |
| 2050 | } |
| 2051 | |
| 2052 | time(&time_limit); |
| 2053 | time_limit += timeout_sec; |
| 2054 | |
| 2055 | wait: |
| 2056 | pid_seen = waitpid(cmd->pid, &wait_status, WNOHANG); |
| 2057 | |
| 2058 | if (!pid_seen) { |
| 2059 | /* |
| 2060 | * The child is currently running. Ask the callback |
| 2061 | * if the child is ready to do work or whether we |
| 2062 | * should keep waiting for it to boot up. |
| 2063 | */ |
| 2064 | ret = (*wait_cb)(cmd, cb_data); |
| 2065 | if (!ret) { |
| 2066 | /* |
| 2067 | * The child is running and "ready". |
| 2068 | */ |
| 2069 | trace2_child_ready(cmd, "ready"); |