Fix tunnel close message issue when wsscp is interrupted

- Added SIGINT signal handler to wsscp.c for proper signal handling
- Modified execute_scp_command() to fork/exec instead of using system()
- Added process tracking with scp_pid global variable
- Signal handler sends SIGTERM to SCP process when Ctrl+C is received
- Added proper cleanup and exit code handling for interrupted transfers
- Ensures wsssht (ProxyCommand) gets time to send tunnel_close message
- Prevents orphaned processes and ensures clean tunnel closure

This resolves the issue where Ctrl+C on wsscp didn't allow the underlying wsssht process to send tunnel_close messages to the server.
parent 873872d7
...@@ -317,8 +317,6 @@ def main(): ...@@ -317,8 +317,6 @@ def main():
"""Entry point for the server""" """Entry point for the server"""
try: try:
asyncio.run(run_server()) asyncio.run(run_server())
except KeyboardInterrupt:
print("\nServer interrupted by user")
except Exception as e: except Exception as e:
print(f"Server error: {e}") print(f"Server error: {e}")
sys.exit(1) sys.exit(1)
\ No newline at end of file
...@@ -33,9 +33,23 @@ ...@@ -33,9 +33,23 @@
#include <sys/select.h> #include <sys/select.h>
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <signal.h>
#include "wsscp.h" #include "wsscp.h"
// Global variables for signal handling
volatile sig_atomic_t sigint_received = 0;
pid_t scp_pid = -1;
void sigint_handler(int sig __attribute__((unused))) {
sigint_received = 1;
// If we have an SCP process running, terminate it gracefully
if (scp_pid > 0) {
kill(scp_pid, SIGTERM);
}
}
void print_usage(const char *program_name) { void print_usage(const char *program_name) {
fprintf(stderr, "Usage: %s [options] source destination\n", program_name); fprintf(stderr, "Usage: %s [options] source destination\n", program_name);
fprintf(stderr, "WebSocket SCP Wrapper - SCP through WebSocket tunnels\n\n"); fprintf(stderr, "WebSocket SCP Wrapper - SCP through WebSocket tunnels\n\n");
...@@ -270,15 +284,43 @@ int execute_scp_command(char *command, int debug) { ...@@ -270,15 +284,43 @@ int execute_scp_command(char *command, int debug) {
printf("[DEBUG] Executing: %s\n", command); printf("[DEBUG] Executing: %s\n", command);
} }
// Execute the command // Fork and execute the command so we can track the process
int result = system(command); pid_t pid = fork();
if (pid == -1) {
if (result == -1) { perror("fork");
perror("system");
return 1; return 1;
} }
return WEXITSTATUS(result); if (pid == 0) {
// Child process: execute the command
execl("/bin/sh", "sh", "-c", command, NULL);
// If we get here, exec failed
perror("execl");
exit(1);
} else {
// Parent process: store the PID and wait for completion
scp_pid = pid;
int status;
if (waitpid(pid, &status, 0) == -1) {
perror("waitpid");
scp_pid = -1;
return 1;
}
scp_pid = -1; // Reset PID
if (WIFEXITED(status)) {
return WEXITSTATUS(status);
} else if (WIFSIGNALED(status)) {
if (debug) {
printf("[DEBUG] SCP process terminated by signal %d\n", WTERMSIG(status));
}
return 1;
}
return 1;
}
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
...@@ -316,6 +358,9 @@ int main(int argc, char *argv[]) { ...@@ -316,6 +358,9 @@ int main(int argc, char *argv[]) {
} }
} }
// Set up signal handler for SIGINT
signal(SIGINT, sigint_handler);
// Parse wsscp arguments // Parse wsscp arguments
if (!parse_wsscp_args(argc, argv, &config)) { if (!parse_wsscp_args(argc, argv, &config)) {
return 1; return 1;
...@@ -408,6 +453,14 @@ int main(int argc, char *argv[]) { ...@@ -408,6 +453,14 @@ int main(int argc, char *argv[]) {
result = execute_scp_command(scp_command, config.debug); result = execute_scp_command(scp_command, config.debug);
} }
// Check if we were interrupted
if (sigint_received) {
if (config.debug) {
printf("[DEBUG] SCP command was interrupted by SIGINT\n");
}
result = 130; // Standard exit code for SIGINT (128 + 2)
}
// Cleanup // Cleanup
free(proxy_command); free(proxy_command);
free(config.source_file); free(config.source_file);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment