// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "tools/android/common/daemon.h"
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include "base/command_line.h"
#include "base/notreached.h"
namespace {
const char kNoSpawnDaemon[] = "no-spawn-daemon";
int g_exit_status = 0;
void Exit(int unused) {
_exit(g_exit_status);
}
void CloseFileDescriptor(int fd) {
int old_errno = errno;
close(fd);
errno = old_errno;
}
} // namespace
namespace tools {
bool HasHelpSwitch(const base::CommandLine& command_line) {
return command_line.HasSwitch("h") || command_line.HasSwitch("help");
}
bool HasNoSpawnDaemonSwitch(const base::CommandLine& command_line) {
return command_line.HasSwitch(kNoSpawnDaemon);
}
void ShowHelp(const char* program,
const char* extra_title,
const char* extra_descriptions) {
printf("Usage: %s [-%s] %s\n"
" -%s stops from spawning a daemon process\n%s",
program, kNoSpawnDaemon, extra_title, kNoSpawnDaemon,
extra_descriptions);
}
void SpawnDaemon(int exit_status) {
g_exit_status = exit_status;
signal(SIGUSR1, Exit);
if (fork()) {
// In parent process.
sleep(10); // Wait for the child process to finish setsid().
NOTREACHED_IN_MIGRATION();
}
// In child process.
setsid(); // Detach the child process from its parent.
kill(getppid(), SIGUSR1); // Inform the parent process to exit.
// Close the standard input and outputs, otherwise the process may block
// adbd when the shell exits.
// Comment out these lines if you want to see outputs for debugging.
CloseFileDescriptor(0);
CloseFileDescriptor(1);
CloseFileDescriptor(2);
}
} // namespace tools