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