1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "tools/android/common/daemon.h"
6
7#include <errno.h>
8#include <signal.h>
9#include <stdio.h>
10#include <sys/types.h>
11#include <unistd.h>
12
13#include "base/command_line.h"
14#include "base/logging.h"
15
16namespace {
17
18const char kNoSpawnDaemon[] = "D";
19
20int g_exit_status = 0;
21
22void Exit(int unused) {
23  _exit(g_exit_status);
24}
25
26void CloseFileDescriptor(int fd) {
27  int old_errno = errno;
28  close(fd);
29  errno = old_errno;
30}
31
32}  // namespace
33
34namespace tools {
35
36bool HasHelpSwitch(const CommandLine& command_line) {
37  return command_line.HasSwitch("h") || command_line.HasSwitch("help");
38}
39
40bool HasNoSpawnDaemonSwitch(const CommandLine& command_line) {
41  return command_line.HasSwitch(kNoSpawnDaemon);
42}
43
44void ShowHelp(const char* program,
45              const char* extra_title,
46              const char* extra_descriptions) {
47  printf("Usage: %s [-%s] %s\n"
48         " -%s  stops from spawning a daemon process\n%s",
49         program, kNoSpawnDaemon, extra_title, kNoSpawnDaemon,
50         extra_descriptions);
51}
52
53void SpawnDaemon(int exit_status) {
54  g_exit_status = exit_status;
55  signal(SIGUSR1, Exit);
56
57  if (fork()) {
58    // In parent process.
59    sleep(10);  // Wait for the child process to finish setsid().
60    NOTREACHED();
61  }
62
63  // In child process.
64  setsid();  // Detach the child process from its parent.
65  kill(getppid(), SIGUSR1);  // Inform the parent process to exit.
66
67  // Close the standard input and outputs, otherwise the process may block
68  // adbd when the shell exits.
69  // Comment out these lines if you want to see outputs for debugging.
70  CloseFileDescriptor(0);
71  CloseFileDescriptor(1);
72  CloseFileDescriptor(2);
73}
74
75}  // namespace tools
76