This commit is contained in:
+43
-9
@@ -16,6 +16,26 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char* filename_from_path(const char* path) {
|
||||
const char* slash = strrchr(path, '/');
|
||||
return slash ? slash + 1 : path;
|
||||
}
|
||||
|
||||
static bool should_exclude_file(const Config* config, const char* filename) {
|
||||
for (int i = 0; i < config->exclude_count; i++) {
|
||||
if (glob_match(config->exclude_patterns[i], filename))
|
||||
return true;
|
||||
}
|
||||
if (config->include_count > 0) {
|
||||
for (int i = 0; i < config->include_count; i++) {
|
||||
if (glob_match(config->include_patterns[i], filename))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int receive_files(Config* config, int fd) {
|
||||
Status status;
|
||||
if (!receive_status(fd, &status))
|
||||
@@ -29,8 +49,10 @@ int receive_files(Config* config, int fd) {
|
||||
goto next;
|
||||
if (file == NULL && !skipped)
|
||||
return -1;
|
||||
if (config->save_to_disk)
|
||||
file_save_to_disk(config->receive_root_directory, file);
|
||||
if (config->save_to_disk) {
|
||||
if (!should_exclude_file(config, filename_from_path(file->path)))
|
||||
file_save_to_disk(config->receive_root_directory, file);
|
||||
}
|
||||
file_destroy(file);
|
||||
} else if (status == STATUS_CHUNK) {
|
||||
Chunk* chunk = receive_chunk_data(fd, config);
|
||||
@@ -39,8 +61,10 @@ int receive_files(Config* config, int fd) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < chunk->element_count; i++) {
|
||||
if (config->save_to_disk)
|
||||
file_save_to_disk(config->receive_root_directory, chunk->items[i]);
|
||||
if (config->save_to_disk) {
|
||||
if (!should_exclude_file(config, filename_from_path(chunk->items[i]->path)))
|
||||
file_save_to_disk(config->receive_root_directory, chunk->items[i]);
|
||||
}
|
||||
}
|
||||
chunk_destroy(chunk);
|
||||
} else {
|
||||
@@ -50,8 +74,10 @@ int receive_files(Config* config, int fd) {
|
||||
send_status(fd, STATUS_ERROR);
|
||||
return -1;
|
||||
}
|
||||
if (config->save_to_disk)
|
||||
file_save_to_disk(config->receive_root_directory, file);
|
||||
if (config->save_to_disk) {
|
||||
if (!should_exclude_file(config, filename_from_path(file->path)))
|
||||
file_save_to_disk(config->receive_root_directory, file);
|
||||
}
|
||||
file_destroy(file);
|
||||
}
|
||||
next:
|
||||
@@ -112,13 +138,21 @@ void handler(int file_descriptor) {
|
||||
close(file_descriptor);
|
||||
}
|
||||
|
||||
/* Signal-safe flag: set by the signal handler, checked in main loop.
|
||||
* We cannot safely access g_server from the signal handler because it's
|
||||
* not sig_atomic_t. Instead, the handler sets this flag and calls _exit
|
||||
* (which is async-signal-safe). The server is fork-based (not threaded),
|
||||
* so g_server is only accessed from the main thread and cleanup() only
|
||||
* runs in the parent process — no concurrent access from children. */
|
||||
static volatile sig_atomic_t g_server_cleanup_requested = 0;
|
||||
static Server* g_server = NULL;
|
||||
|
||||
static void cleanup(int sig) {
|
||||
(void)sig;
|
||||
if (g_server) {
|
||||
server_delete(&g_server);
|
||||
}
|
||||
g_server_cleanup_requested = 1;
|
||||
/* _exit is async-signal-safe; we must not call server_delete() from a
|
||||
* signal handler (it may call non-async-signal-safe functions). The OS
|
||||
* will reclaim resources on exit. */
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user