- Timestamp:
- 05/29/05 22:35:58 (3 years ago)
- Files:
-
- branches/wdctlrestart/wifidog/ChangeLog (modified) (1 diff)
- branches/wdctlrestart/wifidog/src/client_list.c (modified) (2 diffs)
- branches/wdctlrestart/wifidog/src/client_list.h (modified) (1 diff)
- branches/wdctlrestart/wifidog/src/commandline.c (modified) (3 diffs)
- branches/wdctlrestart/wifidog/src/conf.c (modified) (1 diff)
- branches/wdctlrestart/wifidog/src/conf.h (modified) (2 diffs)
- branches/wdctlrestart/wifidog/src/debug.c (modified) (1 diff)
- branches/wdctlrestart/wifidog/src/firewall.c (modified) (4 diffs)
- branches/wdctlrestart/wifidog/src/fw_iptables.c (modified) (2 diffs)
- branches/wdctlrestart/wifidog/src/gateway.c (modified) (15 diffs)
- branches/wdctlrestart/wifidog/src/safe.c (modified) (2 diffs)
- branches/wdctlrestart/wifidog/src/safe.h (modified) (2 diffs)
- branches/wdctlrestart/wifidog/src/util.c (modified) (4 diffs)
- branches/wdctlrestart/wifidog/src/wdctl.c (modified) (5 diffs)
- branches/wdctlrestart/wifidog/src/wdctl.h (modified) (1 diff)
- branches/wdctlrestart/wifidog/src/wdctl_thread.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/wdctlrestart/wifidog/ChangeLog
r639 r644 1 1 # $Header$ 2 3 2005-05-26 Mina Naguib <mina@ilesansfil.org> 4 * New wdctl command "restart" which will get wifidog to restart itself 5 while preserving the existing clientlist. Perfect for 0-downtime 6 upgrading! 7 * safe.c: New safe_fork that croaks if the fork fails, also takes care of 8 closing some global file descriptors for the child 9 * debug.c: Now also logs the PID as part of every entry 10 * gateway.c: Handler for SIGCHLD now waitpid()s with WNOHANG flag to prevent deadlock 11 when the handler is called and another wait() or waitpid() is used 12 * util.c: execute() now uses waitpid() instead of wait() to reap only the child 13 it fork/executed 14 * Extra debugging entries throughout code 2 15 3 16 2005-05-24 Mina Naguib <mina@ilesansfil.org> branches/wdctlrestart/wifidog/src/client_list.c
r467 r644 51 51 * Holds a pointer to the first element of the list 52 52 */ 53 statict_client *firstclient = NULL;53 t_client *firstclient = NULL; 54 54 55 55 /** Get the first element of the list of connected clients … … 96 96 curclient->mac = safe_strdup(mac); 97 97 curclient->token = safe_strdup(token); 98 curclient->counters.incoming = curclient->counters. outgoing= 0;98 curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing = curclient->counters.outgoing_history = 0; 99 99 curclient->counters.last_updated = time(NULL); 100 100 branches/wdctlrestart/wifidog/src/client_list.h
r471 r644 31 31 */ 32 32 typedef struct _t_counters { 33 unsigned long long incoming; /**< @brief Incoming data */ 34 unsigned long long outgoing; /**< @brief Outgoing data */ 33 unsigned long long incoming; /**< @brief Incoming data total*/ 34 unsigned long long outgoing; /**< @brief Outgoing data total*/ 35 unsigned long long incoming_history; /**< @brief Incoming data before wifidog restarted*/ 36 unsigned long long outgoing_history; /**< @brief Outgoing data before wifidog restarted*/ 35 37 time_t last_updated; /**< @brief Last update of the counters */ 36 38 } t_counters; branches/wdctlrestart/wifidog/src/commandline.c
r467 r644 29 29 #include <unistd.h> 30 30 #include <string.h> 31 #include <syslog.h> 31 32 33 #include "debug.h" 32 34 #include "safe.h" 33 35 #include "conf.h" … … 35 37 #include "../config.h" 36 38 39 /* 40 * Holds an argv that could be passed to exec*() if we restart ourselves 41 */ 42 char ** restartargv = NULL; 43 37 44 static void usage(void); 45 46 /* 47 * A flag to denote whether we were restarted via a parent wifidog, or started normally 48 * 0 means normally, otherwise it will be populated by the PID of the parent 49 */ 50 pid_t restarted = 0; 38 51 39 52 /** @internal … … 54 67 printf(" -h Print usage\n"); 55 68 printf(" -v Print version information\n"); 69 printf(" -x pid Used internally by WiFiDog when re-starting itself *DO NOT ISSUE THIS SWITCH MANUAlLY*\n"); 70 printf(" -i <path> Internal socket path used when re-starting self\n"); 56 71 printf("\n"); 57 72 } 58 73 59 74 /** Uses getopt() to parse the command line and set configuration values 75 * also populates restartargv 60 76 */ 61 void 62 parse_commandline(int argc, char **argv) 63 { 77 void parse_commandline(int argc, char **argv) { 64 78 int c; 79 int skiponrestart; 80 int i; 81 65 82 s_config *config = config_get_config(); 66 83 67 while (-1 != (c = getopt(argc, argv, "c:hfd:sw:v"))) { 68 switch(c) { 69 case 'h': 70 usage(); 71 exit(1); 72 break; 84 //MAGIC 3: Our own -x, the pid, and NULL : 85 restartargv = safe_malloc((argc + 3) * sizeof(char*)); 86 i=0; 87 restartargv[i++] = safe_strdup(argv[0]); 73 88 74 case 'c': 75 if (optarg) { 76 strncpy(config->configfile, optarg, sizeof(config->configfile)); 77 } 78 break; 89 while (-1 != (c = getopt(argc, argv, "c:hfd:sw:vx:i:"))) { 79 90 80 case 'w': 81 if (optarg) { 82 free(config->wdctl_sock); 83 config->wdctl_sock = safe_strdup(optarg); 91 skiponrestart = 0; 92 93 switch(c) { 94 95 case 'h': 96 usage(); 97 exit(1); 98 break; 99 100 case 'c': 101 if (optarg) { 102 strncpy(config->configfile, optarg, sizeof(config->configfile)); 103 } 104 break; 105 106 case 'w': 107 if (optarg) { 108 free(config->wdctl_sock); 109 config->wdctl_sock = safe_strdup(optarg); 110 } 111 break; 112 113 case 'f': 114 skiponrestart = 1; 115 config->daemon = 0; 116 break; 117 118 case 'd': 119 if (optarg) { 120 config->debuglevel = atoi(optarg); 121 } 122 break; 123 124 case 's': 125 config->log_syslog = 1; 126 break; 127 128 case 'v': 129 printf("This is WiFiDog version " VERSION "\n"); 130 exit(1); 131 break; 132 133 case 'x': 134 skiponrestart = 1; 135 if (optarg) { 136 restarted = atoi(optarg); 137 } 138 else { 139 printf("The expected PID to the -x switch was not supplied!"); 140 exit(1); 141 } 142 break; 143 144 case 'i': 145 if (optarg) { 146 free(config->internal_sock); 147 config->internal_sock = safe_strdup(optarg); 148 } 149 break; 150 151 default: 152 usage(); 153 exit(1); 154 break; 155 84 156 } 85 break;86 157 87 case 'f': 88 config->daemon = 0; 89 break; 158 if (!skiponrestart) { 159 /* Add it to restartargv */ 160 safe_asprintf(&(restartargv[i++]), "-%c", c); 161 if (optarg) { 162 restartargv[i++] = safe_strdup(optarg); 163 } 164 } 90 165 91 case 'd': 92 if (optarg) { 93 config->debuglevel = atoi(optarg); 94 } 95 break; 166 } 96 167 97 case 's': 98 config->log_syslog = 1; 99 break; 168 /* Finally, we should add the -x, pid and NULL to restartargv 169 * HOWEVER we cannot do it here, since this is called before we fork to background 170 * so we'll leave this job to gateway.c after forking is completed 171 * so that the correct PID is assigned 172 * 173 * We add 3 nulls, and the first 2 will be overridden later 174 */ 175 restartargv[i++] = NULL; 176 restartargv[i++] = NULL; 177 restartargv[i++] = NULL; 100 178 101 case 'v':102 printf("This is WiFiDog version " VERSION "\n");103 exit(1);104 break;105 106 default:107 usage();108 exit(1);109 break;110 }111 }112 179 } 113 180 branches/wdctlrestart/wifidog/src/conf.c
r491 r644 158 158 config.log_syslog = DEFAULT_LOG_SYSLOG; 159 159 config.wdctl_sock = safe_strdup(DEFAULT_WDCTL_SOCK); 160 config.internal_sock = safe_strdup(DEFAULT_INTERNAL_SOCK); 160 161 config.rulesets = NULL; 161 162 } branches/wdctlrestart/wifidog/src/conf.h
r290 r644 42 42 #define DEFAULT_SYSLOG_FACILITY LOG_DAEMON 43 43 #define DEFAULT_WDCTL_SOCK "/tmp/wdctl.sock" 44 #define DEFAULT_INTERNAL_SOCK "/tmp/wifidog.sock" 44 45 #define DEFAULT_AUTHSERVPORT 80 45 46 #define DEFAULT_AUTHSERVSSLPORT 443 … … 92 93 char configfile[255]; /**< @brief name of the config file */ 93 94 char *wdctl_sock; /**< @brief wdctl path to socket */ 95 char *internal_sock; /**< @brief internal path to socket */ 94 96 int daemon; /**< @brief if daemon > 0, use daemon mode */ 95 97 int debuglevel; /**< @brief Debug information verbosity */ branches/wdctlrestart/wifidog/src/debug.c
r243 r644 49 49 50 50 if (level <= LOG_WARNING) { 51 fprintf(stderr, "[%d][%.24s] (%s:%d) ", level, ctime_r(&ts, buf),51 fprintf(stderr, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), 52 52 filename, line); 53 53 vfprintf(stderr, format, vlist); 54 54 fputc('\n', stderr); 55 55 } else if (!config->daemon) { 56 fprintf(stdout, "[%d][%.24s] (%s:%d) ", level, ctime_r(&ts, buf),56 fprintf(stdout, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), 57 57 filename, line); 58 58 vfprintf(stdout, format, vlist); branches/wdctlrestart/wifidog/src/firewall.c
r490 r644 70 70 extern pthread_mutex_t client_list_mutex; 71 71 72 /* from commandline.c */ 73 extern pid_t restarted; 74 72 75 int icmp_fd = 0; 73 76 … … 144 147 { 145 148 int flags, oneopt = 1, zeroopt = 0; 149 int result = 0; 150 t_client * client = NULL; 146 151 147 152 debug(LOG_INFO, "Creating ICMP socket"); … … 156 161 157 162 debug(LOG_INFO, "Initializing Firewall"); 158 return iptables_fw_init(); 163 result = iptables_fw_init(); 164 165 if (restarted) { 166 debug(LOG_INFO, "Restoring firewall rules for clients inherited from parent"); 167 LOCK_CLIENT_LIST(); 168 client = client_get_first_client(); 169 while (client) { 170 fw_allow(client->ip, client->mac, client->fw_connection_state); 171 client = client->next; 172 } 173 UNLOCK_CLIENT_LIST(); 174 } 175 176 return result; 159 177 } 160 178 … … 269 287 fw_deny(p1->ip, p1->mac, p1->fw_connection_state); 270 288 p1->fw_connection_state = FW_MARK_KNOWN; 271 p1->counters.incoming = p1->counters.outgoing = 0;289 p1->counters.incoming = p1->counters.outgoing = p1->counters.incoming_history = p1->counters.outgoing_history = 0; 272 290 fw_allow(p1->ip, p1->mac, p1->fw_connection_state); 273 291 } branches/wdctlrestart/wifidog/src/fw_iptables.c
r634 r644 468 468 LOCK_CLIENT_LIST(); 469 469 if ((p1 = client_list_find_by_ip(ip))) { 470 if ( p1->counters.outgoing< counter) {471 p1->counters.outgoing = counter;470 if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) { 471 p1->counters.outgoing = p1->counters.outgoing_history + counter; 472 472 p1->counters.last_updated = time(NULL); 473 473 debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes", ip, counter); … … 506 506 LOCK_CLIENT_LIST(); 507 507 if ((p1 = client_list_find_by_ip(ip))) { 508 if ( p1->counters.incoming< counter) {509 p1->counters.incoming = counter;508 if ((p1->counters.incoming - p1->counters.incoming_history) < counter) { 509 p1->counters.incoming = p1->counters.incoming_history + counter; 510 510 debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter); 511 511 } branches/wdctlrestart/wifidog/src/gateway.c
r495 r644 35 35 #include <time.h> 36 36 37 /* for fork() */38 #include <sys/types.h>39 #include <unistd.h>40 41 37 /* for strerror() */ 42 38 #include <string.h> … … 45 41 #include <sys/wait.h> 46 42 43 /* for unix socket communication*/ 44 #include <sys/socket.h> 45 #include <sys/un.h> 46 47 #include "common.h" 47 48 #include "httpd.h" 48 49 #include "safe.h" … … 67 68 static pthread_t tid_ping = 0; 68 69 70 /* The internal web server */ 71 httpd * webserver = NULL; 72 73 /* from commandline.c */ 74 extern char ** restartargv; 75 extern pid_t restarted; 76 t_client *firstclient; 77 78 /* from client_list.c */ 79 extern pthread_mutex_t client_list_mutex; 80 81 /* Appends -x, the current PID, and NULL to restartargv 82 * see parse_commandline in commandline.c for details 83 */ 84 void append_x_restartargv(void) { 85 int i; 86 87 for (i=0; restartargv[i]; i++); 88 89 restartargv[i++] = safe_strdup("-x"); 90 safe_asprintf(&(restartargv[i++]), "%d", getpid()); 91 } 92 93 /* @internal 94 * @brief Connects to the parent via the internal socket 95 * Downloads from it the active client list 96 */ 97 void get_clients_from_parent(void) { 98 int sock; 99 struct sockaddr_un sa_un; 100 s_config * config = NULL; 101 char linebuffer[MAX_BUF]; 102 int len = 0; 103 char *running1 = NULL; 104 char *running2 = NULL; 105 char *token1 = NULL; 106 char *token2 = NULL; 107 char onechar; 108 char *command = NULL; 109 char *key = NULL; 110 char *value = NULL; 111 t_client * client = NULL; 112 t_client * lastclient = NULL; 113 114 config = config_get_config(); 115 116 debug(LOG_INFO, "Connecting to parent to download clients"); 117 118 /* Connect to socket */ 119 sock = socket(AF_UNIX, SOCK_STREAM, 0); 120 memset(&sa_un, 0, sizeof(sa_un)); 121 sa_un.sun_family = AF_UNIX; 122 strncpy(sa_un.sun_path, config->internal_sock, (sizeof(sa_un.sun_path) - 1)); 123 124 if (connect(sock, (struct sockaddr *)&sa_un, strlen(sa_un.sun_path) + sizeof(sa_un.sun_family))) { 125 debug(LOG_ERR, "Failed to connect to parent (%s) - client list not downloaded", strerror(errno)); 126 return; 127 } 128 129 debug(LOG_INFO, "Connected to parent. Downloading clients"); 130 131 LOCK_CLIENT_LIST(); 132 133 command = NULL; 134 memset(linebuffer, 0, sizeof(linebuffer)); 135 len = 0; 136 client = NULL; 137 /* Get line by line */ 138 while (read(sock, &onechar, 1) == 1) { 139 if (onechar == '\n') { 140 /* End of line */ 141 onechar = '\0'; 142 } 143 linebuffer[len++] = onechar; 144 145 if (!onechar) { 146 /* We have a complete entry in linebuffer - parse it */ 147 debug(LOG_DEBUG, "Received from parent: [%s]", linebuffer); 148 running1 = linebuffer; 149 while ((token1 = strsep(&running1, "|")) != NULL) { 150 if (!command) { 151 /* The first token is the command */ 152 command = token1; 153 } 154 else { 155 /* Token1 has something like "foo=bar" */ 156 running2 = token1; 157 key = value = NULL; 158 while ((token2 = strsep(&running2, "=")) != NULL) { 159 if (!key) { 160 key = token2; 161 } 162 else if (!value) { 163 value = token2; 164 } 165 } 166 } 167 168 if (strcmp(command, "CLIENT") == 0) { 169 /* This line has info about a client in the client list */ 170 if (!client) { 171 /* Create a new client struct */ 172 client = safe_malloc(sizeof(t_client)); 173 memset(client, 0, sizeof(t_client)); 174 } 175 } 176 177 if (key && value) { 178 if (strcmp(command, "CLIENT") == 0) { 179 /* Assign the key into the appropriate slot in the connection structure */ 180 if (strcmp(key, "ip") == 0) { 181 client->ip = safe_strdup(value); 182 } 183 else if (strcmp(key, "mac") == 0) { 184 client->mac = safe_strdup(value); 185 } 186 else if (strcmp(key, "token") == 0) { 187 client->token = safe_strdup(value); 188 } 189 else if (strcmp(key, "fw_connection_state") == 0) { 190 client->fw_connection_state = atoi(value); 191 } 192 else if (strcmp(key, "fd") == 0) { 193 client->fd = atoi(value); 194 } 195 else if (strcmp(key, "counters_incoming") == 0) { 196 client->counters.incoming_history = atoll(value); 197 client->counters.incoming = client->counters.incoming_history; 198 } 199 else if (strcmp(key, "counters_outgoing") == 0) { 200 client->counters.outgoing_history = atoll(value); 201 client->counters.outgoing = client->counters.outgoing_history; 202 } 203 else if (strcmp(key, "counters_last_updated") == 0) { 204 client->counters.last_updated = atol(value); 205 } 206 else { 207 debug(LOG_NOTICE, "I don't know how to inherit key [%s] value [%s] from parent", key, value); 208 } 209 } 210 } 211 } 212 213 /* End of parsing this command */ 214 if (client) { 215 /* Add this client to the client list */ 216 if (!firstclient) { 217 firstclient = client; 218 lastclient = firstclient; 219 } 220 else { 221 lastclient->next = client; 222 lastclient = client; 223 } 224 } 225 226 /* Clean up */ 227 command = NULL; 228 memset(linebuffer, 0, sizeof(linebuffer)); 229 len = 0; 230 client = NULL; 231 } 232 } 233 234 UNLOCK_CLIENT_LIST(); 235 debug(LOG_INFO, "Client list downloaded successfully from parent"); 236 237 close(sock); 238 } 239 69 240 /**@internal 70 241 * @brief Handles SIGCHLD signals to avoid zombie processes … … 78 249 { 79 250 int status; 251 pid_t rc; 80 252 81 wait(&status); 253 debug(LOG_DEBUG, "Handler for SIGCHLD called. Trying to reap a child"); 254 255 rc = waitpid(-1, &status, WNOHANG); 256 257 debug(LOG_DEBUG, "Handler for SIGCHLD reaped child PID %d", rc); 82 258 } 83 259 … … 89 265 static pthread_mutex_t sigterm_mutex = PTHREAD_MUTEX_INITIALIZER; 90 266 91 debug(LOG_INFO, " Caught signal %d", s);267 debug(LOG_INFO, "Handler for termination caught signal %d", s); 92 268 93 269 /* Makes sure we only call fw_destroy() once. */ … … 100 276 } 101 277 102 debug(LOG_ DEBUG, "Flushing firewall rules...");278 debug(LOG_INFO, "Flushing firewall rules..."); 103 279 fw_destroy(); 104 280 … … 116 292 } 117 293 118 debug(LOG_ DEBUG, "Exiting...");294 debug(LOG_NOTICE, "Exiting..."); 119 295 exit(s == 0 ? 1 : 0); 120 296 } … … 179 355 main_loop(void) 180 356 { 181 httpd * webserver;182 357 int result; 183 358 pthread_t tid; … … 186 361 void **params; 187 362 188 /* Initializes the linked list of connected clients */189 client_list_init();190 191 363 /* If we don't have the Gateway IP address, get it. Can't fail. */ 192 364 if (!config->gw_address) { … … 194 366 if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { 195 367 debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); 196 exit(1);368 exit(1); 197 369 } 198 370 debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); … … 200 372 201 373 /* Initializes the web server */ 202 debug(LOG_NOTICE, "Creating web server on %s:%d", 203 config->gw_address, config->gw_port); 204 webserver = httpdCreate(config->gw_address, config->gw_port); 205 if (webserver == NULL) { 206 debug(LOG_ERR, "Could not create web server: %s", 207 strerror(errno)); 374 debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); 375 if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { 376 debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); 208 377 exit(1); 209 378 } 379 210 380 debug(LOG_DEBUG, "Assigning callbacks to web server"); 211 381 httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog); … … 216 386 httpdAddC404Content(webserver, http_callback_404); 217 387 218 /* Init the signals to catch chld/quit/etc */219 init_signals();220 221 388 /* Reset the firewall (if WiFiDog crashed) */ 222 389 fw_destroy(); 390 /* Then initialize it */ 223 391 fw_init(); 224 392 … … 270 438 * We got a connection 271 439 * 272 * We should forkanother thread440 * We should create another thread 273 441 */ 274 442 debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); … … 297 465 298 466 /** Reads the configuration file and then starts the main loop */ 299 int 300 main(int argc, char **argv) 301 { 467 int main(int argc, char **argv) { 468 302 469 s_config *config = config_get_config(); 303 470 config_init(); … … 305 472 parse_commandline(argc, argv); 306 473 474 /* Initialize the config */ 307 475 config_read(config->configfile); 308 476 config_validate(); 309 477 478 /* Initializes the linked list of connected clients */ 479 client_list_init(); 480 481 /* Init the signals to catch chld/quit/etc */ 482 init_signals(); 483 484 if (restarted) { 485 /* 486 * We were restarted and our parent is waiting for us to talk to it over the socket 487 */ 488 get_clients_from_parent(); 489 490 /* 491 * At this point the parent will start destroying itself and the firewall. Let it finish it's job before we continue 492 */ 493 while (kill(restarted, 0) != -1) { 494 debug(LOG_INFO, "Waiting for parent PID %d to die before continuing loading", restarted); 495 sleep(1); 496 } 497 498 debug(LOG_INFO, "Parent PID %d seems to be dead. Continuing loading."); 499 } 500 310 501 if (config->daemon) { 311 502 312 503 debug(LOG_INFO, "Forking into background"); 313 504 314 switch(fork()) { 315 case -1: /* error */ 316 debug(LOG_ERR, "fork(): %s", strerror(errno)); 317 exit(1); 318 break; 319 320 case 0: /* parent */ 321 main_loop(); 322 break; 323 324 default: /* child */ 325 exit(0); 326 break; 327 } 328 } else { 505 switch(safe_fork()) { 506 case 0: /* child */ 507 setsid(); 508 append_x_restartargv(); 509 main_loop(); 510 break; 511 512 default: /* parent */ 513 exit(0); 514 break; 515 } 516 } 517 else { 518 append_x_restartargv(); 329 519 main_loop(); 330 520 } branches/wdctlrestart/wifidog/src/safe.c
r467 r644 28 28 */ 29 29 30 30 31 #include <stdarg.h> 32 #include <stdio.h> 31 33 #include <stdlib.h> 32 34 #include <string.h> 33 35 #include <errno.h> 34 36 37 #include "httpd.h" 35 38 #include "safe.h" 36 39 #include "debug.h" 37 40 #include <syslog.h> 41 42 /* From gateway.c */ 43 extern httpd * webserver; 38 44 39 45 void * safe_malloc (size_t size) { … … 83 89 return (retval); 84 90 } 91 92 pid_t safe_fork(void) { 93 pid_t result; 94 result = fork(); 95 96 if (result == -1) { 97 debug(LOG_CRIT, "Failed to fork: %s. Bailing out", strerror(errno)); 98 exit (1); 99 } 100 else if (result == 0) { 101 /* I'm the child - do some cleanup */ 102 if (webserver) { 103 close(webserver->serverSock); 104 webserver = NULL; 105 } 106 } 107 108 return result; 109 } 110 branches/wdctlrestart/wifidog/src/safe.h
r467 r644 29 29 30 30 #include <stdarg.h> /* For va_list */ 31 #include <sys/types.h> /* For fork */ 32 #include <unistd.h> /* For fork */ 31 33 32 34 /** @brief Safe version of malloc … … 46 48 int safe_vasprintf(char **strp, const char *fmt, va_list ap); 47 49 50 /* @brief Safe version of fork 51 */ 52 53 pid_t safe_fork(void); 54 48 55 #endif /* _SAFE_H_ */ 49 56 branches/wdctlrestart/wifidog/src/util.c
r493 r644 65 65 extern pthread_mutex_t config_mutex; 66 66 67 /* Defined in commandline.c */ 68 extern pid_t restarted; 69 67 70 /* XXX Do these need to be locked ? */ 68 71 static time_t last_online_time = 0; … … 89 92 new_argv[3] = NULL; 90 93 91 if ((pid = fork()) < 0) { /* fork a child process */ 92 debug(LOG_ERR, "fork(): %s", strerror(errno)); 93 exit(1); 94 } else if (pid == 0) { /* for the child process: */ 94 pid = safe_fork(); 95 if (pid == 0) {
