runscript.cc 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/wait.h>
  5. #include <string>
  6. #include <vector>
  7. #include <cerrno>
  8. #include "logger.h"
  9. #include "common.h"
  10. extern "C" {
  11. int run_script(std::string arg0, std::vector<std::string> env)
  12. {
  13. /* Convert the vector containing environment variables to the format
  14. * expected by execle(). */
  15. char const* envp[env.size() + 1];
  16. for (int i = 0; i < env.size(); ++i) {
  17. envp[i] = env[i].c_str();
  18. }
  19. envp[env.size()] = (char const*) NULL;
  20. /* fork() & execle() */
  21. int ret, wstatus, exitcode;
  22. pid_t pid;
  23. pid = fork();
  24. if (pid == -1) {
  25. LOG_ERROR(runscript_logger, RUNSCRIPT_FORK_FAILED).arg(strerror(errno));
  26. return -1;
  27. }
  28. if (pid == 0) {
  29. /* Child process */
  30. ret = execle(script_path.c_str(), script_name.c_str(), arg0.c_str(), (char *)NULL, envp);
  31. LOG_ERROR(runscript_logger, RUNSCRIPT_EXEC_FAILED).arg(strerror(errno));
  32. /* This only exists the child, not Kea itself. */
  33. exit(EXIT_FAILURE);
  34. } else {
  35. if (script_wait) {
  36. /* Parent process */
  37. LOG_DEBUG(runscript_logger, 50, RUNSCRIPT_WAITING_SCRIPT);
  38. ret = wait(&wstatus);
  39. if (ret == -1) {
  40. LOG_ERROR(runscript_logger, RUNSCRIPT_WAITPID_FAILED).arg(strerror(errno));
  41. return -1;
  42. }
  43. /* Get exit code */
  44. if (WIFEXITED(wstatus))
  45. exitcode = WEXITSTATUS(wstatus);
  46. else
  47. /* By default, assume everything worked well */
  48. exitcode = 0;
  49. return exitcode;
  50. } else {
  51. return 0;
  52. }
  53. }
  54. }
  55. } // end extern "C"