Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
16
Добавлен:
01.05.2014
Размер:
2.01 Кб
Скачать
#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <string.h>

#include <limits.h>



struct sh_rec

{

pid_t sh_pid;

FILE* stream;

} sh_info[OPEN_MAX];

static int num_sh;



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; /* invalid fstream value */

fclose(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;

}

int main (int argc, char* argv[])

{

char buf[256], *mode= (argc>2) ? "w" : "r";

FILE *fptr;



if (argc>1 && (fptr = popen(argv[1],mode)))

{

switch (*mode)

{

case 'r': while (fgets(buf,256,fptr)) fputs(buf,stdout);

break;

case 'w': fprintf(fptr,"%s\n",argv[2]);

}

return pclose(fptr);

}

return 5;

}
Соседние файлы в папке ch8