Remove accidental file 'tatus'

ODNADev 2025-08-04 13:46:43 +05:30
parent 5713e6f88b
commit 2118fb3b55
1 changed files with 0 additions and 370 deletions

370
tatus
View File

@ -1,370 +0,0 @@
diff --git a/src/lcpex/liblcpex.cpp b/src/lcpex/liblcpex.cpp
index b0e033e..db79c19 100644
--- a/src/lcpex/liblcpex.cpp
+++ b/src/lcpex/liblcpex.cpp
@@ -1,5 +1,69 @@
#include "liblcpex.h"
+#include <cstring>
+#include <stdexcept>
+#include <signal.h>
+#include <string>
+#include "../logger/Logger.h"
+#include "FileHandle.h"
+#define BUFFER_SIZE 1024
+
+
+// Initialize logger
+static Logger logger(E_INFO, "lcpex");
+std::string user = logger.get_user_name();
+std::string group = logger.get_group_name();
+
+void signal_handler(int sig) {
+ std::string command = "signal_handler"; // Command context
+
+ // Create an instance of Logger (you can change the log level and mask accordingly)
+ // Log the signal handling
+ if (sig == SIGCHLD) {
+ // Log that SIGCHLD was received, but leave the exit status to the parent
+ logger.log_to_json_file("E_INFO", "SIGCHLD received. A child process ended.", user, group, command);
+ } else if (sig == SIGINT) {
+ logger.log_to_json_file("E_FATAL", "SIGINT received. Gracefully terminating...", user, group, command);
+ } else if (sig == SIGTERM) {
+ logger.log_to_json_file("E_FATAL", "SIGTERM received. Terminating...", user, group, command);
+ } else if (sig == SIGSEGV) {
+ logger.log_to_json_file("E_FATAL", "SIGSEGV received. Possible segmentation fault.", user, group, command);
+ } else {
+ logger.log_to_json_file("E_FATAL", "Unhandled signal received", user, group, command);
+ }
+}
+
+// Setup signal registrations
+void setup_signal_handlers() {
+ struct sigaction sa;
+ sa.sa_handler = signal_handler; // <-- handler function
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
+ std::string command = "setup_signal_handlers"; // Command context
+
+ // SIGCHLD
+ if (sigaction(SIGCHLD, &sa, nullptr) == -1) {
+ std::string error_message = "Failed to set SIGCHLD handler: " + std::string(strerror(errno));
+ logger.log_to_json_file("E_FATAL", error_message, user, group, command); // Log to JSON file
+ }
+
+ // SIGINT
+ if (sigaction(SIGINT, &sa, nullptr) == -1) {
+ std::string error_message = "Failed to set SIGINT handler: " + std::string(strerror(errno));
+ logger.log_to_json_file("E_FATAL", error_message, user, group, command); // Log to JSON file
+ }

+ // SIGTERM
+ if (sigaction(SIGTERM, &sa, nullptr) == -1) {
+ std::string error_message = "Failed to set SIGTERM handler: " + std::string(strerror(errno));
+ logger.log_to_json_file("E_FATAL", error_message, user, group, command); // Log to JSON file
+ }
+
+ // SIGSEGV
+ if (sigaction(SIGSEGV, &sa, nullptr) == -1) {
+ std::string error_message = "Failed to set SIGSEGV handler: " + std::string(strerror(errno));
+ logger.log_to_json_file("E_FATAL", error_message, user, group, command); // Log to JSON file
+ }
+}

std::string prefix_generator(
std::string command,
@@ -37,8 +101,12 @@ std::string prefix_generator(
// it's not a shell command, so we can just execute it directly
prefix = command;
}
- std::cout << "LAUNCHER: " << prefix << std::endl;
+
+ // Log the message to JSON file
+ logger.log_to_json_file("E_INFO", "LAUNCHER: " + prefix, user, group, command);
+ //logger.log(E_INFO, "LAUNCHER: " + prefix);
return prefix;
+
}


@@ -69,6 +137,7 @@ int lcpex(
environment_file_path
);
command = prefix;
+ setup_signal_handlers();

// if we are forcing a pty, then we will use the vpty library
if( force_pty )
@@ -91,10 +160,14 @@ int lcpex(
*/
void set_cloexec_flag(int fd)
{
+ std::string command = "set_cloexec_flag";
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
{
- perror("fcntl");
- exit(1);
+ std::string error_message = "fcntl(F_SETFD) failed for fd " + std::to_string(fd);
+
+ logger.log_to_json_file("E_FATAL", error_message, user, group, command);
+
+ throw std::runtime_error("fcntl(F_SETFD) failed for fd " + std::to_string(fd));
}
}

@@ -125,6 +198,13 @@ void set_cloexec_flag(int fd)
void run_child_process(bool context_override, const char* context_user, const char* context_group, char* processed_command[], int fd_child_stdout_pipe[], int fd_child_stderr_pipe[]) {
while ((dup2(fd_child_stdout_pipe[WRITE_END], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
while ((dup2(fd_child_stderr_pipe[WRITE_END], STDERR_FILENO) == -1) && (errno == EINTR)) {}
+ // Close unused pipe ends to avoid leaks
+
+ close(fd_child_stdout_pipe[READ_END]);
+ close(fd_child_stdout_pipe[WRITE_END]);
+ close(fd_child_stderr_pipe[READ_END]);
+ close(fd_child_stderr_pipe[WRITE_END]);
+ std::string command = "run_child_process"; // Command context

if ( context_override ) {
int context_result = set_identity_context(context_user, context_group);
@@ -132,34 +212,38 @@ void run_child_process(bool context_override, const char* context_user, const ch
case IDENTITY_CONTEXT_ERRORS::ERROR_NONE:
break;
case IDENTITY_CONTEXT_ERRORS::ERROR_NO_SUCH_USER:
- std::cerr << "REX: Aborting: context user not found: " << context_user << std::endl;
- exit(1);
+ logger.log(E_FATAL, "Aborting: context user not found: " + std::string(context_user));
+ logger.log_to_json_file("E_FATAL", "Aborting: context user not found: " + std::string(context_user), user, group, command);
+ _exit(1);
break;
case IDENTITY_CONTEXT_ERRORS::ERROR_NO_SUCH_GROUP:
- std::cerr << "REX: Aborting: context group not found: " << context_group << std::endl;
- exit(1);
+ logger.log(E_FATAL, "Aborting: context group not found: " + std::string(context_group));
+ logger.log_to_json_file("E_FATAL", "Aborting: context group not found: " + std::string(context_group), user, group, command);
+ _exit(1);
break;
case IDENTITY_CONTEXT_ERRORS::ERROR_SETGID_FAILED:
- std::cerr << "REX: Aborting: Setting GID failed: " << context_user << "/" << context_group << std::endl;
- exit(1);
+ logger.log(E_FATAL, "Aborting: Setting GID failed: " + std::string(context_user) + "/" + std::string(context_group));
+ logger.log_to_json_file("E_FATAL", "Aborting: Setting GID failed: " + std::string(context_user) + "/" + std::string(context_group), user, group, command);
+ _exit(1);
break;
case IDENTITY_CONTEXT_ERRORS::ERROR_SETUID_FAILED:
- std::cerr << "REX: Aborting: Setting UID failed: " << context_user << "/" << context_group << std::endl;
- exit(1);
+ logger.log(E_FATAL, "Aborting: Setting UID failed: " + std::string(context_user) + "/" + std::string(context_group));
+ logger.log_to_json_file("E_FATAL", "Aborting: Setting UID failed: " + std::string(context_user) + "/" + std::string(context_group), user, group, command);
+ _exit(1);
break;
default:
- std::cerr << "REX: Aborting: Unknown error while setting identity context." << std::endl;
- exit(1);
+ logger.log(E_FATAL, "Aborting: Unknown error while setting identity context.");
+ logger.log_to_json_file("E_FATAL", "Aborting: Unknown error while setting identity context.", user, group, command);
+ _exit(1);
break;
}
}
-
int exit_code = execvp(processed_command[0], processed_command);
- perror("failed on execvp in child");
- exit(exit_code);
+ logger.log_to_json_file("E_FATAL", "failed on execvp in child", user, group, command);
+ logger.log(E_FATAL, "failed on execvp in child");
+ _Exit(exit_code);
}

-
int execute(
std::string command,
FILE * stdout_log_fh,
@@ -169,6 +253,8 @@ int execute(
std::string context_group,
bool environment_supplied
){
+
+ try {
// this does three things:
// - execute a dang string as a subprocess command
// - capture child stdout/stderr to respective log files
@@ -190,13 +276,13 @@ int execute(
int fd_child_stderr_pipe[2];

if ( pipe(fd_child_stdout_pipe ) == -1 ) {
- perror( "child stdout pipe" );
- exit( 1 );
+ throw std::runtime_error("Failed to create stdout pipe");
}

if ( pipe( fd_child_stderr_pipe ) == -1 ) {
- perror( "child stderr pipe" );
- exit( 1 );
+ close(fd_child_stdout_pipe[0]);
+ close(fd_child_stdout_pipe[1]);
+ throw std::runtime_error("Failed to create stderr pipe");
}

// using O_CLOEXEC to ensure that the child process closes the file descriptors
@@ -206,15 +292,20 @@ int execute(
set_cloexec_flag( fd_child_stderr_pipe[WRITE_END] );

// status result basket for the parent process to capture the child's exit status
- int status = 616;
+ int status;
pid_t pid = fork();

switch( pid ) {
case -1:
{
// fork failed
- perror("fork failure");
- exit(1);
+ logger.log(E_FATAL, "fork failure: " + std::string(strerror(errno)));
+ logger.log_to_json_file("E_FATAL", "fork failure: " + std::string(strerror(errno)), user, group, command);
+ close(fd_child_stdout_pipe[0]); // Pipe Leaks on Error Paths
+ close(fd_child_stdout_pipe[1]); // Pipe Leaks on Error Paths
+ close(fd_child_stderr_pipe[0]); // Pipe Leaks on Error Paths
+ close(fd_child_stderr_pipe[1]); // Pipe Leaks on Error Paths
+ throw std::runtime_error("fork() failed: " + std::string(strerror(errno)));
}

case 0:
@@ -234,14 +325,23 @@ int execute(
{
// parent process

+ FdGuard stdout_read_guard(fd_child_stdout_pipe[READ_END]);
+ FdGuard stderr_read_guard(fd_child_stderr_pipe[READ_END]);
+ FdGuard stdout_write_guard(fd_child_stdout_pipe[WRITE_END]);
+ FdGuard stderr_write_guard(fd_child_stderr_pipe[WRITE_END]);
+
+ // We don't need WRITE_ENDs in parent, close them now
+ stdout_write_guard.reset(); // Closes and sets fd to -1
+ stderr_write_guard.reset();
+
// The parent process has no need to access the entrance to the pipe, so fd_child_*_pipe[1|0] should be closed
// within that process too:
- close(fd_child_stdout_pipe[WRITE_END]);
- close(fd_child_stderr_pipe[WRITE_END]);

- // attempt to write to stdout,stderr from child as well as to write each to file
- char buf[BUFFER_SIZE];

+ // attempt to write to stdout,stderr from child as well as to write each to file
+ char buf[BUFFER_SIZE] = {0};
+ std::strncpy(buf, command.c_str(), BUFFER_SIZE - 1);
+ buf[BUFFER_SIZE - 1] = '\0';
// contains the byte count of the last read from the pipe
ssize_t byte_count;

@@ -251,11 +351,11 @@ int execute(
// populate the watched_fds array

// child STDOUT to parent
- watched_fds[CHILD_PIPE_NAMES::STDOUT_READ].fd = fd_child_stdout_pipe[READ_END];
+ watched_fds[CHILD_PIPE_NAMES::STDOUT_READ].fd = stdout_read_guard.get();
watched_fds[CHILD_PIPE_NAMES::STDOUT_READ].events = POLLIN;

// child STDERR to parent
- watched_fds[CHILD_PIPE_NAMES::STDERR_READ].fd = fd_child_stderr_pipe[READ_END];
+ watched_fds[CHILD_PIPE_NAMES::STDERR_READ].fd = stderr_read_guard.get();
watched_fds[CHILD_PIPE_NAMES::STDERR_READ].events = POLLIN;

// number of files poll() reports as ready
@@ -275,8 +375,9 @@ int execute(

if (num_files_readable == -1) {
// error occurred in poll()
- perror("poll");
- exit(1);
+ logger.log(E_FATAL, "poll() failed: " + std::string(strerror(errno)));
+ logger.log_to_json_file("E_FATAL", "poll() failed", user, group, command);
+ throw std::runtime_error("poll() failed");
}
if (num_files_readable == 0) {
// poll reports no files readable
@@ -291,7 +392,10 @@ int execute(
if (byte_count == -1) {
if (errno == EAGAIN) { continue; } else {
// error reading from pipe
- perror("read");
+ logger.log(E_FATAL, "Error while reading: " + std::string(strerror(errno)));
+ logger.log_to_json_file("E_FATAL", "Error while reading from pipe", user, group, command);
+ stdout_read_guard.reset(-1);
+ stderr_read_guard.reset(-1);
exit(EXIT_FAILURE);
}

@@ -312,13 +416,17 @@ int execute(
write_all(STDERR_FILENO, buf, byte_count);
} else {
// this should never happen
- perror("Logic error!");
+ logger.log(E_FATAL, "Logic error: unexpected pipe index.");
exit(EXIT_FAILURE);
}
}
}
if (watched_fds[this_fd].revents & POLLERR) {
- close(watched_fds[this_fd].fd);
+ if (this_fd == CHILD_PIPE_NAMES::STDOUT_READ) {
+ stdout_read_guard.reset(-1);
+ } else if (this_fd == CHILD_PIPE_NAMES::STDERR_READ) {
+ stderr_read_guard.reset(-1);
+ }
break_out = true;
}
if (watched_fds[this_fd].revents & POLLHUP) {
@@ -333,21 +441,46 @@ int execute(
waitpid(pid, &status, 0);

// Drain the pipes before exiting
- while ((byte_count = read(fd_child_stdout_pipe[READ_END], buf, BUFFER_SIZE)) > 0) {
+ while ((byte_count = read(stdout_read_guard.get(), buf, BUFFER_SIZE)) > 0) {
write_all(stdout_log_fh->_fileno, buf, byte_count);
write_all(STDOUT_FILENO, buf, byte_count);
}
- while ((byte_count = read(fd_child_stderr_pipe[READ_END], buf, BUFFER_SIZE)) > 0) {
+ while ((byte_count = read(stderr_read_guard.get(), buf, BUFFER_SIZE)) > 0) {
write_all(stderr_log_fh->_fileno, buf, byte_count);
write_all(STDERR_FILENO, buf, byte_count);
}

- if WIFEXITED(status) {
- return WEXITSTATUS(status);
- } else {
- return -617;
+ int status;
+ pid_t pid = waitpid(-1, &status, WNOHANG); // Non-blocking wait for child process
+ if (pid > 0) { // If a child process has terminated
+ // Check if the child process exited normally
+ if (WIFEXITED(status)) {
+ int exit_code = WEXITSTATUS(status);
+ logger.log(E_INFO, "Child exited with status " + std::to_string(exit_code));
+ logger.log_to_json_file("E_INFO", "Child exited with status " + std::to_string(exit_code), user, group, command);
+ }
+ // Check if the child process was terminated by a signal
+ else if (WIFSIGNALED(status)) {
+ int signal_number = WTERMSIG(status);
+ logger.log(E_FATAL, "Process terminated by signal: " + std::to_string(signal_number));
+ logger.log_to_json_file("E_FATAL", "Process terminated by signal: " + std::to_string(signal_number), user, group, command);
+ // Reset signal handler to default before exiting
+ signal(signal_number, SIG_DFL);
+ // Return 128 + signal number as the exit code for signal termination
+ return 128 + signal_number; // POSIX exit code format
+ }
+ // Handle unexpected exit conditions
+ else {
+ logger.log(E_WARN, "Unknown child exit condition.");
+ logger.log_to_json_file("E_WARN", "Unknown child exit condition", user, group, command);
+ }
}
}
}
+ return 0;
+ } catch (const std::exception& ex) {
+ std::cerr << "[LCPEX ERROR] " << ex.what() << std::endl;
+ return -999;
+}
}