Skip to content

Commit 02bf121

Browse files
committed
C++-ify lib.misc.cc.
1 parent 1230a48 commit 02bf121

File tree

5 files changed

+68
-85
lines changed

5 files changed

+68
-85
lines changed

judge/evict.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
#include <cstring>
1313
#include <cstdlib>
1414

15+
#include "lib.misc.h"
16+
1517
extern "C" {
1618
#include "lib.error.h"
17-
#include "lib.misc.h"
1819
}
1920

2021
#define PROGRAM "evict"

judge/runpipe.cc

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#include "lib.misc.h"
6767

6868
#include <algorithm>
69+
#include <array>
6970
#include <chrono>
7071
#include <csignal>
7172
#include <cstring>
@@ -232,22 +233,17 @@ struct process_t {
232233

233234
// Fork and exec the child process, redirecting its standard I/O.
234235
void spawn() {
235-
fd_t stdio[3] = {stdin_fd, stdout_fd, FDREDIR_NONE};
236-
237-
char pid_buf[12];
238-
vector<const char *> argv;
239-
for (size_t i = 0; i < args.size(); i++) {
240-
argv.push_back(args[i].c_str());
241-
if (i == 1 && cmd == "sudo" &&
242-
args[i].find("/runguard") != string::npos) {
236+
std::array<int, 3> stdio = {stdin_fd, stdout_fd, FDREDIR_NONE};
237+
238+
auto exec_args = args;
239+
if (cmd == "sudo" && exec_args.size() > 1 && exec_args[1].find("/runguard") != string::npos) {
243240
// This is a hack, and can be improved significantly after implementing
244241
// https://docs.google.com/document/d/1WZRwdvJUamsczYC7CpP3ZIBU8xG6wNqYqrNJf7osxYs/edit#heading=h.i7kgdnmw8qd7
245-
argv.push_back("-U");
246-
sprintf(pid_buf, "%d", getpid());
247-
argv.push_back(pid_buf);
248-
}
242+
exec_args.push_back("-U");
243+
exec_args.push_back(std::to_string(getpid()));
249244
}
250-
pid = execute(cmd.c_str(), argv.data(), argv.size(), stdio, 0);
245+
246+
pid = execute(cmd, exec_args, stdio, false);
251247
if (pid < 0) {
252248
error(errno, "failed to execute command #%ld", index);
253249
}

lib/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ endif
44

55
include $(TOPDIR)/Makefile.global
66

7-
OBJECTS = lib.error$(OBJEXT) lib.misc$(OBJEXT)
7+
OBJECTS = $(addsuffix $(OBJEXT),lib.error lib.misc)
88

99
build: $(OBJECTS)
1010

lib/lib.misc.cc

Lines changed: 41 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,91 +7,87 @@
77

88
#include "config.h"
99

10-
#include <stdlib.h>
10+
#include <cstdlib>
1111
#include <unistd.h>
12-
#include <string.h>
13-
#include <stdarg.h>
14-
#include <signal.h>
12+
#include <cstring>
13+
#include <cstdarg>
14+
#include <csignal>
1515
#include <sys/wait.h>
1616
#include <fcntl.h>
17+
#include <vector>
18+
#include <iostream>
1719

1820
#include "lib.misc.h"
1921
#include "lib.error.h"
2022

2123
/* Array indices for input/output file descriptors as used by pipe() */
22-
#define PIPE_IN 1
23-
#define PIPE_OUT 0
24+
constexpr int PIPE_IN = 1;
25+
constexpr int PIPE_OUT = 0;
2426

2527
const int def_stdio_fd[3] = { STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO };
2628

27-
int execute(const char *cmd, const char **args, int nargs, int stdio_fd[3], int err2out)
29+
int execute(const std::string& cmd, const std::vector<std::string>& args,
30+
std::array<int, 3>& stdio_fd, bool err2out)
2831
{
29-
pid_t pid, child_pid;
30-
int redirect;
31-
int status;
32-
int pipe_fd[3][2];
33-
char **argv;
34-
int i, dir;
35-
36-
if ( (argv=(char **) malloc((nargs+2)*sizeof(char *)))==NULL ) return -1;
37-
3832
if ( err2out ) stdio_fd[2] = FDREDIR_NONE;
3933

40-
redirect = ( stdio_fd[0]!=FDREDIR_NONE ||
41-
stdio_fd[1]!=FDREDIR_NONE ||
42-
stdio_fd[2]!=FDREDIR_NONE );
34+
const bool redirect = ( stdio_fd[0]!=FDREDIR_NONE ||
35+
stdio_fd[1]!=FDREDIR_NONE ||
36+
stdio_fd[2]!=FDREDIR_NONE );
4337

4438
/* Build the complete argument list for execvp.
4539
* We can const-cast the pointers, since execvp is guaranteed
4640
* not to modify these (or the data pointed to).
4741
*/
48-
argv[0] = (char *) cmd;
49-
for(i=0; i<nargs; i++) argv[i+1] = (char *) args[i];
50-
argv[nargs+1] = NULL;
42+
std::vector<char *> argv;
43+
argv.push_back(const_cast<char*>(cmd.c_str()));
44+
for (const auto& arg : args) {
45+
argv.push_back(const_cast<char*>(arg.c_str()));
46+
}
47+
argv.push_back(nullptr);
5148

49+
int pipe_fd[3][2];
5250
/* Open pipes for IO redirection */
53-
for(i=0; i<3; i++) {
54-
if ( stdio_fd[i]==FDREDIR_PIPE && pipe(pipe_fd[i])!=0 ) goto ret_error;
51+
for(int i=0; i<3; i++) {
52+
if ( stdio_fd[i]==FDREDIR_PIPE && pipe(pipe_fd[i])!=0 ) return -1;
5553
}
5654

55+
pid_t child_pid;
5756
switch ( child_pid = fork() ) {
5857
case -1: /* error */
59-
free(argv);
6058
return -1;
6159

6260
case 0: /* child process */
6361
/* Connect pipes to command stdin/stdout/stderr and close unneeded fd's */
64-
for(i=0; i<3; i++) {
62+
for(int i=0; i<3; i++) {
6563
if ( stdio_fd[i]==FDREDIR_PIPE ) {
6664
/* stdin must be connected to the pipe output,
6765
stdout/stderr to the pipe input: */
68-
dir = (i==0 ? PIPE_OUT : PIPE_IN);
69-
if ( dup2(pipe_fd[i][dir],def_stdio_fd[i])<0 ) goto ret_error;
70-
if ( close(pipe_fd[i][dir])!=0 ) goto ret_error;
71-
if ( close(pipe_fd[i][1-dir])!=0 ) goto ret_error;
66+
const int dir = (i==0 ? PIPE_OUT : PIPE_IN);
67+
if ( dup2(pipe_fd[i][dir],def_stdio_fd[i])<0 ) return -1;
68+
if ( close(pipe_fd[i][dir])!=0 ) return -1;
69+
if ( close(pipe_fd[i][1-dir])!=0 ) return -1;
7270
}
7371
if ( stdio_fd[i]>=0 ) {
74-
if ( dup2(stdio_fd[i],def_stdio_fd[i])<0 ) goto ret_error;
75-
if ( close(stdio_fd[i])!=0 ) goto ret_error;
72+
if ( dup2(stdio_fd[i],def_stdio_fd[i])<0 ) return -1;
73+
if ( close(stdio_fd[i])!=0 ) return -1;
7674
}
7775
}
7876
/* Redirect stderr to stdout */
79-
if ( err2out && dup2(STDOUT_FILENO,STDERR_FILENO)<0 ) goto ret_error;
77+
if ( err2out && dup2(STDOUT_FILENO,STDERR_FILENO)<0 ) return -1;
8078

8179
/* Replace child with command */
82-
execvp(cmd,argv);
80+
execvp(cmd.c_str(), argv.data());
8381
abort();
8482

8583
default: /* parent process */
8684

87-
free(argv);
88-
8985
/* Set and close file descriptors */
90-
for(i=0; i<3; i++) {
86+
for(int i=0; i<3; i++) {
9187
if ( stdio_fd[i]==FDREDIR_PIPE ) {
9288
/* parent process output must connect to the input of
9389
the pipe to child, and vice versa for stdout/stderr: */
94-
dir = (i==0 ? PIPE_IN : PIPE_OUT);
90+
const int dir = (i==0 ? PIPE_IN : PIPE_OUT);
9591
stdio_fd[i] = pipe_fd[i][dir];
9692
if ( close(pipe_fd[i][1-dir])!=0 ) return -1;
9793
}
@@ -101,6 +97,8 @@ int execute(const char *cmd, const char **args, int nargs, int stdio_fd[3], int
10197
if ( redirect ) return child_pid;
10298

10399
/* Wait for the child command to finish */
100+
int status;
101+
pid_t pid;
104102
while ( (pid = wait(&status))!=-1 && pid!=child_pid );
105103
if ( pid!=child_pid ) return -1;
106104

@@ -115,21 +113,15 @@ int execute(const char *cmd, const char **args, int nargs, int stdio_fd[3], int
115113

116114
/* This should never be reached */
117115
return -2;
118-
119-
/* Handle resources before returning on error */
120-
ret_error:
121-
free(argv);
122-
return -1;
123116
}
124117

125118

126119
void version(const char *prog, const char *vers)
127120
{
128-
printf("\
129-
%s -- part of DOMjudge version %s\n\
130-
Written by the DOMjudge developers\n\n\
131-
DOMjudge comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n\
132-
are welcome to redistribute it under certain conditions. See the GNU\n\
133-
General Public Licence for details.\n", prog, vers);
121+
std::cout << prog << " -- part of DOMjudge version " << vers << std::endl
122+
<< "Written by the DOMjudge developers" << std::endl << std::endl
123+
<< "DOMjudge comes with ABSOLUTELY NO WARRANTY. This is free software, and you" << std::endl
124+
<< "are welcome to redistribute it under certain conditions. See the GNU" << std::endl
125+
<< "General Public Licence for details." << std::endl;
134126
exit(0);
135127
}

lib/lib.misc.h

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
#ifndef LIB_MISC_H
66
#define LIB_MISC_H
77

8-
#ifdef __cplusplus
9-
extern "C" {
10-
#endif
8+
#include <string>
9+
#include <vector>
10+
#include <array>
1111

1212
/* I/O redirection options for execute() */
1313
#define FDREDIR_NONE -1
@@ -17,23 +17,22 @@ extern "C" {
1717
* LIBDIR as defined in calling program. */
1818
#define alert(msgtype,description) _alert(LIBDIR,msgtype,description)
1919

20-
int execute(const char *, const char **, int, int[3], int)
21-
__attribute__((nonnull (1, 2)));
20+
int execute(const std::string& cmd, const std::vector<std::string>& args,
21+
std::array<int, 3>& stdio_fd, bool err2out);
2222
/* Execute a subprocess using fork and execvp and optionally perform
2323
* IO redirection of stdin/stdout/stderr.
2424
*
2525
* Arguments:
26-
* char *cmd command to be executed (PATH is searched)
27-
* char *args[] array of arguments to command
28-
* int nargs number of arguments specified
29-
* int stdio_fd[3] File descriptors for stdin, stdout and stderr respectively.
30-
* Each can separately be set to one of the following:
31-
* FDREDIR_NONE - don't do redirection
32-
* FDREDIR_PIPE - connect to pipe and set value to file
33-
* descriptor of other end of the pipe
34-
* fd >= 0 - make this a duplicate of <fd>
35-
* int err2out Set non-zero to redirect command stderr to stdout. When set
36-
* the redirection of stderr by stdio_fd[2] is ignored.
26+
* cmd command to be executed (PATH is searched)
27+
* args vector of arguments to command
28+
* stdio_fd File descriptors for stdin, stdout and stderr respectively.
29+
* Each can separately be set to one of the following:
30+
* FDREDIR_NONE - don't do redirection
31+
* FDREDIR_PIPE - connect to pipe and set value to file
32+
* descriptor of other end of the pipe
33+
* fd >= 0 - make this a duplicate of <fd>
34+
* err2out Set to true to redirect command stderr to stdout. When set
35+
* the redirection of stderr by stdio_fd[2] is ignored.
3736
*
3837
* Returns:
3938
* 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)
4746
* with the process-ID of the child command.
4847
*/
4948

50-
5149
void version(const char *, const char *) __attribute__((nonnull (1, 2)));
5250
/* Print standard program name and version, with disclaimer and GPL
5351
* licence info. Arguments: program name and version strings.
5452
*/
5553

56-
#ifdef __cplusplus
57-
}
58-
#endif
59-
6054
#endif /* LIB_MISC_H */

0 commit comments

Comments
 (0)