Enable and fix many extra warnings supported by GCC and Clang.
[tinc] / src / dropin.c
1 /*
2     dropin.c -- a set of drop-in replacements for libc functions
3     Copyright (C) 2000-2005 Ivo Timmermans,
4                   2000-2022 Guus Sliepen <guus@tinc-vpn.org>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "system.h"
22
23 #ifndef HAVE_ASPRINTF
24 #include "xalloc.h"
25 #endif
26
27 #ifndef HAVE_DAEMON
28 /*
29   Replacement for the daemon() function.
30
31   The daemon() function is for programs wishing to detach themselves
32   from the controlling terminal and run in the background as system
33   daemons.
34
35   Unless the argument nochdir is non-zero, daemon() changes the
36   current working directory to the root (``/'').
37
38   Unless the argument noclose is non-zero, daemon() will redirect
39   standard input, standard output and standard error to /dev/null.
40 */
41 int daemon(int nochdir, int noclose) {
42 #ifdef HAVE_FORK
43         pid_t pid;
44         int fd;
45
46         pid = fork();
47
48         /* Check if forking failed */
49         if(pid < 0) {
50                 perror("fork");
51                 exit(-1);
52         }
53
54         /* If we are the parent, terminate */
55         if(pid) {
56                 exit(0);
57         }
58
59         /* Detach by becoming the new process group leader */
60         if(setsid() < 0) {
61                 perror("setsid");
62                 return -1;
63         }
64
65         /* Change working directory to the root (to avoid keeping mount
66            points busy) */
67         if(!nochdir) {
68                 chdir("/");
69         }
70
71         /* Redirect stdin/out/err to /dev/null */
72         if(!noclose) {
73                 fd = open("/dev/null", O_RDWR);
74
75                 if(fd < 0) {
76                         perror("opening /dev/null");
77                         return -1;
78                 } else {
79                         dup2(fd, 0);
80                         dup2(fd, 1);
81                         dup2(fd, 2);
82                 }
83         }
84
85         return 0;
86 #else
87         (void)nochdir;
88         (void)noclose;
89         return -1;
90 #endif
91 }
92 #endif
93
94 #ifndef HAVE_ASPRINTF
95 int asprintf(char **buf, const char *fmt, ...) {
96         int result;
97         va_list ap;
98         va_start(ap, fmt);
99         result = vasprintf(buf, fmt, ap);
100         va_end(ap);
101         return result;
102 }
103
104 int vasprintf(char **buf, const char *fmt, va_list ap) {
105         int status;
106         va_list aq;
107         int len;
108
109         len = 4096;
110         *buf = xmalloc(len);
111
112         va_copy(aq, ap);
113         status = vsnprintf(*buf, len, fmt, aq);
114         va_end(aq);
115
116         if(status >= 0) {
117                 *buf = xrealloc(*buf, status + 1);
118         }
119
120         if(status > len - 1) {
121                 len = status + 1;
122                 va_copy(aq, ap);
123                 status = vsnprintf(*buf, len, fmt, aq);
124                 va_end(aq);
125         }
126
127         return status;
128 }
129 #endif
130
131 #ifndef HAVE_GETTIMEOFDAY
132 int gettimeofday(struct timeval *tv, void *tz) {
133 #ifdef HAVE_MINGW
134         FILETIME ft;
135         GetSystemTimeAsFileTime(&ft);
136         uint64_t lt = (uint64_t)ft.dwLowDateTime | ((uint64_t)ft.dwHighDateTime << 32);
137         lt -= 116444736000000000ULL;
138         tv->tv_sec = lt / 10000000;
139         tv->tv_usec = (lt / 10) % 1000000;
140 #else
141 #warning No high resolution time source!
142         tv->tv_sec = time(NULL);
143         tv->tv_usec = 0;
144 #endif
145         return 0;
146 }
147 #endif