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