You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.1 KiB

  1. /*
  2. * Revision Control Information
  3. *
  4. * $Id: pipefork.c,v 1.7 2012/02/05 05:34:04 fabio Exp fabio $
  5. *
  6. */
  7. /* LINTLIBRARY */
  8. #include "util.h"
  9. #include <sys/wait.h>
  10. /*
  11. * util_pipefork - fork a command and set up pipes to and from
  12. *
  13. * Rick L Spickelmier, 3/23/86
  14. * Richard Rudell, 4/6/86
  15. * Rick L Spickelmier, 4/30/90, got rid of slimey vfork semantics
  16. *
  17. * Returns:
  18. * 1 for success, with toCommand and fromCommand pointing to the streams
  19. * 0 for failure
  20. */
  21. /* ARGSUSED */
  22. int
  23. util_pipefork(
  24. char * const *argv, /* normal argv argument list */
  25. FILE **toCommand, /* pointer to the sending stream */
  26. FILE **fromCommand, /* pointer to the reading stream */
  27. int *pid)
  28. {
  29. #ifdef UNIX
  30. int forkpid, waitPid;
  31. int topipe[2], frompipe[2];
  32. char buffer[1024];
  33. int status;
  34. /* create the PIPES...
  35. * fildes[0] for reading from command
  36. * fildes[1] for writing to command
  37. */
  38. if (pipe(topipe)) return(0);
  39. if (pipe(frompipe)) return(0);
  40. #ifdef __CYGWIN32__
  41. if ((forkpid = fork()) == 0) {
  42. #else
  43. if ((forkpid = vfork()) == 0) {
  44. #endif
  45. /* child here, connect the pipes */
  46. (void) dup2(topipe[0], fileno(stdin));
  47. (void) dup2(frompipe[1], fileno(stdout));
  48. (void) close(topipe[0]);
  49. (void) close(topipe[1]);
  50. (void) close(frompipe[0]);
  51. (void) close(frompipe[1]);
  52. (void) execvp(argv[0], argv);
  53. (void) sprintf(buffer, "util_pipefork: can not exec %s", argv[0]);
  54. perror(buffer);
  55. (void) _exit(1);
  56. }
  57. if (pid) {
  58. *pid = forkpid;
  59. }
  60. #ifdef __CYGWIN32__
  61. waitPid = waitpid(-1, &status, WNOHANG);
  62. #else
  63. waitPid = wait3(&status, WNOHANG, NULL);
  64. #endif
  65. /* parent here, use slimey vfork() semantics to get return status */
  66. if (waitPid == forkpid && WIFEXITED(status)) {
  67. return 0;
  68. }
  69. if ((*toCommand = fdopen(topipe[1], "w")) == NULL) {
  70. return 0;
  71. }
  72. if ((*fromCommand = fdopen(frompipe[0], "r")) == NULL) {
  73. return 0;
  74. }
  75. (void) close(topipe[0]);
  76. (void) close(frompipe[1]);
  77. return 1;
  78. #else
  79. (void) fprintf(stderr,
  80. "util_pipefork: not implemented on your operating system\n");
  81. return 0;
  82. #endif
  83. }