Skip to content

Commit 0b0ede5

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

File tree

4 files changed

+68
-89
lines changed

4 files changed

+68
-89
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/lib.misc.cc

Lines changed: 42 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,91 +7,83 @@
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

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

45+
int pipe_fd[3][2];
5246
/* 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;
47+
for(int i=0; i<3; i++) {
48+
if ( stdio_fd[i]==FDREDIR_PIPE && pipe(pipe_fd[i])!=0 ) return -1;
5549
}
5650

51+
pid_t child_pid;
5752
switch ( child_pid = fork() ) {
5853
case -1: /* error */
59-
free(argv);
6054
return -1;
6155

6256
case 0: /* child process */
6357
/* Connect pipes to command stdin/stdout/stderr and close unneeded fd's */
64-
for(i=0; i<3; i++) {
58+
for(int i=0; i<3; i++) {
6559
if ( stdio_fd[i]==FDREDIR_PIPE ) {
6660
/* stdin must be connected to the pipe output,
6761
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;
62+
const int dir = (i==0 ? PIPE_OUT : PIPE_IN);
63+
if ( dup2(pipe_fd[i][dir],def_stdio_fd[i])<0 ) return -1;
64+
if ( close(pipe_fd[i][dir])!=0 ) return -1;
65+
if ( close(pipe_fd[i][1-dir])!=0 ) return -1;
7266
}
7367
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;
68+
if ( dup2(stdio_fd[i],def_stdio_fd[i])<0 ) return -1;
69+
if ( close(stdio_fd[i])!=0 ) return -1;
7670
}
7771
}
7872
/* Redirect stderr to stdout */
79-
if ( err2out && dup2(STDOUT_FILENO,STDERR_FILENO)<0 ) goto ret_error;
73+
if ( err2out && dup2(STDOUT_FILENO,STDERR_FILENO)<0 ) return -1;
8074

8175
/* Replace child with command */
82-
execvp(cmd,argv);
76+
execvp(cmd.c_str(), argv.data());
8377
abort();
8478

8579
default: /* parent process */
8680

87-
free(argv);
88-
8981
/* Set and close file descriptors */
90-
for(i=0; i<3; i++) {
82+
for(int i=0; i<3; i++) {
9183
if ( stdio_fd[i]==FDREDIR_PIPE ) {
9284
/* parent process output must connect to the input of
9385
the pipe to child, and vice versa for stdout/stderr: */
94-
dir = (i==0 ? PIPE_IN : PIPE_OUT);
86+
const int dir = (i==0 ? PIPE_IN : PIPE_OUT);
9587
stdio_fd[i] = pipe_fd[i][dir];
9688
if ( close(pipe_fd[i][1-dir])!=0 ) return -1;
9789
}
@@ -101,6 +93,8 @@ int execute(const char *cmd, const char **args, int nargs, int stdio_fd[3], int
10193
if ( redirect ) return child_pid;
10294

10395
/* Wait for the child command to finish */
96+
int status;
97+
pid_t pid;
10498
while ( (pid = wait(&status))!=-1 && pid!=child_pid );
10599
if ( pid!=child_pid ) return -1;
106100

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

116110
/* This should never be reached */
117111
return -2;
118-
119-
/* Handle resources before returning on error */
120-
ret_error:
121-
free(argv);
122-
return -1;
123112
}
124113

125114

126115
void version(const char *prog, const char *vers)
127116
{
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);
117+
std::cout << prog << " -- part of DOMjudge version " << vers << std::endl
118+
<< "Written by the DOMjudge developers" << std::endl << std::endl
119+
<< "DOMjudge comes with ABSOLUTELY NO WARRANTY. This is free software, and you" << std::endl
120+
<< "are welcome to redistribute it under certain conditions. See the GNU" << std::endl
121+
<< "General Public Licence for details." << std::endl;
134122
exit(0);
135-
}
123+
}

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+
* const std::string& cmd command to be executed (PATH is searched)
27+
* const std::vector<std::string>& args vector of arguments to command
28+
* std::array<int, 3>& 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+
* bool 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)