0

I know how to (more or less) do this in C:

#include <stdio.h>
#include <string.h>

int
main(int argc, char** argv)
{
  char buf[BUFSIZ];
  fgets(buf, sizeof buf, stdin); // reads STDIN into buffer `buf` line by line
  if (buf[strlen(buf) - 1] == '\n')
  {
    printf("%s", buf);
  }
  return 0;
}

The desired end result being to read STDIN from a pipe, if present. (I know the above code doesn't do that, but I couldn't figure out how to only do the above when reading from a pipe/heredoc).

How would I do something similar in Chicken Scheme?

Like I said before, the end goal is to be able to do this:

echo 'a' | ./read-stdin
# a

./read-stdin << EOF
a
EOF
# a

./read-stdin <<< "a"
 # a

./read-stdin <(echo "a")
 # a

./read-stdin < <(echo "a")
 # a
Alexej Magura
  • 4,833
  • 3
  • 26
  • 40
  • Once any one of the first three works, the other two will work. The fourth one provides a file name on the command line that the `read-stdin` program would have to open and read. Maybe you meant to write: `./read-stdin < <(echo "a")` which redirects to standard input; then once one works, they all work. – Jonathan Leffler Mar 20 '14 at 15:30
  • @JonathanLeffler what does that have to do with anything? The zsh examples with `read-stdin` are just that: examples. In zsh both `cat < <(echo a)` and `cat <(echo a)` have the same result. I don't actually have a `read-stdin` program that actually does the above, I was just trying to illustrate what the end result was supposed to be. – Alexej Magura Mar 20 '14 at 15:33
  • 2
    There is a difference between `cat < <(echo a)` and `cat <(echo a)`; in the first, the shell opens the file, but in the second `cat` does. So, the last example requires different action from your putative `read-stdin` program from the other examples. Other than that, it doesn't progress you towards an answer, I'm afraid. I'd help if I knew anything of Chicken Scheme but I'd never heard of it before your question, and I know little enough about Scheme (but I have sort of used it for things barely more complex than 'hello world'). – Jonathan Leffler Mar 20 '14 at 16:24

1 Answers1

0

Figured it out.

;; read-stdin.scm

(use posix)
;; let me know if STDIN is coming from a terminal or a pipe/file
(if (terminal-port? (current-input-port))
   (fprintf (current-error-port) "~A~%" "stdin is a terminal") ;; prints to stderr
   (fprintf (current-error-port) "~A~%" "stdin is a pipe or file"))
;; read from STDIN
(do ((c (read-char) (read-char)))
   ((eof-object? c))
   (printf "~C" c))
(newline)

According to the Chicken wiki, terminal-port? is Chicken's equivalent to C's isatty() function.

NOTE

The above example works best when compiled. Running it with csi seems to make terminal-port? always return true, but perhaps adding an explicit call to (exit) and th end of the file would cause the Chicken Scheme interpreter to exit, thus allowing STDIN to be something other than a terminal?

Alexej Magura
  • 4,833
  • 3
  • 26
  • 40