Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/rtp2httpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ int worker_id = SUPERVISOR_WORKER_ID; /* Worker ID for this process (0-based) */
int main(int argc, char *argv[]) {
parse_cmd_line(argc, argv);

/* Initialize status tracking system (before fork, shared memory) */
/* Fatal: workers dereference status_shared without NULL checks; continuing
* would just SIGSEGV-loop the supervisor. */
if (status_init() != 0) {
logger(LOG_ERROR, "Failed to initialize status tracking");
/* Continue anyway - status page won't work but streaming will */
logger(LOG_FATAL, "Failed to initialize status tracking, exiting");
Comment thread
stackia marked this conversation as resolved.
return 1;
}

logger(LOG_INFO, "Starting rtp2httpd with %d worker(s)", config.workers);
Expand Down
27 changes: 22 additions & 5 deletions src/status.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,19 @@ static char shm_path[256] = {0};
int status_init(void) {
int fd;

/* Create shared memory file in /tmp */
/* PID-keyed path: EEXIST can only be a stale leftover from a prior instance
* with the same PID (no live process can hold our PID in this namespace),
* so unlink-and-retry is safe. */
snprintf(shm_path, sizeof(shm_path), "/tmp/rtp2httpd_status_%d", getpid());
fd = open(shm_path, O_CREAT | O_RDWR | O_EXCL, 0600);
if (fd == -1 && errno == EEXIST) {
logger(LOG_WARN, "Stale shared memory file %s found, removing and retrying", shm_path);
if (unlink(shm_path) == -1 && errno != ENOENT) {
logger(LOG_ERROR, "Failed to unlink stale shared memory file: %s", strerror(errno));
return -1;
}
fd = open(shm_path, O_CREAT | O_RDWR | O_EXCL, 0600);
Comment thread
stackia marked this conversation as resolved.
}
if (fd == -1) {
logger(LOG_ERROR, "Failed to create shared memory file: %s", strerror(errno));
return -1;
Expand All @@ -72,14 +82,20 @@ int status_init(void) {
return -1;
}

/* Map shared memory */
status_shared = mmap(NULL, sizeof(status_shared_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (status_shared == MAP_FAILED) {
logger(LOG_ERROR, "Failed to map shared memory: %s", strerror(errno));
/* Map shared memory.
* logger() probes status_shared with a NULL check, not a MAP_FAILED check,
* so we must reset to NULL before logging or any failure path that calls
* logger() will dereference (void*)-1. */
void *mapped = mmap(NULL, sizeof(status_shared_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mapped == MAP_FAILED) {
int err = errno;
status_shared = NULL;
logger(LOG_ERROR, "Failed to map shared memory: %s", strerror(err));
close(fd);
unlink(shm_path);
return -1;
}
status_shared = mapped;

/* Close file descriptor immediately after mmap()
* Per POSIX: "closing the file descriptor does not unmap the region"
Expand Down Expand Up @@ -114,6 +130,7 @@ int status_init(void) {
close(status_shared->worker_notification_pipes[j]);
}
munmap(status_shared, sizeof(status_shared_t));
status_shared = NULL;
unlink(shm_path);
return -1;
}
Expand Down
Loading