#ifndef __PIO_H__
#define __PIO_H__
FILE* popen(const char* shell_cmd, const char* mode);
int pclose(FILE* fstream);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include "pio.h"
static int num_sh = 0;
struct sh_rec
{
pid_t sh_pid;
FILE* stream;
} sh_info[OPEN_MAX];
FILE *popen(const char *shell_cmd, const char *mode)
{
int fifo[2];
if ((strcmp(mode , "r") && strcmp(mode, "w")) || pipe(fifo) == -1)
return 0;
switch (sh_info[num_sh].sh_pid = fork())
{
case -1: perror("fork"); return 0;
case 0: (*mode == 'r') ? dup2(fifo[1], STDOUT_FILENO) :
dup2(fifo[0], STDIN_FILENO);
close(fifo[0]);
close(fifo[1]);
execl("/bin/sh", "sh", "-c", shell_cmd, 0);
exit(5);
}
if (*mode == 'r')
{
close(fifo[1]);
return (sh_info[num_sh++].stream = fdopen(fifo[0], mode));
}
else
{
close(fifo[0]);
return (sh_info[num_sh++].stream = fdopen(fifo[1], mode));
}
}
int pclose(FILE *fstream)
{
int i, status, rc = -1;
for (i = 0; i < num_sh; i++)
if (sh_info[i].stream == fstream)
break;
if (i == num_sh) return -1;
close(fstream);
if (waitpid(sh_info[i].sh_pid, &status, 0) == sh_info[i].sh_pid || WIFEXITED(status))
rc = WEXITSTATUS(status);
for (i++; i < num_sh; i++)
sh_info[i-1] = sh_info[i];
num_sh--;
return rc;
}