1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00
ULib/include/ulib/process.h
stefanocasazza b5184ba45e sync
2018-07-27 18:11:02 +02:00

201 lines
4.1 KiB
C++

// ============================================================================
//
// = LIBRARY
// ULib - c++ library
//
// = FILENAME
// process.h
//
// = AUTHOR
// Stefano Casazza
//
// ============================================================================
#ifndef ULIB_PROCESS_H
#define ULIB_PROCESS_H 1
#include <ulib/internal/common.h>
#ifdef HAVE_SYSEXITS_H
# include <sysexits.h>
#else
# include <ulib/base/replace/sysexits.h>
#endif
#if defined(__CYGWIN__) || defined(__APPLE__) || !defined(_MSWINDOWS_)
# include <sys/wait.h>
# ifndef _MSWINDOWS_
# include <sys/socket.h>
# endif
#endif
#define U_FAILED_NONE 0
#define U_FAILED_SOME 2
#define U_FAILED_ALL 3
#define U_FAILED_ALARM 4
class UCommand;
class UServer_Base;
class UNoCatPlugIn;
class U_EXPORT UProcess {
public:
// Check for memory error
U_MEMORY_TEST
// Allocator e Deallocator
U_MEMORY_ALLOCATOR
U_MEMORY_DEALLOCATOR
UProcess()
{
U_TRACE_CTOR(0, UProcess, "")
_pid = (pid_t)-1;
status = 0;
running = false;
}
~UProcess()
{
U_TRACE_DTOR(0, UProcess)
}
// FORK
bool fork();
bool child() const { return (_pid == 0); }
bool parent() const { return (_pid > 0); }
pid_t pid() const { return _pid; }
pid_t ppid() const
{
U_TRACE_NO_PARAM(0, "UProcess::ppid()")
pid_t _ppid = U_SYSCALL_NO_PARAM(getppid);
U_RETURN(_ppid);
}
// WAIT
void wait()
{
U_TRACE_NO_PARAM(0, "UProcess::wait()")
U_CHECK_MEMORY
if (running &&
UProcess::waitpid(_pid, &status, 0) == _pid)
{
running = false;
}
# ifdef DEBUG
char buffer[128];
(void) exitInfo(buffer, status);
U_INTERNAL_DUMP("status = %d, %S", status, buffer)
# endif
}
int waitAll(int timeoutMS = 0);
static uint32_t removeZombies()
{
U_TRACE_NO_PARAM(1, "UProcess::removeZombies()")
uint32_t n = 0;
# ifndef _MSWINDOWS_
while (U_SYSCALL(waitpid, "%d,%p,%d", -1, U_NULLPTR, WNOHANG) > 0) ++n;
# endif
U_RETURN(n);
}
static int waitpid(pid_t pid = -1, int* status = U_NULLPTR, int options = WNOHANG);
// STATUS CHILD
static char* exitInfo(char* buffer, int status);
char* exitInfo(char* buffer) const { return exitInfo(buffer, status); }
static int exitValue(int _status)
{
U_TRACE(0, "UProcess::exitValue(%d)", _status)
int exit_value = ( WIFEXITED(_status) ? WEXITSTATUS(_status) :
WIFSIGNALED(_status) ? - (WTERMSIG(_status) << 8) : -1);
U_RETURN(exit_value);
}
int exitValue() const { return exitValue(status); }
// Inter Process Comunication (IPC)
static int filedes[6]; // 3 serie di pipe to manage file descriptors for child I/O redirection...
static void pipe(int fdp);
// services for EXEC
static void nice(int inc)
{
U_TRACE(1, "UProcess::nice(%d)", inc)
(void) U_SYSCALL(nice, "%d", inc);
}
static void kill(pid_t pid, int sig)
{
U_TRACE(1, "UProcess::kill(%d,%d)", pid, sig)
(void) U_SYSCALL(kill, "%d,%d", pid, sig);
}
static void setProcessGroup(pid_t pid = 0, pid_t pgid = 0)
{
U_TRACE(1, "UProcess::setProcessGroup(%d,%d)", pid, pgid)
# ifndef _MSWINDOWS_
(void) U_SYSCALL(setpgid, "%d,%d", pid, pgid);
# endif
}
// exec with internal vfork() with management of file descriptors for child I/O redirection...
static pid_t execute(const char* pathname, char* argv[], char* envp[], bool fd_stdin, bool fd_stdout, bool fd_stderr);
#if defined(U_STDCPP_ENABLE) && defined(DEBUG)
const char* dump(bool) const;
#endif
protected:
pid_t _pid;
int status;
bool running;
#ifdef _MSWINDOWS_
static STARTUPINFO aStartupInfo;
static PROCESS_INFORMATION aProcessInformation;
static HANDLE hFile[6], hChildIn, hChildOut, hChildErr;
#endif
static void setStdInOutErr(bool fd_stdin, bool fd_stdout, bool fd_stderr) U_NO_EXPORT;
private:
U_DISALLOW_COPY_AND_ASSIGN(UProcess)
friend class UCommand;
friend class UServer_Base;
friend class UNoCatPlugIn;
};
#endif