'C + + calls shell commands containing sudo, resulting in deadlock
When I call sudo sleep 1000, a while loop outside me gets stuck. How can I solve it?
The calling method is as follows:
#include <iostream>
#include <string.h>
#include <vector>
#include <sys/unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <chrono>
#include <stdio.h>
#include <stdlib.h>
#include <thread>
class popen2 {
public:
FILE *in{nullptr};
FILE *out{nullptr};
pid_t pid{0};
int rcode{-1};
popen2() {
string cmd;
int pfd[2]{0};
if (pfd[0] != STDIN_FILENO) {
dup2(pfd[0], STDIN_FILENO);
close(pfd[0]);
}
if (pfd[1] != STDOUT_FILENO) {
dup2(pfd[1], STDOUT_FILENO);
close(pfd[1]);
}
execl("/bin/bash", "sh", "-c", "sudo sleep 1000", (char *) 0);
_exit(127);
}
/* parent */
this->in = fdopen(pfd[1], "w");
this->out = fdopen(pfd[0], "r");
}
~popen2() {
if (pid == 0)
return; /* wasn't opened */
if (fclose(in) == EOF)
return;
if (fclose(out) == EOF)
return;
while (waitpid(pid, &rcode, 0) < 0)
if (errno != EINTR)
return; /* error other than EINTR from waitpid() */
}
int poll() {
return waitpid(pid, &rcode, WNOHANG);
}
int kill(int sig = SIGKILL) {
return ::kill(this->pid, sig);
}
};
use:
popen2 p();
fcntl(fileno(p.out), F_SETFL, O_NONBLOCK);
auto tmStart = sh::utils::NowTime();
while (true) {
while (fgets(tmp, sizeof(tmp), p.out) != NULL)
out.append(tmp);
if (p.poll() > 0)
break;
if (sh::utils::NowTime() - tmStart > timeout) {
p.kill();
std::cout << "cmd timeout.\n";
}
this_thread::sleep_for(std::chrono::milliseconds(1));
}
Solution 1:[1]
execl("/bin/bash", "sh", "-c", "sudo sleep 1000", (char *) 0);
At this point your process no longer exists.
The exec() family of functions replaces the current process image with a new process image. The functions described in this manual page are front-ends for execve(2). (See the manual page for execve(2) for further details about the replacement of the current process image.)
Usually those are used with fork() but I'm not sure why you even trying to call an externall process at this point, just for sleep (which exists as a function)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Swift - Friday Pie |
