ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/lib/dropin.c
Revision: 1.3
Committed: Tue Apr 26 00:55:55 2005 UTC (19 years ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_01, rel-3_0, rel-2_2, rel-2_0, rel-2_21, rel-2_22, rel-2_25, HEAD
Changes since 1.2: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 dropin.c -- a set of drop-in replacements for libc functions
3 Copyright (C) 2000,2001 Ivo Timmermans <ivo@o2w.nl>,
4 2000,2001 Guus Sliepen <guus@sliepen.eu.org>
5 2003 Marc Lehmann <gvpe@schmorp.de>
6
7 This file is part of GVPE.
8
9 GVPE is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with gvpe; if not, write to the Free Software
21 Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #include "config.h"
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33
34 #include <errno.h>
35
36 #ifndef HAVE_DAEMON
37 /*
38 Replacement for the daemon() function.
39
40 The daemon() function is for programs wishing to detach themselves
41 from the controlling terminal and run in the background as system
42 daemons.
43
44 Unless the argument nochdir is non-zero, daemon() changes the
45 current working directory to the root (``/'').
46
47 Unless the argument noclose is non-zero, daemon() will redirect
48 standard input, standard output and standard error to /dev/null.
49 */
50 int daemon(int nochdir, int noclose)
51 {
52 pid_t pid;
53 int fd;
54
55 pid = fork();
56
57 /* Check if forking failed */
58 if(pid < 0) {
59 perror("fork");
60 exit(-1);
61 }
62
63 /* If we are the parent, terminate */
64 if(pid)
65 exit(0);
66
67 /* Detach by becoming the new process group leader */
68 if(setsid() < 0) {
69 perror("setsid");
70 return -1;
71 }
72
73 /* Change working directory to the root (to avoid keeping mount
74 points busy) */
75 if(!nochdir) {
76 chdir("/");
77 }
78
79 /* Redirect stdin/out/err to /dev/null */
80 if(!noclose) {
81 fd = open("/dev/null", O_RDWR);
82
83 if(fd < 0) {
84 perror("opening /dev/null");
85 return -1;
86 } else {
87 dup2(fd, 0);
88 dup2(fd, 1);
89 dup2(fd, 2);
90 }
91 }
92
93 return 0;
94 }
95 #endif
96
97 #ifndef HAVE_GET_CURRENT_DIR_NAME
98 /*
99 Replacement for the GNU get_current_dir_name function:
100
101 get_current_dir_name will malloc(3) an array big enough to hold the
102 current directory name. If the environment variable PWD is set, and
103 its value is correct, then that value will be returned.
104 */
105 char *get_current_dir_name(void)
106 {
107 size_t size;
108 char *buf;
109 char *r;
110
111 /* Start with 100 bytes. If this turns out to be insufficient to
112 contain the working directory, double the size. */
113 size = 100;
114 buf = malloc(size);
115
116 errno = 0; /* Success */
117 r = getcwd(buf, size);
118
119 /* getcwd returns NULL and sets errno to ERANGE if the bufferspace
120 is insufficient to contain the entire working directory. */
121 while(r == NULL && errno == ERANGE) {
122 free(buf);
123 size <<= 1; /* double the size */
124 buf = malloc(size);
125 r = getcwd(buf, size);
126 }
127
128 return buf;
129 }
130 #endif
131
132 #ifndef HAVE_ASPRINTF
133 int asprintf(char **buf, const char *fmt, ...)
134 {
135 int status;
136 va_list ap;
137 int len;
138
139 len = 4096;
140 *buf = malloc(len);
141
142 va_start(ap, fmt);
143 status = vsnprintf(*buf, len, fmt, ap);
144 va_end(ap);
145
146 if(status >= 0)
147 *buf = realloc(*buf, status);
148
149 if(status > len - 1) {
150 len = status;
151 va_start(ap, fmt);
152 status = vsnprintf(*buf, len, fmt, ap);
153 va_end(ap);
154 }
155
156 return status;
157 }
158 #endif