From 9bd5fa62194651769ca09fc49d9b8a99ba837a7d Mon Sep 17 00:00:00 2001 From: Tobias Werth Date: Sun, 26 Oct 2025 13:20:58 +0100 Subject: [PATCH 1/4] Delete dead code from lib.misc.c. --- lib/lib.misc.c | 127 ------------------------------------------------- lib/lib.misc.h | 28 ----------- 2 files changed, 155 deletions(-) diff --git a/lib/lib.misc.c b/lib/lib.misc.c index c04e7c4003..2ce4253757 100644 --- a/lib/lib.misc.c +++ b/lib/lib.misc.c @@ -24,27 +24,6 @@ const int def_stdio_fd[3] = { STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO }; -void _alert(const char *libdir, const char *msgtype, const char *description) -{ - static char none[1] = ""; - char *cmd; - int silenced __attribute__((unused)); - - if ( description==NULL ) description = none; - - cmd = allocstr("%s/alert '%s' '%s' &",libdir,msgtype,description); - logmsg(LOG_INFO,"executing '%s'",cmd); - - /* Assign return value to temp variable to remove compiler - * warnings. We're already trying to generate a warning; there's - * no sense in generating another warning when this gives an - * error. - */ - silenced = system(cmd); - - free(cmd); -} - int execute(const char *cmd, const char **args, int nargs, int stdio_fd[3], int err2out) { pid_t pid, child_pid; @@ -143,112 +122,6 @@ int execute(const char *cmd, const char **args, int nargs, int stdio_fd[3], int return -1; } -int exitsignalled; - -void sig_handler(int sig) -{ - logmsg(LOG_DEBUG, "Signal %d received", sig); - - switch ( sig ) { - case SIGTERM: - case SIGHUP: - case SIGINT: - exitsignalled = 1; - break; - } -} - -void initsignals() -{ - struct sigaction sa; - sigset_t newmask, oldmask; - - exitsignalled = 0; - - /* unmask all signals */ - memset(&newmask, 0, sizeof(newmask)); - if ( sigprocmask(SIG_SETMASK, &newmask, &oldmask)!=0 ) { - error(errno,"unmasking signals"); - } - - logmsg(LOG_DEBUG, "Installing signal handlers"); - - sa.sa_handler = &sig_handler; - sa.sa_mask = newmask; - sa.sa_flags = 0; - - if ( sigaction(SIGTERM,&sa,NULL)!=0 ) error(errno,"installing signal handler"); - if ( sigaction(SIGHUP ,&sa,NULL)!=0 ) error(errno,"installing signal handler"); - if ( sigaction(SIGINT ,&sa,NULL)!=0 ) error(errno,"installing signal handler"); -} - - -char *pidfile; - -/* Function to remove PID file at process exit. */ -void remove_pidfile() -{ - unlink(pidfile); -} - -void daemonize(const char *_pidfile) -{ - pid_t pid; - int fd, maxfd; - char str[15]; - - switch ( pid = fork() ) { - case -1: error(errno, "cannot fork daemon"); - case 0: break; /* child process: do nothing here. */ - default: _exit(0); /* parent process: exit. */ - } - - /* Check and write PID to file */ - if ( _pidfile!=NULL ) { - pidfile = strdup(_pidfile); - if ( (fd=open(pidfile, O_RDWR|O_CREAT|O_EXCL, 0640))<0 ) { - error(errno, "cannot create pidfile '%s'", pidfile); - } - sprintf(str, "%d\n", pid); - if ( write(fd, str, strlen(str))<(ssize_t)strlen(str) ) { - error(errno, "failed writing PID to file"); - } - if ( close(fd)!=0 ) error(errno, "closing pidfile '%s'", pidfile); - atexit(remove_pidfile); - } - - /* Notify user with daemon PID before detaching from TTY. */ - logmsg(LOG_NOTICE, "daemonizing with PID = %d", pid); - - /* Reopen std{in,out,err} file descriptors to /dev/null. - Closing them gives error when the daemon or a child process - tries to read/write to them. */ - if ( freopen("/dev/null", "r", stdin )!=NULL || - freopen("/dev/null", "w", stdout)!=NULL || - freopen("/dev/null", "w", stderr)!=NULL ) { - error(errno, "cannot reopen stdio files to /dev/null"); - } - - /* Close all other file descriptors. */ - maxfd = sysconf(_SC_OPEN_MAX); - for(fd=3; fd Date: Sun, 26 Oct 2025 13:25:37 +0100 Subject: [PATCH 2/4] Reuse version function from lib.misc. --- judge/runguard.cc | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/judge/runguard.cc b/judge/runguard.cc index e7e3e590fb..460d2e680b 100644 --- a/judge/runguard.cc +++ b/judge/runguard.cc @@ -29,6 +29,8 @@ #include "config.h" +#include "lib.misc.h" + /* Some system/site specific config: VALID_USERS, CHROOT_PREFIX */ #include "runguard-config.h" @@ -346,17 +348,6 @@ void write_meta(const char *key, const char *format, ...) va_end(ap); } -void version(const char *prog, const char *vers) -{ - printf("\ -%s -- part of DOMjudge version %s\n\ -Written by the DOMjudge developers\n\n\ -DOMjudge comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n\ -are welcome to redistribute it under certain conditions. See the GNU\n\ -General Public Licence for details.\n", prog, vers); - exit(0); -} - void usage() { printf("\ From 1230a48fbb6be12b58d13dc0915df2a094b65f68 Mon Sep 17 00:00:00 2001 From: Tobias Werth Date: Sun, 26 Oct 2025 13:43:41 +0100 Subject: [PATCH 3/4] Make lib.misc compile as C++. --- Makefile.global | 3 +-- judge/Makefile | 12 ++++++------ lib/Makefile | 5 +++-- lib/{lib.misc.c => lib.misc.cc} | 0 4 files changed, 10 insertions(+), 10 deletions(-) rename lib/{lib.misc.c => lib.misc.cc} (100%) diff --git a/Makefile.global b/Makefile.global index a6d55daf80..bb094d4bb6 100644 --- a/Makefile.global +++ b/Makefile.global @@ -62,12 +62,11 @@ endef # Library objects required in multiple places: LIBSBASE = $(addprefix $(TOPDIR)/lib/,lib.error lib.misc) LIBHEADERS = $(addsuffix .h,$(LIBSBASE)) -LIBSOURCES = $(addsuffix .c,$(LIBSBASE)) LIBOBJECTS = $(addsuffix $(OBJEXT),$(LIBSBASE)) CFLAGS += -I$(TOPDIR)/lib -I$(TOPDIR)/etc CXXFLAGS += -I$(TOPDIR)/lib -I$(TOPDIR)/etc -$(LIBOBJECTS): %$(OBJEXT): %.c %.h +$(LIBOBJECTS): $(MAKE) -C $(TOPDIR)/lib $(notdir $@) # Default recursive targets; these should always at least call the diff --git a/judge/Makefile b/judge/Makefile index 7e3e4787d8..74b756a6b8 100644 --- a/judge/Makefile +++ b/judge/Makefile @@ -13,14 +13,14 @@ judgehost: $(TARGETS) $(SUBST_FILES) $(SUBST_FILES): %: %.in $(TOPDIR)/paths.mk $(substconfigvars) -evict: evict.cc $(LIBHEADERS) $(LIBSOURCES) - $(CXX) $(CXXFLAGS) -o $@ $< $(LIBSOURCES) +evict: evict.cc $(LIBOBJECTS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $< $(LIBOBJECTS) -runguard: runguard.cc $(LIBHEADERS) $(LIBSOURCES) $(TOPDIR)/etc/runguard-config.h - $(CXX) $(CXXFLAGS) -o $@ $< $(LIBSOURCES) $(LIBCGROUP) +runguard: runguard.cc $(LIBOBJECTS) $(TOPDIR)/etc/runguard-config.h + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $< $(LIBOBJECTS) $(LIBCGROUP) -runpipe: runpipe.cc $(LIBHEADERS) $(LIBSOURCES) - $(CXX) $(CXXFLAGS) -static -o $@ $< $(LIBSOURCES) +runpipe: runpipe.cc $(LIBOBJECTS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -static -o $@ $< $(LIBOBJECTS) install-judgehost: $(INSTALL_PROG) -t $(DESTDIR)$(judgehost_libjudgedir) \ diff --git a/lib/Makefile b/lib/Makefile index 238684c01f..1ccf42d117 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -4,11 +4,12 @@ endif include $(TOPDIR)/Makefile.global -OBJECTS = $(addsuffix $(OBJEXT),lib.error lib.misc) +OBJECTS = lib.error$(OBJEXT) lib.misc$(OBJEXT) build: $(OBJECTS) -$(OBJECTS): %$(OBJEXT): %.c %.h +lib.error$(OBJEXT): lib.error.c lib.error.h +lib.misc$(OBJEXT): lib.misc.cc lib.misc.h clean-l: rm -f $(OBJECTS) diff --git a/lib/lib.misc.c b/lib/lib.misc.cc similarity index 100% rename from lib/lib.misc.c rename to lib/lib.misc.cc From 02bf121f780dace338587d3692683c49c122fcbb Mon Sep 17 00:00:00 2001 From: Tobias Werth Date: Sun, 26 Oct 2025 14:23:23 +0100 Subject: [PATCH 4/4] C++-ify lib.misc.cc. --- judge/evict.cc | 3 +- judge/runpipe.cc | 22 +++++------- lib/Makefile | 2 +- lib/lib.misc.cc | 90 ++++++++++++++++++++++-------------------------- lib/lib.misc.h | 36 ++++++++----------- 5 files changed, 68 insertions(+), 85 deletions(-) diff --git a/judge/evict.cc b/judge/evict.cc index dc21f0b0ac..cdc1f1b103 100644 --- a/judge/evict.cc +++ b/judge/evict.cc @@ -12,9 +12,10 @@ #include #include +#include "lib.misc.h" + extern "C" { #include "lib.error.h" -#include "lib.misc.h" } #define PROGRAM "evict" diff --git a/judge/runpipe.cc b/judge/runpipe.cc index e57fd5b948..be48667d6b 100644 --- a/judge/runpipe.cc +++ b/judge/runpipe.cc @@ -66,6 +66,7 @@ #include "lib.misc.h" #include +#include #include #include #include @@ -232,22 +233,17 @@ struct process_t { // Fork and exec the child process, redirecting its standard I/O. void spawn() { - fd_t stdio[3] = {stdin_fd, stdout_fd, FDREDIR_NONE}; - - char pid_buf[12]; - vector argv; - for (size_t i = 0; i < args.size(); i++) { - argv.push_back(args[i].c_str()); - if (i == 1 && cmd == "sudo" && - args[i].find("/runguard") != string::npos) { + std::array stdio = {stdin_fd, stdout_fd, FDREDIR_NONE}; + + auto exec_args = args; + if (cmd == "sudo" && exec_args.size() > 1 && exec_args[1].find("/runguard") != string::npos) { // This is a hack, and can be improved significantly after implementing // https://docs.google.com/document/d/1WZRwdvJUamsczYC7CpP3ZIBU8xG6wNqYqrNJf7osxYs/edit#heading=h.i7kgdnmw8qd7 - argv.push_back("-U"); - sprintf(pid_buf, "%d", getpid()); - argv.push_back(pid_buf); - } + exec_args.push_back("-U"); + exec_args.push_back(std::to_string(getpid())); } - pid = execute(cmd.c_str(), argv.data(), argv.size(), stdio, 0); + + pid = execute(cmd, exec_args, stdio, false); if (pid < 0) { error(errno, "failed to execute command #%ld", index); } diff --git a/lib/Makefile b/lib/Makefile index 1ccf42d117..e608dbfba5 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -4,7 +4,7 @@ endif include $(TOPDIR)/Makefile.global -OBJECTS = lib.error$(OBJEXT) lib.misc$(OBJEXT) +OBJECTS = $(addsuffix $(OBJEXT),lib.error lib.misc) build: $(OBJECTS) diff --git a/lib/lib.misc.cc b/lib/lib.misc.cc index 2ce4253757..9a498001df 100644 --- a/lib/lib.misc.cc +++ b/lib/lib.misc.cc @@ -7,91 +7,87 @@ #include "config.h" -#include +#include #include -#include -#include -#include +#include +#include +#include #include #include +#include +#include #include "lib.misc.h" #include "lib.error.h" /* Array indices for input/output file descriptors as used by pipe() */ -#define PIPE_IN 1 -#define PIPE_OUT 0 +constexpr int PIPE_IN = 1; +constexpr int PIPE_OUT = 0; const int def_stdio_fd[3] = { STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO }; -int execute(const char *cmd, const char **args, int nargs, int stdio_fd[3], int err2out) +int execute(const std::string& cmd, const std::vector& args, + std::array& stdio_fd, bool err2out) { - pid_t pid, child_pid; - int redirect; - int status; - int pipe_fd[3][2]; - char **argv; - int i, dir; - - if ( (argv=(char **) malloc((nargs+2)*sizeof(char *)))==NULL ) return -1; - if ( err2out ) stdio_fd[2] = FDREDIR_NONE; - redirect = ( stdio_fd[0]!=FDREDIR_NONE || - stdio_fd[1]!=FDREDIR_NONE || - stdio_fd[2]!=FDREDIR_NONE ); + const bool redirect = ( stdio_fd[0]!=FDREDIR_NONE || + stdio_fd[1]!=FDREDIR_NONE || + stdio_fd[2]!=FDREDIR_NONE ); /* Build the complete argument list for execvp. * We can const-cast the pointers, since execvp is guaranteed * not to modify these (or the data pointed to). */ - argv[0] = (char *) cmd; - for(i=0; i argv; + argv.push_back(const_cast(cmd.c_str())); + for (const auto& arg : args) { + argv.push_back(const_cast(arg.c_str())); + } + argv.push_back(nullptr); + int pipe_fd[3][2]; /* Open pipes for IO redirection */ - for(i=0; i<3; i++) { - if ( stdio_fd[i]==FDREDIR_PIPE && pipe(pipe_fd[i])!=0 ) goto ret_error; + for(int i=0; i<3; i++) { + if ( stdio_fd[i]==FDREDIR_PIPE && pipe(pipe_fd[i])!=0 ) return -1; } + pid_t child_pid; switch ( child_pid = fork() ) { case -1: /* error */ - free(argv); return -1; case 0: /* child process */ /* Connect pipes to command stdin/stdout/stderr and close unneeded fd's */ - for(i=0; i<3; i++) { + for(int i=0; i<3; i++) { if ( stdio_fd[i]==FDREDIR_PIPE ) { /* stdin must be connected to the pipe output, stdout/stderr to the pipe input: */ - dir = (i==0 ? PIPE_OUT : PIPE_IN); - if ( dup2(pipe_fd[i][dir],def_stdio_fd[i])<0 ) goto ret_error; - if ( close(pipe_fd[i][dir])!=0 ) goto ret_error; - if ( close(pipe_fd[i][1-dir])!=0 ) goto ret_error; + const int dir = (i==0 ? PIPE_OUT : PIPE_IN); + if ( dup2(pipe_fd[i][dir],def_stdio_fd[i])<0 ) return -1; + if ( close(pipe_fd[i][dir])!=0 ) return -1; + if ( close(pipe_fd[i][1-dir])!=0 ) return -1; } if ( stdio_fd[i]>=0 ) { - if ( dup2(stdio_fd[i],def_stdio_fd[i])<0 ) goto ret_error; - if ( close(stdio_fd[i])!=0 ) goto ret_error; + if ( dup2(stdio_fd[i],def_stdio_fd[i])<0 ) return -1; + if ( close(stdio_fd[i])!=0 ) return -1; } } /* Redirect stderr to stdout */ - if ( err2out && dup2(STDOUT_FILENO,STDERR_FILENO)<0 ) goto ret_error; + if ( err2out && dup2(STDOUT_FILENO,STDERR_FILENO)<0 ) return -1; /* Replace child with command */ - execvp(cmd,argv); + execvp(cmd.c_str(), argv.data()); abort(); default: /* parent process */ - free(argv); - /* Set and close file descriptors */ - for(i=0; i<3; i++) { + for(int i=0; i<3; i++) { if ( stdio_fd[i]==FDREDIR_PIPE ) { /* parent process output must connect to the input of the pipe to child, and vice versa for stdout/stderr: */ - dir = (i==0 ? PIPE_IN : PIPE_OUT); + const int dir = (i==0 ? PIPE_IN : PIPE_OUT); stdio_fd[i] = pipe_fd[i][dir]; if ( close(pipe_fd[i][1-dir])!=0 ) return -1; } @@ -101,6 +97,8 @@ int execute(const char *cmd, const char **args, int nargs, int stdio_fd[3], int if ( redirect ) return child_pid; /* Wait for the child command to finish */ + int status; + pid_t pid; while ( (pid = wait(&status))!=-1 && pid!=child_pid ); if ( pid!=child_pid ) return -1; @@ -115,21 +113,15 @@ int execute(const char *cmd, const char **args, int nargs, int stdio_fd[3], int /* This should never be reached */ return -2; - - /* Handle resources before returning on error */ - ret_error: - free(argv); - return -1; } void version(const char *prog, const char *vers) { - printf("\ -%s -- part of DOMjudge version %s\n\ -Written by the DOMjudge developers\n\n\ -DOMjudge comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n\ -are welcome to redistribute it under certain conditions. See the GNU\n\ -General Public Licence for details.\n", prog, vers); + std::cout << prog << " -- part of DOMjudge version " << vers << std::endl + << "Written by the DOMjudge developers" << std::endl << std::endl + << "DOMjudge comes with ABSOLUTELY NO WARRANTY. This is free software, and you" << std::endl + << "are welcome to redistribute it under certain conditions. See the GNU" << std::endl + << "General Public Licence for details." << std::endl; exit(0); } diff --git a/lib/lib.misc.h b/lib/lib.misc.h index 7bc419c30d..c39009f3f1 100644 --- a/lib/lib.misc.h +++ b/lib/lib.misc.h @@ -5,9 +5,9 @@ #ifndef LIB_MISC_H #define LIB_MISC_H -#ifdef __cplusplus -extern "C" { -#endif +#include +#include +#include /* I/O redirection options for execute() */ #define FDREDIR_NONE -1 @@ -17,23 +17,22 @@ extern "C" { * LIBDIR as defined in calling program. */ #define alert(msgtype,description) _alert(LIBDIR,msgtype,description) -int execute(const char *, const char **, int, int[3], int) - __attribute__((nonnull (1, 2))); +int execute(const std::string& cmd, const std::vector& args, + std::array& stdio_fd, bool err2out); /* Execute a subprocess using fork and execvp and optionally perform * IO redirection of stdin/stdout/stderr. * * Arguments: - * char *cmd command to be executed (PATH is searched) - * char *args[] array of arguments to command - * int nargs number of arguments specified - * int stdio_fd[3] File descriptors for stdin, stdout and stderr respectively. - * Each can separately be set to one of the following: - * FDREDIR_NONE - don't do redirection - * FDREDIR_PIPE - connect to pipe and set value to file - * descriptor of other end of the pipe - * fd >= 0 - make this a duplicate of - * int err2out Set non-zero to redirect command stderr to stdout. When set - * the redirection of stderr by stdio_fd[2] is ignored. + * cmd command to be executed (PATH is searched) + * args vector of arguments to command + * stdio_fd File descriptors for stdin, stdout and stderr respectively. + * Each can separately be set to one of the following: + * FDREDIR_NONE - don't do redirection + * FDREDIR_PIPE - connect to pipe and set value to file + * descriptor of other end of the pipe + * fd >= 0 - make this a duplicate of + * err2out Set to true to redirect command stderr to stdout. When set + * the redirection of stderr by stdio_fd[2] is ignored. * * Returns: * On errors from system calls -1 is returned: check errno for extra information. @@ -47,14 +46,9 @@ int execute(const char *, const char **, int, int[3], int) * with the process-ID of the child command. */ - void version(const char *, const char *) __attribute__((nonnull (1, 2))); /* Print standard program name and version, with disclaimer and GPL * licence info. Arguments: program name and version strings. */ -#ifdef __cplusplus -} -#endif - #endif /* LIB_MISC_H */