popen.c 691 B

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. #include "stdio_impl.h"
  2. FILE *popen(const char *cmd, const char *mode)
  3. {
  4. int p[2];
  5. int op;
  6. pid_t pid;
  7. FILE *f;
  8. const char *modes = "rw", *mi = strchr(modes, *mode);
  9. if (mi) {
  10. op = mi-modes;
  11. } else {
  12. errno = EINVAL;
  13. return 0;
  14. }
  15. if (pipe(p)) return NULL;
  16. f = fdopen(p[op], mode);
  17. if (!f) {
  18. close(p[0]);
  19. close(p[1]);
  20. return NULL;
  21. }
  22. pid = fork();
  23. switch (pid) {
  24. case -1:
  25. fclose(f);
  26. close(p[0]);
  27. close(p[1]);
  28. return NULL;
  29. case 0:
  30. if (dup2(p[1-op], 1-op) < 0) _exit(127);
  31. if (p[0] != 1-op) close(p[0]);
  32. if (p[1] != 1-op) close(p[1]);
  33. execl("/bin/sh", "sh", "-c", cmd, (char *)0);
  34. _exit(127);
  35. }
  36. close(p[1-op]);
  37. f->pipe_pid = pid;
  38. return f;
  39. }