Process_VMS.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. //
  2. // Process_VMS.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/Process_VMS.cpp#3 $
  5. //
  6. // Library: Foundation
  7. // Package: Processes
  8. // Module: Process
  9. //
  10. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #include "Poco/Process_VMS.h"
  16. #include "Poco/NumberFormatter.h"
  17. #include "Poco/NamedEvent.h"
  18. #include <sstream>
  19. #include <times.h>
  20. #include <time.h>
  21. namespace Poco {
  22. //
  23. // ProcessHandleImpl
  24. //
  25. ProcessHandleImpl::ProcessHandleImpl(pid_t pid):
  26. _pid(pid)
  27. {
  28. }
  29. ProcessHandleImpl::~ProcessHandleImpl()
  30. {
  31. }
  32. pid_t ProcessHandleImpl::id() const
  33. {
  34. return _pid;
  35. }
  36. int ProcessHandleImpl::wait() const
  37. {
  38. int status;
  39. if (waitpid(_pid, &status, 0) != _pid)
  40. throw SystemException("Cannot wait for process", NumberFormatter::format(_pid));
  41. return WEXITSTATUS(status);
  42. }
  43. //
  44. // ProcessImpl
  45. //
  46. ProcessImpl::PIDImpl ProcessImpl::idImpl()
  47. {
  48. return getpid();
  49. }
  50. void ProcessImpl::timesImpl(long& userTime, long& kernelTime)
  51. {
  52. struct tms buffer;
  53. times(&buffer)*1000/CLOCKS_PER_SEC;
  54. userTime = buffer.tms_utime/CLOCKS_PER_SEC;
  55. kernelTime = buffer.tms_stime/CLOCKS_PER_SEC;
  56. }
  57. ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env)
  58. {
  59. char** argv = new char*[args.size() + 2];
  60. int i = 0;
  61. argv[i++] = const_cast<char*>(command.c_str());
  62. for (ArgsImpl::const_iterator it = args.begin(); it != args.end(); ++it)
  63. argv[i++] = const_cast<char*>(it->c_str());
  64. argv[i] = NULL;
  65. try
  66. {
  67. int pid = vfork();
  68. if (pid < 0)
  69. {
  70. throw SystemException("Cannot fork process for", command);
  71. }
  72. else if (pid == 0)
  73. {
  74. if (!initialDirectory.empty())
  75. {
  76. if (chdir(initialDirectory.c_str()) != 0)
  77. {
  78. std::stringstream str;
  79. str << "Cannot set initial directory to '" << initialDirectory << "' when forking process for";
  80. throw SystemException(str.str(), command);
  81. }
  82. }
  83. setEnvironmentVariables(environment_variables);
  84. if (execvp(command.c_str(), argv) == -1)
  85. throw SystemException("Cannot execute command", command);
  86. }
  87. else
  88. {
  89. delete [] argv;
  90. return new ProcessHandleImpl(pid);
  91. }
  92. }
  93. catch (...)
  94. {
  95. delete [] argv;
  96. throw;
  97. }
  98. }
  99. void ProcessImpl::killImpl(ProcessHandleImpl& handle)
  100. {
  101. killImpl(handle.id());
  102. }
  103. void ProcessImpl::killImpl(PIDImpl pid)
  104. {
  105. if (kill(pid, SIGKILL) != 0)
  106. {
  107. switch (errno)
  108. {
  109. case ESRCH:
  110. throw NotFoundException("cannot kill process");
  111. case EPERM:
  112. throw NoPermissionException("cannot kill process");
  113. default:
  114. throw SystemException("cannot kill process");
  115. }
  116. }
  117. }
  118. bool ProcessImpl::isRunningImpl(const ProcessHandleImpl& handle)
  119. {
  120. throw Poco::NotImplementedException("Process::is_running()");
  121. }
  122. bool ProcessImpl::isRunningImpl(PIDImpl pid)
  123. {
  124. throw Poco::NotImplementedException("Process::is_running()");
  125. }
  126. void ProcessImpl::requestTerminationImpl(PIDImpl pid)
  127. {
  128. std::string evName("POCOTRM");
  129. evName.append(NumberFormatter::formatHex(pid, 8));
  130. NamedEvent ev(evName);
  131. ev.set();
  132. }
  133. } // namespace Poco