Home | History | Annotate | Download | only in common
      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 
     16 namespace {
     17 
     18 const char kNoSpawnDaemon[] = "D";
     19 
     20 int g_exit_status = 0;
     21 
     22 void Exit(int unused) {
     23   _exit(g_exit_status);
     24 }
     25 
     26 void CloseFileDescriptor(int fd) {
     27   int old_errno = errno;
     28   close(fd);
     29   errno = old_errno;
     30 }
     31 
     32 }  // namespace
     33 
     34 namespace tools {
     35 
     36 bool HasHelpSwitch(const CommandLine& command_line) {
     37   return command_line.HasSwitch("h") || command_line.HasSwitch("help");
     38 }
     39 
     40 bool HasNoSpawnDaemonSwitch(const CommandLine& command_line) {
     41   return command_line.HasSwitch(kNoSpawnDaemon);
     42 }
     43 
     44 void 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 
     53 void 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