On Wed, 21 Mar 2001, Anil Madhavapeddy wrote:
> This has come up a few times, but is there any chance of having a
> bi-directional popen() that doesn't depend on the underlying system
> call supporting it?
Hm.. it would be possible to make one that uses socketpair() instead of
pipe() to do it's work.
Something to the effect of:
/* Real global */
int return_code = 0;
pid_t last_pid = 0; /* This means it can only have one popen() going at
once.. */
void php_sigchld_handler(int sig)
{
int status;
pid_t pid;
pid = wait4(-1, &status, WNOHANG, NULL);
if (pid > 0)
{
if (WIFEXITED(status))
{
return_code = WEXITSTATUS(status);
}
}
return;
}
int php_pclose(FILE *pipe)
{
int fd = _fileno(pipe);
int ret;
int status;
fclose(pipe);
ret = wait4(last_pid, &status, WNOHANG, NULL);
if (ret == 0)
{
kill(last_pid, SIGTERM);
if (ret == 0)
return return_code;
else
return WEXITSTATUS(status);
}
else
{
return WEXITSTATUS(status);
}
}
FILE* php_popen(char *cmd, char *mode)
{
int fds[2];
FILE *ret;
pid_t pid;
int i;
if ((mode[0] == 'r' || mode[0] == 'w') && mode[1] == '\0')
{
return popen(cmd, mode);
}
else
{
if (socketpair(AF_INET, SOCK_STREAM, 0, fds[2]) == 0)
{
pid = fork();
if (pid > 0)
{
/* Parent process */
/* Catch SIGCHLD to tell us when it's exited. */
(void) signal(SIGCHLD, php_sigchld_handler);
/* Create a FILE* from the file descriptor */
ret = fdopen(fds[0], "w+");
if (ret == NULL)
{
/* Oh -- can't fdopen()? */
(void) kill(ret, SIGKILL);
}
/* And we're done */
return ret;
}
else if (pid == 0)
{
/* Child process */
for (i = 0; i < 1024; i++) {
if (i != fds[1])
{
(void) close(i);
}
}
/* Create stdin/stdout/stderr */
dup2(fds[1], 0);
dup2(fds[1], 1);
dup2(fds[1], 2);
execl("/bin/sh", "-c", cmd, (char *) 0);
exit(127);
}
else
{
return NULL;
}
}
}
}
PS: This is just a quick hack. I think it might work as is, but it's not
something I would try using as-is without checking it out first.
Chris
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]