MiKTeX 23.10-next
A scalable TeX distribution
Loading...
Searching...
No Matches
Process.h
1/* miktex/Core/Process.h: -*- C++ -*-
2
3 Copyright (C) 1996-2021 Christian Schenk
4
5 This file is part of the MiKTeX Core Library.
6
7 The MiKTeX Core Library is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2, or
10 (at your option) any later version.
11
12 The MiKTeX Core Library is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with the MiKTeX Core Library; if not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22#pragma once
23
24#if !defined(B7FD926CACF346B0BA927D19810BDA19)
25#define B7FD926CACF346B0BA927D19810BDA19
26
27#include <miktex/Core/config.h>
28
29#include <cstddef>
30#include <cstdint>
31#include <cstdio>
32
33#include <algorithm>
34#include <functional>
35#include <memory>
36#include <string>
37#include <vector>
38
39#include <miktex/Util/PathName>
40
41#include "Exceptions.h"
42
43MIKTEX_CORE_BEGIN_NAMESPACE;
44
46class MIKTEXNOVTABLE IRunProcessCallback
47{
53public:
54 virtual bool MIKTEXTHISCALL OnProcessOutput(const void* output, std::size_t n) = 0;
55
56#if 0
62public:
63 virtual bool MIKTEXTHISCALL OnProcessError(const void* error, std::size_t n) = 0;
64#endif
65};
66
68template<std::size_t MaxStdoutSize_ = 1024, std::size_t ExpectedStdoutSize_ = 1024> class ProcessOutput :
70{
71public:
73 stdoutBytes(ExpectedStdoutSize_)
74 {
75 }
76
77public:
78 bool MIKTEXTHISCALL OnProcessOutput(const void* bytes, std::size_t nBytes) override
79 {
80#if defined(_MSC_VER)
81#pragma push_macro("min")
82#undef min
83#endif
84 std::size_t n = std::min(nBytes, MaxStdoutSize_ - stdoutOffset);
85#if defined(MIKTEX_WINDOWS)
86#pragma pop_macro("min")
87#endif
88 if (n > 0)
89 {
90 stdoutBytes.reserve(stdoutOffset + n);
91 std::copy(reinterpret_cast<const uint8_t*>(bytes), reinterpret_cast<const uint8_t*>(bytes) + n, stdoutBytes.data() + stdoutOffset);
92 stdoutOffset += n;
93 }
94 return true;
95 }
96
99public:
100 std::vector<uint8_t> GetStandardOutput() const
101 {
102 return stdoutBytes;
103 }
104
107public:
108 std::string StdoutToString() const
109 {
110 // FIXME: assume UTF-8
111 std::string result;
112 result.reserve(stdoutOffset);
113 result.assign(reinterpret_cast<const char*>(stdoutBytes.data()), reinterpret_cast<const char*>(stdoutBytes.data() + stdoutOffset));
114 return result;
115 }
116
117private:
118 std::vector<uint8_t> stdoutBytes;
119
120private:
121 std::size_t stdoutOffset = 0;
122};
123
126{
129 std::vector<std::string> Arguments;
130
132 std::string FileName;
133
134#if defined(MIKTEX_WINDOWS)
136 FILE* StandardError = nullptr;
137#endif
138
140 FILE* StandardInput = nullptr;
141
142#if defined(MIKTEX_WINDOWS)
144 FILE* StandardOutput = nullptr;
145#endif
146
148 bool RedirectStandardError = false;
149
151 bool RedirectStandardInput = false;
152
154 bool RedirectStandardOutput = false;
155
157 std::string WorkingDirectory;
158
160 bool Daemonize = false;
161
163 {
164 }
165
167 FileName(fileName.ToString())
168 {
169 }
170};
171
174{
175 None,
176 Runnable,
177 Sleeping,
178 Stopped,
179 Zombie,
180 Other
181};
182
185{
186 None,
187 Exited,
188 Signaled,
189 Other
190};
191
194{
195 std::string name;
196 ProcessStatus status = ProcessStatus::None;
197 int parent = -1;
198};
199
201class MIKTEXNOVTABLE Process
202{
203public:
204 virtual MIKTEXTHISCALL ~Process() noexcept = 0;
205
209public:
210 virtual FILE* MIKTEXTHISCALL get_StandardInput() = 0;
211
215public:
216 virtual FILE* MIKTEXTHISCALL get_StandardOutput() = 0;
217
221public:
222 virtual FILE* MIKTEXTHISCALL get_StandardError() = 0;
223
225public:
226 virtual void MIKTEXTHISCALL WaitForExit() = 0;
227
231public:
232 virtual bool MIKTEXTHISCALL WaitForExit(int milliseconds) = 0;
233
236public:
237 virtual ProcessExitStatus MIKTEXTHISCALL get_ExitStatus() const = 0;
238
241public:
242 virtual int MIKTEXTHISCALL get_ExitCode() const = 0;
243
246public:
247 virtual bool MIKTEXTHISCALL get_Exception(MiKTeX::Core::MiKTeXException& ex) const = 0;
248
250public:
251 virtual void MIKTEXTHISCALL Close() = 0;
252
255public:
256 virtual int MIKTEXTHISCALL GetSystemId() = 0;
257
260public:
261 virtual std::unique_ptr<Process> MIKTEXTHISCALL get_Parent() = 0;
262
265public:
266 virtual std::string MIKTEXTHISCALL get_ProcessName() = 0;
267
270public:
271 virtual ProcessInfo MIKTEXTHISCALL GetProcessInfo() = 0;
272
275public:
276 static MIKTEXCORECEEAPI(std::unique_ptr<Process>) GetCurrentProcess();
277
281public:
282 static MIKTEXCORECEEAPI(std::unique_ptr<Process>) GetProcess(int systemId);
283
286public:
287 static MIKTEXCORECEEAPI(std::vector<std::string>) GetInvokerNames();
288
291public:
292 static MIKTEXCORECEEAPI(std::unique_ptr<Process>) StartSystemCommand(const std::string& commandLine, FILE** ppFileStandardInput, FILE** ppFileStandardOutput);
293
296public:
297 static void StartSystemCommand(const std::string& commandLine)
298 {
299 auto process = StartSystemCommand(commandLine, nullptr, nullptr);
300 process->Close();
301 }
302
306public:
307 static MIKTEXCORECEEAPI(bool) ExecuteSystemCommand(const std::string& commandLine);
308
314public:
315 static MIKTEXCORECEEAPI(bool) ExecuteSystemCommand(const std::string& commandLine, int* exitCode);
316
324public:
325 static MIKTEXCORECEEAPI(bool) ExecuteSystemCommand(const std::string& commandLine, int* exitCode, IRunProcessCallback* callback, const char* workingDirectory);
326
331public:
332 static MIKTEXCORECEEAPI(void) Run(const MiKTeX::Util::PathName& fileName, const std::vector<std::string>& arguments);
333
336public:
337 static void Run(const MiKTeX::Util::PathName& fileName)
338 {
339 Run(fileName, std::vector<std::string>{ fileName.ToString() });
340 }
341
347public:
348 static MIKTEXCORECEEAPI(void) Run(const MiKTeX::Util::PathName& fileName, const std::vector<std::string>& arguments, IRunProcessCallback* callback);
349
360public:
361 static MIKTEXCORECEEAPI(bool) Run(const MiKTeX::Util::PathName& fileName, const std::vector<std::string>& arguments, IRunProcessCallback* callback, int* exitCode, MiKTeXException* miktexException, const char* workingDirectory);
362
373public:
374 static MIKTEXCORECEEAPI(bool) Run(const MiKTeX::Util::PathName& fileName, const std::vector<std::string>& arguments, std::function<bool(const void*, std::size_t)> callback, int* exitCode, MiKTeXException* miktexException, const char* workingDirectory);
375
385public:
386 static bool Run(const MiKTeX::Util::PathName& fileName, const std::vector<std::string>& arguments, IRunProcessCallback* callback, int* exitCode, const char* workingDirectory)
387 {
388 return Run(fileName, arguments, callback, exitCode, nullptr, workingDirectory);
389 }
390
394public:
395 static MIKTEXCORECEEAPI(std::unique_ptr<Process>) Start(const ProcessStartInfo& startinfo);
396
406public:
407 static MIKTEXCORECEEAPI(void) Start(const MiKTeX::Util::PathName& fileName, const std::vector<std::string>& arguments, FILE* pFileStandardInput, FILE** ppFileStandardInput, FILE** ppFileStandardOutput, FILE** ppFileStandardError, const char* workingDirectory);
408
411public:
412 static void Start(const MiKTeX::Util::PathName& fileName)
413 {
414 Start(fileName, std::vector<std::string>{ fileName.GetFileNameWithoutExtension().ToString() }, nullptr, nullptr, nullptr, nullptr, nullptr);
415 }
416
421public:
422 static void Start(const MiKTeX::Util::PathName& fileName, const std::vector<std::string>& arguments)
423 {
424 Start(fileName, arguments, nullptr, nullptr, nullptr, nullptr, nullptr);
425 }
426
427public:
428 static MIKTEXCORECEEAPI(void) Overlay(const MiKTeX::Util::PathName& fileName, const std::vector<std::string>& arguments);
429};
430
431MIKTEX_CORE_END_NAMESPACE;
432
433#endif
Run process callback interface.
Definition: Process.h:47
virtual bool OnProcessOutput(const void *output, std::size_t n)=0
An instance of this class manages a child process.
Definition: Process.h:202
virtual ProcessInfo GetProcessInfo()=0
static void Run(const MiKTeX::Util::PathName &fileName, const std::vector< std::string > &arguments, IRunProcessCallback *callback)
static void Start(const MiKTeX::Util::PathName &fileName, const std::vector< std::string > &arguments, FILE *pFileStandardInput, FILE **ppFileStandardInput, FILE **ppFileStandardOutput, FILE **ppFileStandardError, const char *workingDirectory)
static void StartSystemCommand(const std::string &commandLine)
Definition: Process.h:297
static std::unique_ptr< Process > GetProcess(int systemId)
static void Run(const MiKTeX::Util::PathName &fileName)
Definition: Process.h:337
static std::unique_ptr< Process > StartSystemCommand(const std::string &commandLine, FILE **ppFileStandardInput, FILE **ppFileStandardOutput)
static bool Run(const MiKTeX::Util::PathName &fileName, const std::vector< std::string > &arguments, IRunProcessCallback *callback, int *exitCode, MiKTeXException *miktexException, const char *workingDirectory)
static void Run(const MiKTeX::Util::PathName &fileName, const std::vector< std::string > &arguments)
virtual bool get_Exception(MiKTeX::Core::MiKTeXException &ex) const =0
virtual int GetSystemId()=0
static bool ExecuteSystemCommand(const std::string &commandLine, int *exitCode)
virtual std::string get_ProcessName()=0
static bool Run(const MiKTeX::Util::PathName &fileName, const std::vector< std::string > &arguments, IRunProcessCallback *callback, int *exitCode, const char *workingDirectory)
Definition: Process.h:386
virtual void WaitForExit()=0
Waits for the process to finish.
virtual FILE * get_StandardOutput()=0
static std::vector< std::string > GetInvokerNames()
virtual FILE * get_StandardError()=0
static std::unique_ptr< Process > GetCurrentProcess()
static void Start(const MiKTeX::Util::PathName &fileName)
Definition: Process.h:412
virtual std::unique_ptr< Process > get_Parent()=0
virtual ProcessExitStatus get_ExitStatus() const =0
static void Start(const MiKTeX::Util::PathName &fileName, const std::vector< std::string > &arguments)
Definition: Process.h:422
static bool ExecuteSystemCommand(const std::string &commandLine)
virtual void Close()=0
Frees all resources associated with this Process object.
static bool Run(const MiKTeX::Util::PathName &fileName, const std::vector< std::string > &arguments, std::function< bool(const void *, std::size_t)> callback, int *exitCode, MiKTeXException *miktexException, const char *workingDirectory)
static bool ExecuteSystemCommand(const std::string &commandLine, int *exitCode, IRunProcessCallback *callback, const char *workingDirectory)
static std::unique_ptr< Process > Start(const ProcessStartInfo &startinfo)
virtual bool WaitForExit(int milliseconds)=0
virtual int get_ExitCode() const =0
virtual FILE * get_StandardInput()=0
A callback interface to save process output.
Definition: Process.h:70
std::vector< uint8_t > GetStandardOutput() const
Definition: Process.h:100
bool OnProcessOutput(const void *bytes, std::size_t nBytes) override
Definition: Process.h:78
std::string StdoutToString() const
Definition: Process.h:108
Instances of this class can be used to store path names.
Definition: PathName.h:73
ProcessExitStatus
Process exit status.
Definition: Process.h:185
ProcessStatus
Process status.
Definition: Process.h:174
Process information.
Definition: Process.h:194
Process start options.
Definition: Process.h:126
std::string FileName
File system path to the executable file.
Definition: Process.h:132
std::vector< std::string > Arguments
Definition: Process.h:129
std::string WorkingDirectory
Working directory for the process.
Definition: Process.h:157