daemonize.c revision b19350d4c76b0f301466a6502dc0b5a3e3bfafda
1e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/* 2e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 4e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * you may not use this file except in compliance with the License. 6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * You may obtain a copy of the License at 7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * See the License for the specific language governing permissions and 14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * limitations under the License. 15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */ 17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 18e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 19e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/types.h> 20e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdio.h> 21e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h> 22e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <fcntl.h> 23e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <unistd.h> 24e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/stat.h> 25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/wait.h> 26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include "hardware_legacy/power.h" 29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 30e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 31b19350d4c76b0f301466a6502dc0b5a3e3bfafdaThe Android Open Source Projectint main(int argc, char **argv) 32e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 33e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int pid, fd, mode; 34e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned int delay = 0; 35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int status = 0; 36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char *file = 0; 37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char lockid[32]; 38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 39e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (argc < 2) { 40e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("Usage: %s [-f logfile] [-a] [-d delay] <program>\n", argv[0]); 41e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(1); 42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 43e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project close(0); open("/dev/null", 0); 44e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project close(1); 45e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 46e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mode = O_TRUNC; 47e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 48e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project while(**++argv == '-') { 49e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project while(*++*argv) { 50e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project switch(**argv) { 51e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case 'f': 52e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(*++*argv) 53e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project file = *argv; 54e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project else 55e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project file = *++argv; 56e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project goto next_arg; 57e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case 'd': 58e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(*++*argv) 59e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project delay = atoi(*argv); 60e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project else 61e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project delay = atoi(*++argv); 62e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project goto next_arg; 63e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case 'a': 64e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mode = O_APPEND; 65e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project break; 66e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 67e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 68e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectnext_arg: ; 69e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 70e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 71e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (file) { 72e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(open(file, O_WRONLY|mode|O_CREAT, 0666) < 0) { 73e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project perror(file); 74e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(1); 75e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 76e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 77e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project else { 78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(open("/dev/null", O_WRONLY) < 0) { 79e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project perror("/dev/null"); 80e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(1); 81e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 82e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 83e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 84e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project switch(pid = fork()) { 85e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case -1: 86e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project perror(argv[0]); 87e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(1); 88e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project break; 89e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case 0: 90e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fflush(stdout); 91e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project close(2); dup(1); /* join stdout and stderr */ 92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project chdir("/"); 93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project umask(0); 94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project setpgrp(); 95e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project setsid(); 96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (fd = 3; fd < 256; fd++) { 97e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project close(fd); 98e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 99e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(delay) { 100e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project snprintf(lockid, 32, "daemonize%d", (int) getpid()); 101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project acquire_wake_lock(PARTIAL_WAKE_LOCK, lockid); 102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 103e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 104e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project switch(pid = fork()) { 105e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case -1: 106e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project break; 107e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case 0: 108e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(delay) { 109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project sleep(delay); 110e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project execv(argv[0], argv); 112e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project execvp(argv[0], argv); 113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project perror(argv[0]); 114e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project break; 115e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project default: 116e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(delay) { 117e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project waitpid(pid, &status, 0); 118e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project release_wake_lock(lockid); 119e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 120e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project _exit(0); 121e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 122e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project _exit(1); 123e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project break; 124e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project default: 125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(0); 126e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project break; 127e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 128e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 129e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 130e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/* vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab */ 131