]> git.proxmox.com Git - ceph.git/blame_incremental - ceph/src/common/SubProcess.h
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / common / SubProcess.h
... / ...
CommitLineData
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph distributed storage system
5 *
6 * Copyright (C) 2015 Mirantis Inc
7 *
8 * Author: Mykola Golub <mgolub@mirantis.com>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 */
16
17#ifndef SUB_PROCESS_H
18#define SUB_PROCESS_H
19
20#if defined(__FreeBSD__) || defined(__APPLE__)
21#include <signal.h>
22#endif
23
24#ifndef _WIN32
25#include <sys/wait.h>
26#endif
27#include <sstream>
28#include <vector>
29
30#include "include/compat.h"
31
32/**
33 * SubProcess:
34 * A helper class to spawn a subprocess.
35 *
36 * Example:
37 *
38 * SubProcess cat("cat", SubProcess::PIPE, SubProcess::PIPE);
39 * if (cat.spawn() != 0) {
40 * std::cerr << "cat failed: " << cat.err() << std::endl;
41 * return false;
42 * }
43 * write_to_fd(cat.get_stdout(), "hello world!\n");
44 * cat.close_stdout();
45 * read_from_fd(cat.get_stdin(), buf);
46 * if (cat.join() != 0) {
47 * std::cerr << cat.err() << std::endl;
48 * return false;
49 * }
50 */
51
52class SubProcess {
53public:
54 enum std_fd_op{
55 KEEP,
56 CLOSE,
57 PIPE
58 };
59public:
60 SubProcess(const char *cmd,
61 std_fd_op stdin_op = CLOSE,
62 std_fd_op stdout_op = CLOSE,
63 std_fd_op stderr_op = CLOSE);
64 virtual ~SubProcess();
65
66 void add_cmd_args(const char *arg, ...);
67 void add_cmd_arg(const char *arg);
68
69 virtual int spawn(); // Returns 0 on success or -errno on failure.
70 virtual int join(); // Returns exit code (0 on success).
71
72 bool is_spawned() const { return pid > 0; }
73
74 int get_stdin() const;
75 int get_stdout() const;
76 int get_stderr() const;
77
78 void close_stdin();
79 void close_stdout();
80 void close_stderr();
81
82 void kill(int signo = SIGTERM) const;
83
84 const std::string err() const;
85
86protected:
87 bool is_child() const { return pid == 0; }
88 virtual void exec();
89
90 void close(int &fd);
91
92#ifdef _WIN32
93 void close_h(HANDLE &handle);
94#endif
95
96protected:
97 std::string cmd;
98 std::vector<std::string> cmd_args;
99 std_fd_op stdin_op;
100 std_fd_op stdout_op;
101 std_fd_op stderr_op;
102 int stdin_pipe_out_fd;
103 int stdout_pipe_in_fd;
104 int stderr_pipe_in_fd;
105 int pid;
106 std::ostringstream errstr;
107
108#ifdef _WIN32
109 HANDLE proc_handle = INVALID_HANDLE_VALUE;
110#endif
111};
112
113class SubProcessTimed : public SubProcess {
114public:
115 SubProcessTimed(const char *cmd, std_fd_op stdin_op = CLOSE,
116 std_fd_op stdout_op = CLOSE, std_fd_op stderr_op = CLOSE,
117 int timeout = 0, int sigkill = SIGKILL);
118
119#ifdef _WIN32
120 int spawn() override;
121 int join() override;
122#endif
123
124protected:
125 void exec() override;
126
127private:
128 int timeout;
129 int sigkill;
130
131#ifdef _WIN32
132 std::thread waiter;
133#endif
134};
135
136void timeout_sighandler(int sig);
137
138#endif