Question

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
Was it helpful?

Solution

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?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top