Skip to content
This repository was archived by the owner on May 24, 2020. It is now read-only.

Commit 4948664

Browse files
committed
Split subprocess API into util/
1 parent 1575cd3 commit 4948664

File tree

4 files changed

+87
-38
lines changed

4 files changed

+87
-38
lines changed

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,6 @@ eclean_kernel_SOURCES = \
5353
src/ek2/util/error.h \
5454
src/ek2/util/relativepath.cxx \
5555
src/ek2/util/relativepath.h \
56+
src/ek2/util/subprocess.cxx \
57+
src/ek2/util/subprocess.h \
5658
src/main.cxx

src/ek2/bootloaders/grub2.cxx

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "ek2/util/directorystream.h"
1313
#include "ek2/util/error.h"
1414
#include "ek2/util/relativepath.h"
15+
#include "ek2/util/subprocess.h"
1516

1617
#include <cerrno>
1718
#include <cstring>
@@ -23,7 +24,6 @@ extern "C"
2324
{
2425
# include <fcntl.h>
2526
# include <unistd.h>
26-
# include <sys/wait.h>
2727
};
2828

2929
static const char grub2_autogen_header[] =
@@ -115,51 +115,19 @@ void GRUB2::postrm()
115115
// we should update it
116116
if (is_autogenerated_)
117117
{
118-
// TODO: move this to util/
119-
// love the C exec*() API
120-
std::vector<std::string> argv{"grub-mkconfig",
118+
std::vector<std::string> argv{
121119
is_multislot_ ? "grub2-mkconfig" : "grub-mkconfig",
122120
"-o", grub_cfg_->path()};
123-
std::vector<std::vector<char>> argv_rw;
124-
std::vector<char*> cargv;
125121

126122
if (opts_.pretend)
127123
{
128124
std::cerr << "\nThe following command would be run: "
129-
<< argv[1] << " " << argv[2] << " " << argv[3] << std::endl;
125+
<< argv[0] << " " << argv[1] << " " << argv[2] << std::endl;
130126
return;
131127
}
132128

133-
std::cerr << "\nRunning: " << argv[1] << " " << argv[2]
134-
<< " " << argv[3] << std::endl;
135-
136-
for (const std::string& s : argv)
137-
{
138-
// std::string -> std::vector<char>
139-
argv_rw.emplace_back(s.begin(), s.end());
140-
argv_rw.back().push_back('\0');
141-
142-
// std::vector<char> -> char*
143-
cargv.push_back(argv_rw.back().data());
144-
}
145-
// sentinel
146-
cargv.push_back(nullptr);
147-
148-
pid_t child_pid = fork();
149-
switch (child_pid)
150-
{
151-
case -1:
152-
throw IOError("fork() failed", errno);
153-
break;
154-
case 0:
155-
std::cerr << cargv[0] << "\n";
156-
execvp(cargv[0], cargv.data());
157-
std::cerr << "Failed to execute " << cargv[0]
158-
<< ": " << strerror(errno) << std::endl;
159-
_exit(1);
160-
break;
161-
default:
162-
waitpid(child_pid, nullptr, 0);
163-
}
129+
std::cerr << "\nRunning: " << argv[0] << " " << argv[1]
130+
<< " " << argv[2] << std::endl;
131+
run_subprocess(argv);
164132
}
165133
}

src/ek2/util/subprocess.cxx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* eclean-kernel2
2+
* (c) 2017 Michał Górny
3+
* 2-clause BSD license
4+
*/
5+
6+
#ifdef HAVE_CONFIG_H
7+
# include "config.h"
8+
#endif
9+
10+
#include "ek2/util/subprocess.h"
11+
12+
#include "ek2/util/error.h"
13+
14+
extern "C"
15+
{
16+
# include <unistd.h>
17+
# include <sys/wait.h>
18+
};
19+
20+
#include <cerrno>
21+
#include <cstring>
22+
#include <iostream>
23+
#include <string>
24+
#include <vector>
25+
26+
void run_subprocess(const std::vector<std::string>& argv)
27+
{
28+
std::vector<std::vector<char>> argv_rw;
29+
std::vector<char*> cargv;
30+
31+
for (const std::string& s : argv)
32+
{
33+
// std::string -> std::vector<char>
34+
argv_rw.emplace_back(s.begin(), s.end());
35+
argv_rw.back().push_back('\0');
36+
37+
// std::vector<char> -> char*
38+
cargv.push_back(argv_rw.back().data());
39+
}
40+
// sentinel
41+
cargv.push_back(nullptr);
42+
43+
pid_t child_pid = fork();
44+
switch (child_pid)
45+
{
46+
case -1:
47+
throw IOError("fork() failed", errno);
48+
break;
49+
case 0:
50+
std::cerr << cargv[0] << "\n";
51+
execvp(cargv[0], cargv.data());
52+
std::cerr << "Failed to execute " << cargv[0]
53+
<< ": " << strerror(errno) << std::endl;
54+
_exit(1);
55+
break;
56+
default:
57+
// TODO: handle EINTR
58+
waitpid(child_pid, nullptr, 0);
59+
}
60+
}

src/ek2/util/subprocess.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* eclean-kernel2
2+
* (c) 2017 Michał Górny
3+
* 2-clause BSD license
4+
*/
5+
6+
#pragma once
7+
8+
#ifndef EK2_UTIL_SUBPROCESS_H
9+
#define EK2_UTIL_SUBPROCESS_H 1
10+
11+
#include <string>
12+
#include <vector>
13+
14+
// run subprocess and wait for its termination (alike system())
15+
// argv[0] is assumed to contain the program name, argv[1..n] params
16+
// (execvp() is used)
17+
void run_subprocess(const std::vector<std::string>& argv);
18+
19+
#endif /*EK2_UTIL_SUBPROCESS_H*/

0 commit comments

Comments
 (0)