pipe.scm 1.7 KB

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