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