Skip to content

Commit 21876e8

Browse files
committed
Decouple safe.c from knowing anything about libhttpd
1 parent 2d5f45f commit 21876e8

File tree

3 files changed

+83
-17
lines changed

3 files changed

+83
-17
lines changed

src/gateway.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ main_loop(void)
391391
debug(LOG_ERR, "Could not create web server: %s", strerror(errno));
392392
exit(1);
393393
}
394+
register_fd_cleanup_on_fork(webserver->serverSock);
394395

395396
debug(LOG_DEBUG, "Assigning callbacks to web server");
396397
httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog);

src/safe.c

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,52 @@
3535
#include <errno.h>
3636
#include <syslog.h>
3737

38-
#include "httpd.h"
39-
#include "gateway.h"
4038
#include "safe.h"
4139
#include "debug.h"
4240

41+
/** @brief Clean up all the registered fds. */
42+
static void cleanup_fds(void);
43+
44+
/** List of fd's to close on fork. */
45+
typedef struct _fd_list {
46+
int fd; /**< @brief file descriptor */
47+
struct _fd_list *next; /**< @brief linked list pointer */
48+
} fd_list_t;
49+
50+
static fd_list_t *fd_list = NULL;
51+
52+
/** Clean up all the registered fds. Frees the list as it goes.
53+
* XXX This should only be run by CHILD processes.
54+
*/
55+
static void
56+
cleanup_fds(void)
57+
{
58+
fd_list_t *entry;
59+
60+
while (NULL != (entry = fd_list)) {
61+
close(entry->fd);
62+
fd_list = entry->next;
63+
free(entry);
64+
}
65+
}
66+
67+
/** Register an fd for auto-cleanup on fork()
68+
* @param fd A file descriptor.
69+
*/
70+
void
71+
register_fd_cleanup_on_fork(const int fd)
72+
{
73+
fd_list_t *entry = safe_malloc(sizeof(fd_list_t));
74+
75+
entry->fd = fd;
76+
entry->next = fd_list;
77+
fd_list = entry;
78+
}
79+
80+
/** Allocate zero-filled ram or die.
81+
* @param size Number of bytes to allocate
82+
* @return void * pointer to the zero'd bytes.
83+
*/
4384
void *
4485
safe_malloc(size_t size)
4586
{
@@ -53,6 +94,14 @@ safe_malloc(size_t size)
5394
return (retval);
5495
}
5596

97+
/** Re-allocates memory to a new larger allocation.
98+
* DOES NOT ZERO the added RAM
99+
* Original pointer is INVALID after call
100+
* Dies on allocation failures.
101+
* @param ptr A pointer to a current allocation from safe_malloc()
102+
* @param newsize What size it should now be in bytes
103+
* @return pointer to newly allocation ram
104+
*/
56105
void *
57106
safe_realloc(void *ptr, size_t newsize)
58107
{
@@ -65,6 +114,10 @@ safe_realloc(void *ptr, size_t newsize)
65114
return retval;
66115
}
67116

117+
/** Duplicates a string or die if memory cannot be allocated
118+
* @param s String to duplicate
119+
* @return A string in a newly allocated chunk of heap.
120+
*/
68121
char *
69122
safe_strdup(const char *s)
70123
{
@@ -81,6 +134,13 @@ safe_strdup(const char *s)
81134
return (retval);
82135
}
83136

137+
/** Sprintf into a newly allocated buffer
138+
* Memory MUST be freed. Dies if memory cannot be allocated.
139+
* @param strp Pointer to a pointer that will be set to the newly allocated string
140+
* @param fmt Format string like sprintf
141+
* @param ... Variable number of arguments for format string
142+
* @return int Size of allocated string.
143+
*/
84144
int
85145
safe_asprintf(char **strp, const char *fmt, ...)
86146
{
@@ -94,6 +154,13 @@ safe_asprintf(char **strp, const char *fmt, ...)
94154
return (retval);
95155
}
96156

157+
/** Sprintf into a newly allocated buffer
158+
* Memory MUST be freed. Dies if memory cannot be allocted.
159+
* @param strp Pointer to a pointer that will be set to the newly allocated string
160+
* @param fmt Format string like sprintf
161+
* @param ap pre-digested va_list of arguments.
162+
* @return int Size of allocated string.
163+
*/
97164
int
98165
safe_vasprintf(char **strp, const char *fmt, va_list ap)
99166
{
@@ -108,6 +175,10 @@ safe_vasprintf(char **strp, const char *fmt, va_list ap)
108175
return (retval);
109176
}
110177

178+
/** Fork and then close any registered fille descriptors.
179+
* If fork() fails, we die.
180+
* @return pid_t 0 for child, pid of child for parent
181+
*/
111182
pid_t
112183
safe_fork(void)
113184
{
@@ -119,10 +190,7 @@ safe_fork(void)
119190
exit(1);
120191
} else if (result == 0) {
121192
/* I'm the child - do some cleanup */
122-
if (webserver) {
123-
close(webserver->serverSock);
124-
webserver = NULL;
125-
}
193+
cleanup_fds();
126194
}
127195

128196
return result;

src/safe.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,25 @@
3232
#include <sys/types.h> /* For fork */
3333
#include <unistd.h> /* For fork */
3434

35-
/** @brief Safe version of malloc
36-
*/
35+
/** Register an fd for auto-cleanup on fork() */
36+
void register_fd_cleanup_on_fork(const int);
37+
38+
/** @brief Safe version of malloc */
3739
void *safe_malloc(size_t);
3840

3941
/** @brief Safe version of realloc */
4042
void *safe_realloc(void *, size_t);
4143

42-
/* @brief Safe version of strdup
43-
*/
44+
/* @brief Safe version of strdup */
4445
char *safe_strdup(const char *);
4546

46-
/* @brief Safe version of asprintf
47-
*/
47+
/* @brief Safe version of asprintf */
4848
int safe_asprintf(char **, const char *, ...);
4949

50-
/* @brief Safe version of vasprintf
51-
*/
50+
/* @brief Safe version of vasprintf */
5251
int safe_vasprintf(char **, const char *, va_list);
5352

54-
/* @brief Safe version of fork
55-
*/
56-
53+
/* @brief Safe version of fork */
5754
pid_t safe_fork(void);
5855

5956
#endif /* _SAFE_H_ */

0 commit comments

Comments
 (0)