28#if !defined(TIMEMORY_WINDOWS)
35# if !defined(OPEN_MAX)
39# if !defined(NGROUPS_MAX)
40# define NGROUPS_MAX 16
77 gid_t newgid = getgid();
78 gid_t oldgid = getegid();
79 uid_t newuid = getuid();
80 uid_t olduid = geteuid();
98 setgroups(1, &newgid);
102# if !defined(TIMEMORY_LINUX)
103 auto ret = setegid(newgid);
106 if(permanent != 0 && setgid(newgid) == -1)
109 if(setregid(((permanent != 0) ? newgid : oldgid), newgid) == -1)
116# if !defined(TIMEMORY_LINUX)
117 auto ret = seteuid(newuid);
120 if(permanent != 0 && setuid(newuid) == -1)
123 if(setreuid(((permanent != 0) ? newuid : olduid), newuid) == -1)
131 if(newgid != oldgid && (setegid(oldgid) != -1 || getegid() != newgid))
133 if(newuid != olduid && (seteuid(olduid) != -1 || geteuid() != newuid))
138 if(newgid != oldgid && getegid() != newgid)
140 if(newuid != olduid && geteuid() != newuid)
170 case 0: f = freopen(
"/dev/null",
"rb", stdin);
break;
171 case 1: f = freopen(
"/dev/null",
"wb", stdout);
break;
172 case 2: f = freopen(
"/dev/null",
"wb", stderr);
break;
175 return (f !=
nullptr && fileno(f) == fd) ? 1 : 0;
196 for(
int fd = 0; fd < 3; ++fd)
198 if(fstat(fd, &st) == -1 && (errno != EBADF ||
open_devnull(fd) == 0))
212 if((childpid = ::
fork()) == -1)
231 int stdin_pipe[2] = { 0, 0 };
232 int stdout_pipe[2] = { 0, 0 };
235 static char** _argv = []() {
236 static auto* _tmp =
new char*[1];
255 if(pipe(stdin_pipe) == -1)
261 if(pipe(stdout_pipe) == -1)
263 close(stdin_pipe[1]);
264 close(stdin_pipe[0]);
269 if(!(p->
read_fd = fdopen(stdout_pipe[0],
"r")))
271 close(stdout_pipe[1]);
272 close(stdout_pipe[0]);
273 close(stdin_pipe[1]);
274 close(stdin_pipe[0]);
279 if(!(p->
write_fd = fdopen(stdin_pipe[1],
"w")))
282 close(stdout_pipe[1]);
283 close(stdin_pipe[1]);
284 close(stdin_pipe[0]);
293 close(stdout_pipe[1]);
294 close(stdin_pipe[0]);
302 close(stdout_pipe[0]);
303 close(stdin_pipe[1]);
304 if(stdin_pipe[0] != 0)
306 dup2(stdin_pipe[0], 0);
307 close(stdin_pipe[0]);
309 if(stdout_pipe[1] != 1)
311 dup2(stdout_pipe[1], 1);
312 close(stdout_pipe[1]);
318 close(stdout_pipe[1]);
319 close(stdin_pipe[0]);
333 auto _clean = [&]() {
344 if(WIFEXITED(status))
350 else if(WIFSIGNALED(status))
352 printf(
"process %i killed by signal %d\n", p->
child_pid, WTERMSIG(status));
355 else if(WIFSTOPPED(status))
357 printf(
"process %i stopped by signal %d\n", p->
child_pid, WSTOPSIG(status));
360 else if(WIFCONTINUED(status))
362 printf(
"process %i continued\n", p->
child_pid);
373 }
while(pid == -1 && errno == EINTR);
377 if(pid != -1 && WIFEXITED(status))
378 return WEXITSTATUS(status);
379 return (pid == -1 ? -1 : 0);
393 auto* ret = fgets(buffer, 4096, proc->
read_fd);
394 if(ret ==
nullptr || strlen(buffer) == 0)
409 auto loc = string_t::npos;
410 while((loc = line.find_first_of(
"\n\t")) != string_t::npos)
412 auto delim =
delimit(line,
" \n\t=>");
413 for(
const auto& itr : delim)
415 if(itr.find(
'/') == 0)
416 linked_libraries.push_back(itr);
420 return linked_libraries;
432 auto* ret = fgets(buffer, 4096, proc->
read_fd);
433 if(ret ==
nullptr || strlen(buffer) == 0)
462int windows_popen = 0;
::tim::statistics< Tp > max(::tim::statistics< Tp > lhs, const Tp &rhs)
void drop_privileges(int permanent)
TIMEMORY_PIPE * popen(const char *path, char **argv, char **envp)
void restore_privileges()
std::ostream & flush_output(std::ostream &os, TIMEMORY_PIPE *proc, int max_counter)
std::vector< string_t > strvec_t
int pclose(TIMEMORY_PIPE *p)
strvec_t read_fork(TIMEMORY_PIPE *proc, int max_counter)
group_info & get_group_info()
const std::string std::ostream * os
ContainerT delimit(const std::string &line, const std::string &delimiters="\"',;: ", PredicateT &&predicate=[](const std::string &s) -> std::string { return s;})