pipe.scm 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber, Ivan Shmakov
  3. ; Scheme analogues of Posix popen() and pclose() library calls.
  4. ; Create a pipe and exec COMMAND to talk to one end of the pipe while
  5. ; PROC is handed the other end. If INPUT? is true PROC gets the input
  6. ; end of the pipe and COMMAND gets the output end.
  7. (define (call-with-mumble-pipe input?)
  8. (lambda (command proc . may-be-port)
  9. (call-with-values open-pipe
  10. (lambda (input-pipe output-pipe)
  11. (let ((pid (fork)))
  12. (if pid
  13. ; Parent
  14. (let ((proc-port (if input? input-pipe output-pipe)))
  15. (close-port (if input? output-pipe input-pipe))
  16. (call-with-values
  17. (lambda ()
  18. (proc proc-port))
  19. (lambda vals
  20. (close-port proc-port)
  21. (wait-for-child-process pid)
  22. (apply values vals))))
  23. ; Child
  24. (dynamic-wind
  25. (lambda ()
  26. #f)
  27. (lambda ()
  28. (define port
  29. (and (not (null? may-be-port))
  30. (car may-be-port)))
  31. (if input?
  32. (remap-file-descriptors! (or
  33. port
  34. (current-input-port))
  35. output-pipe
  36. (current-error-port))
  37. (remap-file-descriptors! input-pipe
  38. (or
  39. port
  40. (current-output-port))
  41. (current-error-port)))
  42. (cond ((list? command)
  43. (apply exec command))
  44. (else
  45. ;; FIXME: consider using "$SHELL" here
  46. (exec-file "/bin/sh" "-c" command))))
  47. (lambda ()
  48. (exit 1)))))))))
  49. (define (close-port port)
  50. (if (input-port? port)
  51. (close-input-port port)
  52. (close-output-port port)))
  53. (define call-with-input-pipe
  54. (call-with-mumble-pipe #t))
  55. (define call-with-output-pipe
  56. (call-with-mumble-pipe #f))