Changeset 765
- Timestamp:
- 09/24/05 23:58:47 (3 years ago)
- Files:
-
- trunk/wifidog/ChangeLog (modified) (1 diff)
- trunk/wifidog/src/client_list.c (modified) (2 diffs)
- trunk/wifidog/src/client_list.h (modified) (1 diff)
- trunk/wifidog/src/commandline.c (modified) (3 diffs)
- trunk/wifidog/src/conf.c (modified) (1 diff)
- trunk/wifidog/src/conf.h (modified) (2 diffs)
- trunk/wifidog/src/debug.c (modified) (1 diff)
- trunk/wifidog/src/firewall.c (modified) (4 diffs)
- trunk/wifidog/src/fw_iptables.c (modified) (2 diffs)
- trunk/wifidog/src/gateway.c (modified) (14 diffs)
- trunk/wifidog/src/safe.c (modified) (2 diffs)
- trunk/wifidog/src/safe.h (modified) (2 diffs)
- trunk/wifidog/src/util.c (modified) (4 diffs)
- trunk/wifidog/src/wdctl.c (modified) (5 diffs)
- trunk/wifidog/src/wdctl.h (modified) (1 diff)
- trunk/wifidog/src/wdctl_thread.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/wifidog/ChangeLog
r764 r765 1 1 # $Header$ 2 3 2005-09-24 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-09-24 Mina Naguib <mina@ilesansfil.org> trunk/wifidog/src/client_list.c
r467 r765 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 trunk/wifidog/src/client_list.h
r471 r765 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; trunk/wifidog/src/commandline.c
r467 r765 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 trunk/wifidog/src/conf.c
r764 r765 155 155 config.log_syslog = DEFAULT_LOG_SYSLOG; 156 156 config.wdctl_sock = safe_strdup(DEFAULT_WDCTL_SOCK); 157 config.internal_sock = safe_strdup(DEFAULT_INTERNAL_SOCK); 157 158 config.rulesets = NULL; 158 159 config.trustedmaclist = NULL; trunk/wifidog/src/conf.h
r763 r765 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 … … 100 101 char configfile[255]; /**< @brief name of the config file */ 101 102 char *wdctl_sock; /**< @brief wdctl path to socket */ 103 char *internal_sock; /**< @brief internal path to socket */ 102 104 int daemon; /**< @brief if daemon > 0, use daemon mode */ 103 105 int debuglevel; /**< @brief Debug information verbosity */ trunk/wifidog/src/debug.c
r243 r765 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); trunk/wifidog/src/firewall.c
r490 r765 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 } trunk/wifidog/src/fw_iptables.c
r763 r765 476 476 LOCK_CLIENT_LIST(); 477 477 if ((p1 = client_list_find_by_ip(ip))) { 478 if ( p1->counters.outgoing< counter) {479 p1->counters.outgoing = counter;478 if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) { 479 p1->counters.outgoing = p1->counters.outgoing_history + counter; 480 480 p1->counters.last_updated = time(NULL); 481 481 debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes", ip, counter); … … 514 514 LOCK_CLIENT_LIST(); 515 515 if ((p1 = client_list_find_by_ip(ip))) { 516 if ( p1->counters.incoming< counter) {517 p1->counters.incoming = counter;516 if ((p1->counters.incoming - p1->counters.incoming_history) < counter) { 517 p1->counters.incoming = p1->counters.incoming_history + counter; 518 518 debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter); 519 519 } trunk/wifidog/src/gateway.c
r763 r765 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 /* If we don't have the Gateway IP address, get it. Can't fail. */ 192 if (!config->gw_address) { 193 debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); 194 if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { 195 debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); 196 exit(1); 197 } 198 debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); 199 } 363 /* If we don't have the Gateway IP address, get it. Can't fail. */ 364 if (!config->gw_address) { 365 debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); 366 if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { 367 debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); 368 exit(1); 369 } 370 debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); 371 } 200 372 201 373 /* If we don't have the Gateway ID, construct it from the internal MAC address. Can't fail. */ … … 210 382 211 383 /* Initializes the web server */ 212 debug(LOG_NOTICE, "Creating web server on %s:%d", 213 config->gw_address, config->gw_port); 214 webserver = httpdCreate(config->gw_address, config->gw_port); 215 if (webserver == NULL) { 216 debug(LOG_ERR, "Could not create web server: %s", 217 strerror(errno)); 384 debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); 385 if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { 386 debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); 218 387 exit(1); 219 388 } 389 220 390 debug(LOG_DEBUG, "Assigning callbacks to web server"); 221 391 httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog); … … 226 396 httpdAddC404Content(webserver, http_callback_404); 227 397 228 /* Init the signals to catch chld/quit/etc */229 init_signals();230 231 398 /* Reset the firewall (if WiFiDog crashed) */ 232 399 fw_destroy(); 400 /* Then initialize it */ 233 401 fw_init(); 234 402 … … 280 448 * We got a connection 281 449 * 282 * We should forkanother thread450 * We should create another thread 283 451 */ 284 452 debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); … … 307 475 308 476 /** Reads the configuration file and then starts the main loop */ 309 int 310 main(int argc, char **argv) 311 { 477 int main(int argc, char **argv) { 478 312 479 s_config *config = config_get_config(); 313 480 config_init(); … … 315 482 parse_commandline(argc, argv); 316 483 484 /* Initialize the config */ 317 485 config_read(config->configfile); 318 486 config_validate(); 319 487 488 /* Initializes the linked list of connected clients */ 489 client_list_init(); 490 491 /* Init the signals to catch chld/quit/etc */ 492 init_signals(); 493 494 if (restarted) { 495 /* 496 * We were restarted and our parent is waiting for us to talk to it over the socket 497 */ 498 get_clients_from_parent(); 499 500 /* 501 * At this point the parent will start destroying itself and the firewall. Let it finish it's job before we continue 502 */ 503 while (kill(restarted, 0) != -1) { 504 debug(LOG_INFO, "Waiting for parent PID %d to die before continuing loading", restarted); 505 sleep(1); 506 } 507 508 debug(LOG_INFO, "Parent PID %d seems to be dead. Continuing loading."); 509 } 510 320 511 if (config->daemon) { 321 512 322 513 debug(LOG_INFO, "Forking into background"); 323 514 324 switch(fork()) { 325 case -1: /* error */ 326 debug(LOG_ERR, "fork(): %s", strerror(errno)); 327 exit(1); 328 break; 329 330 case 0: /* parent */ 331 main_loop(); 332 break; 333 334 default: /* child */ 335 exit(0); 336 break; 337 } 338 } else { 515 switch(safe_fork()) { 516 case 0: /* child */ 517 setsid(); 518 append_x_restartargv(); 519 main_loop(); 520 break; 521 522 default: /* parent */ 523 exit(0); 524 break; 525 } 526 } 527 else { 528 append_x_restartargv(); 339 529 main_loop(); 340 530 } trunk/wifidog/src/safe.c
r467 r765 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 trunk/wifidog/src/safe.h
r467 r765 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 trunk/wifidog/src/util.c
r763 r765 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) { /* for the child process
