ib_popen.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * Copyright (c) 2003 Gunnar Ritter
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute
  10. * it freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. *
  17. * 2. Altered source versions must be plainly marked as such, and must not be
  18. * misrepresented as being the original software.
  19. *
  20. * 3. This notice may not be removed or altered from any source distribution.
  21. */
  22. /* Sccsid @(#)ib_popen.c 1.2 (gritter) 4/17/03 */
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <sys/wait.h>
  26. #include <fcntl.h>
  27. #include <unistd.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include <stdlib.h>
  31. #include <signal.h>
  32. #include "iblok.h"
  33. struct iblok *
  34. ib_popen(const char *cmd, unsigned blksize)
  35. {
  36. struct iblok *ip;
  37. int fd[2], err;
  38. pid_t pid;
  39. char *shell;
  40. if (pipe(fd) < 0)
  41. return NULL;
  42. switch (pid = fork()) {
  43. case -1:
  44. return NULL;
  45. case 0:
  46. close(fd[0]);
  47. dup2(fd[1], 1);
  48. close(fd[1]);
  49. if ((shell = getenv("SHELL")) == NULL)
  50. shell = "/bin/sh";
  51. execl(shell, shell, "-c", cmd, NULL);
  52. _exit(0177);
  53. /*NOTREACHED*/
  54. }
  55. close(fd[1]);
  56. if ((ip = ib_alloc(fd[0], blksize)) == NULL) {
  57. err = errno;
  58. close(fd[0]);
  59. errno = err;
  60. }
  61. ip->ib_pid = pid;
  62. return ip;
  63. }
  64. int
  65. ib_pclose(struct iblok *ip)
  66. {
  67. struct sigaction oldhup, oldint, oldquit, act;
  68. int status;
  69. close(ip->ib_fd);
  70. act.sa_handler = SIG_IGN;
  71. sigemptyset(&act.sa_mask);
  72. act.sa_flags = 0;
  73. sigaction(SIGHUP, &act, &oldhup);
  74. sigaction(SIGINT, &act, &oldint);
  75. sigaction(SIGQUIT, &act, &oldquit);
  76. while (waitpid(ip->ib_pid, &status, 0) < 0 && errno == EINTR);
  77. sigaction(SIGHUP, &oldhup, NULL);
  78. sigaction(SIGINT, &oldint, NULL);
  79. sigaction(SIGQUIT, &oldquit, NULL);
  80. return status;
  81. }