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