openbsd-ports/x11/textsuggest/patches/patch-lib_subprocess_hpp

224 lines
6.4 KiB
Plaintext

Get rid of GNU-specific C++ type.
Trim down to features actually needed by Textsuggest.
Index: lib/subprocess.hpp
--- lib/subprocess.hpp.orig
+++ lib/subprocess.hpp
@@ -11,7 +11,7 @@
#include <string>
#include <vector>
#include <iostream>
-#include <ext/stdio_filebuf.h>
+#include <sstream>
#include <cstdio>
#include <system_error>
@@ -27,71 +27,66 @@ class popen
public:
popen(const std::string& cmd, std::vector<std::string> argv)
- : in_filebuf(nullptr), out_filebuf(nullptr), err_filebuf(nullptr), in_stream(nullptr), out_stream(nullptr), err_stream(nullptr)
{
- if (pipe(in_pipe) == -1 ||
- pipe(out_pipe) == -1 ||
- pipe(err_pipe) == -1 )
- {
- throw std::system_error(errno, std::system_category());
- }
-
+ out_stream = new std::stringstream;
+ err_stream = new std::stringstream;
+ open_pipes();
run(cmd, argv);
}
- popen(const std::string& cmd, std::vector<std::string> argv, std::ostream& pipe_stdout)
- : in_filebuf(nullptr), out_filebuf(nullptr), err_filebuf(nullptr), in_stream(nullptr), out_stream(nullptr), err_stream(nullptr)
- {
- auto filebuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(pipe_stdout.rdbuf());
- out_pipe[READ] = -1;
- out_pipe[WRITE] = filebuf->fd();
-
- if (pipe(in_pipe) == -1 ||
- pipe(err_pipe) == -1 )
- {
- throw std::system_error(errno, std::system_category());
- }
-
- run(cmd, argv);
- }
-
~popen()
{
- delete in_filebuf;
- delete in_stream;
- if (out_filebuf != nullptr) delete out_filebuf;
- if (out_stream != nullptr) delete out_stream;
- delete err_filebuf;
+ close_pipe(in_pipe);
+ close_pipe(err_pipe);
+ close_pipe(out_pipe);
+ delete out_stream;
delete err_stream;
}
- std::ostream& stdin() { return *in_stream; };
+ std::istream& get_stdout() { return *out_stream; };
+ std::istream& get_stderr() { return *err_stream; };
- std::istream& stdout()
- {
- if (out_stream == nullptr) throw std::system_error(EBADF, std::system_category());
- return *out_stream;
- };
+ int wait(void) { return WEXITSTATUS(status); }
+
+private:
- std::istream& stderr() { return *err_stream; };
-
- int wait()
+ enum ends_of_pipe { READ = 0, WRITE = 1 };
+
+ void open_pipes(void)
{
- int status = 0;
- waitpid(pid, &status, 0);
- return WEXITSTATUS(status);
- };
+ if (pipe(in_pipe) == -1)
+ throw std::system_error(errno, std::system_category());
- void close()
+ if (pipe(out_pipe) == -1)
+ {
+ int pipe_errno = errno;
+ close_pipe(in_pipe);
+ throw std::system_error(pipe_errno, std::system_category());
+ }
+ if (pipe(err_pipe) == -1 )
+ {
+ int pipe_errno = errno;
+ close_pipe(in_pipe);
+ close_pipe(out_pipe);
+ throw std::system_error(pipe_errno, std::system_category());
+ }
+ }
+
+ void close_pipe_end(int pipe[2], enum ends_of_pipe end)
{
- in_filebuf->close();
+ if (pipe[end] != -1)
+ {
+ ::close(pipe[end]);
+ pipe[end] = -1;
+ }
}
-
-
-private:
-
- enum ends_of_pipe { READ = 0, WRITE = 1 };
+ void close_pipe(int pipe[2])
+ {
+ close_pipe_end(pipe, READ);
+ close_pipe_end(pipe, WRITE);
+ }
+
struct raii_char_str
{
raii_char_str(std::string s) : buf(s.c_str(), s.c_str() + s.size() + 1) { };
@@ -99,6 +94,22 @@ class popen
mutable std::vector<char> buf;
};
+ void slurp_pipe(int fd, std::stringstream *&sink)
+ {
+ char buf[4096];
+
+ while (1)
+ {
+ ssize_t ret = read(out_pipe[READ], buf, sizeof(buf));
+ if (ret == -1)
+ throw std::system_error(errno, std::system_category());
+ else if (ret > 0)
+ sink->write(buf, ret);
+ else
+ break;
+ }
+ }
+
void run(const std::string& cmd, std::vector<std::string> argv)
{
argv.insert(argv.begin(), cmd);
@@ -107,21 +118,17 @@ class popen
if (pid == 0) child(argv);
- ::close(in_pipe[READ]);
- ::close(out_pipe[WRITE]);
- ::close(err_pipe[WRITE]);
+ close_pipe_end(in_pipe, READ);
+ close_pipe_end(out_pipe, WRITE);
+ close_pipe_end(err_pipe, WRITE);
- in_filebuf = new __gnu_cxx::stdio_filebuf<char>(in_pipe[WRITE], std::ios_base::out, 1);
- in_stream = new std::ostream(in_filebuf);
-
- if (out_pipe[READ] != -1)
- {
- out_filebuf = new __gnu_cxx::stdio_filebuf<char>(out_pipe[READ], std::ios_base::in, 1);
- out_stream = new std::istream(out_filebuf);
- }
-
- err_filebuf = new __gnu_cxx::stdio_filebuf<char>(err_pipe[READ], std::ios_base::in, 1);
- err_stream = new std::istream(err_filebuf);
+ slurp_pipe(out_pipe[READ], out_stream);
+ slurp_pipe(err_pipe[READ], err_stream);
+
+ close_pipe_end(out_pipe, READ);
+ close_pipe_end(err_pipe, READ);
+
+ waitpid(pid, &status, 0);
}
void child(const std::vector<std::string>& argv)
@@ -134,12 +141,9 @@ class popen
return;
}
- ::close(in_pipe[READ]);
- ::close(in_pipe[WRITE]);
- if (out_pipe[READ] != -1) ::close(out_pipe[READ]);
- ::close(out_pipe[WRITE]);
- ::close(err_pipe[READ]);
- ::close(err_pipe[WRITE]);
+ close_pipe(in_pipe);
+ close_pipe_end(out_pipe, WRITE);
+ close_pipe_end(err_pipe, WRITE);
std::vector<raii_char_str> real_args(argv.begin(), argv.end());
std::vector<char*> cargs(real_args.begin(), real_args.end());
@@ -153,18 +157,14 @@ class popen
}
pid_t pid;
+ int status;
int in_pipe[2];
int out_pipe[2];
int err_pipe[2];
- __gnu_cxx::stdio_filebuf<char>* in_filebuf;
- __gnu_cxx::stdio_filebuf<char>* out_filebuf;
- __gnu_cxx::stdio_filebuf<char>* err_filebuf;
-
- std::ostream* in_stream;
- std::istream* out_stream;
- std::istream* err_stream;
+ std::stringstream *out_stream;
+ std::stringstream *err_stream;
};
} // namespace: subprocess