- int pipefd[2];
- if(pipe(pipefd) == -1) {
- cLog.msg(Log::PRIO_ERROR) << "executing script '" << script << "' pipe() error: " << AnytunErrno(errno);
- return;
- }
-
- pid_t pid;
- pid = fork();
- if(pid == -1) {
- cLog.msg(Log::PRIO_ERROR) << "executing script '" << script << "' fork() error: " << AnytunErrno(errno);
- return;
- }
-
- if(pid) {
- close(pipefd[1]);
- boost::thread(boost::bind(waitForScript, script, pid, pipefd[0]));
- return;
- }
-
-// child code
- int fd;
- for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
- if(fd != pipefd[1]) close(fd);
-
- fd = open("/dev/null",O_RDWR); // stdin
- if(fd == -1)
- cLog.msg(Log::PRIO_WARNING) << "can't open stdin";
- else {
- if(dup(fd) == -1) // stdout
- cLog.msg(Log::PRIO_WARNING) << "can't open stdout";
- if(dup(fd) == -1) // stderr
- cLog.msg(Log::PRIO_WARNING) << "can't open stderr";
- }
-
- char** argv = new char*[args.size() + 2];
- argv[0] = new char[script.size() + 1];
- std::strcpy(argv[0], script.c_str());
- for(unsigned int i=0; i<args.size(); ++i) {
- argv[i+1] = new char[args[i].size() + 1];
- std::strcpy(argv[i+1], args[i].c_str());
- }
- argv[args.size() + 1] = NULL;
-
- char** evp;
- evp = new char*[env.size() + 1];
- unsigned int i = 0;
- for(StringList::const_iterator it = env.begin(); it != env.end(); ++it) {
- evp[i] = new char[it->size() + 1];
- std::strcpy(evp[i], it->c_str());
- ++i;
- }
- evp[env.size()] = NULL;
-
- execve(script.c_str(), argv, evp);
- // if execve returns, an error occurred, but logging doesn't work
- // because we closed all file descriptors, so just write errno to
- // pipe and call exit
- int err = errno;
- int ret = write(pipefd[1], (void*)(&err), sizeof(err));
- if(ret != sizeof(errno))
- exit(-2);
- exit(-1);