parameters or stdin

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David Warner

    parameters or stdin

    Greetings!

    I need to write some C code that will decide between either reading from
    stdin or take a file name from argv and process it.

    The program needs to work like all of the typical unix utilities where
    the file to process is either provided from a pipe/stream or argv.

    Utilities like lp, tr, grep, etc.

    So, when the command:

    cat filename | grep -i > filename2

    or

    grep -i filename > filename2

    executes, this acts like the programmtic interface i need.

    I have tried everything I can think of from getc, getchar, read, gets,
    etc. which all did not work. I test for EOF or NULL on the return values
    and the program just hangs on a terminal read. So, the command:

    cat filename | testprogram -dvalue

    hangs on the reading from stdin and I never get to test for EOF.

    What am i missing?

    Do I need to set some type of fcntl flag and control the stdin flow
    similar to a wait/nowait process?

    BTW, i am compiling this on HP-UX B.11.00 Unix.

    I need an answer ASAP!

    Thanks in advance!
  • ade ishs

    #2
    Re: parameters or stdin

    David Warner wrote:[color=blue]
    > Greetings!
    >
    > I need to write some C code that will decide between either reading from
    > stdin or take a file name from argv and process it.
    >
    > The program needs to work like all of the typical unix utilities where
    > the file to process is either provided from a pipe/stream or argv.
    >
    > Utilities like lp, tr, grep, etc.
    >
    > So, when the command:
    >
    > cat filename | grep -i > filename2
    >
    > or
    >
    > grep -i filename > filename2
    >
    > executes, this acts like the programmtic interface i need.
    >
    > I have tried everything I can think of from getc, getchar, read, gets,
    > etc. which all did not work. I test for EOF or NULL on the return values
    > and the program just hangs on a terminal read. So, the command:
    >
    > cat filename | testprogram -dvalue
    >
    > hangs on the reading from stdin and I never get to test for EOF.
    >
    > What am i missing?[/color]

    Probably you can show your code to see what's missing. This one works.

    $ cat simplecat.c
    #include <stdio.h>
    #include <stdlib.h>

    #define BUF_SIZE 100

    int main(int argc, char ** argv)
    { char buf[BUF_SIZE + 1];
    FILE * inp;

    if(argc == 2)
    { inp = fopen(argv[1], "r");
    if(!inp)
    { return EXIT_FAILURE;
    }
    }
    else
    { inp = stdin;
    }
    while(fgets(buf , sizeof buf, inp))
    { printf("%s", buf);
    }
    fclose(inp);
    return EXIT_SUCCESS;
    }


    ishs

    Comment

    • Richard Tobin

      #3
      Re: parameters or stdin

      In article <dawarner-B2B38A.18263027 062005@corp.sup ernews.com>,
      David Warner <dawarner@westb ase.com> wrote:
      [color=blue]
      >I need to write some C code that will decide between either reading from
      >stdin or take a file name from argv and process it.[/color]
      [color=blue]
      >I have tried everything I can think of from getc, getchar, read, gets,
      >etc. which all did not work. I test for EOF or NULL on the return values
      >and the program just hangs on a terminal read.[/color]

      The usual thing to do it to see whether there's a filename argument
      and read from stdin if there isn't. Trying to read is useless, since
      there will always be either a file or a terminal on stdin (for typical
      operating systems).

      -- Richard

      Comment

      • #2pencil

        #4
        Re: parameters or stdin

        I did the exact same thing on HP-UX... this is how my code starts...

        main(int argc, char *argv[])
        {
        if (argc > 1) {


        if the arguments are greater than 1 (1 being the command) then process
        them, else use a default. I wrote this to check the similarties
        between 2 files. They are allways the same, but this way I can use it
        to check whatever 2 files I wish. I can option to add file names or
        use defaults.

        Hope this helps,
        -#2pencil-


        Comment

        • Michael Wojcik

          #5
          Re: parameters or stdin


          In article <d9riun$1b4e$2@ pc-news.cogsci.ed. ac.uk>, richard@cogsci. ed.ac.uk (Richard Tobin) writes:[color=blue]
          >
          > The usual thing to do it to see whether there's a filename argument
          > and read from stdin if there isn't. Trying to read is useless, since
          > there will always be either a file or a terminal on stdin (for typical
          > operating systems).[/color]

          Unix is atypical? A great many Unix processes are executed with
          neither a file nor a terminal associated with stdin. Some have
          nothing associated with stdin (for Unix implementations , this
          means descriptor 0 does not refer to an open entry in the file
          table); many more have other types of system objects associated
          with stdin.

          The language requires that (for a hosted implementation) at program
          startup stdin be "predefined " and "need not be opened explicitly".
          That doesn't mean that it must refer to something that can success-
          fully be read. It's entirely possible that the first attempt to
          read from stdin will result in EOF or an error.

          None of that helps with the OP's question, of course.

          --
          Michael Wojcik michael.wojcik@ microfocus.com

          This book uses the modern technology to explain the phenomemon in the world
          of Japanese animation. If you love anime so much, you'd better read this.
          After you read it, you may agree that is destroying the dream of the child.
          Needs Chinese viewing system. -- The Goodboy Scientific

          Comment

          • Richard Tobin

            #6
            Re: parameters or stdin

            In article <da17hd01b2u@ne ws4.newsguy.com >,
            Michael Wojcik <mwojcik@newsgu y.com> wrote:[color=blue][color=green]
            >> Trying to read is useless, since
            >> there will always be either a file or a terminal on stdin (for typical
            >> operating systems).[/color][/color]
            [color=blue]
            >Unix is atypical? A great many Unix processes are executed with
            >neither a file nor a terminal associated with stdin.[/color]

            I was referring to programs run from the command line, which was what
            the OP seemed interested in.

            -- Richard

            Comment

            • Michael Wojcik

              #7
              Re: parameters or stdin


              In article <da1qr7$8g7$1@p c-news.cogsci.ed. ac.uk>, richard@cogsci. ed.ac.uk (Richard Tobin) writes:[color=blue]
              > In article <da17hd01b2u@ne ws4.newsguy.com >,
              > Michael Wojcik <mwojcik@newsgu y.com> wrote:[color=green][color=darkred]
              > >> Trying to read is useless, since
              > >> there will always be either a file or a terminal on stdin (for typical
              > >> operating systems).[/color][/color]
              >[color=green]
              > >Unix is atypical? A great many Unix processes are executed with
              > >neither a file nor a terminal associated with stdin.[/color]
              >
              > I was referring to programs run from the command line, which was what
              > the OP seemed interested in.[/color]

              Perhaps. We all write code that makes some assumptions. I merely
              wanted to point out that this one - that stdin could be read
              successfully - was not always justified.

              It's not true of programs started from the Unix command line, either.
              In ksh:

              $ cat <&-
              cat: cannot stat

              Does anyone do that? Yes. (After all, the operator is there for a
              reason.) I recently had to use this myself, to run a program (that
              I couldn't modify) in the background with no controlling terminal
              association.

              Many Unix programs can assume that stdin is associated with a
              readable entity at program startup, because their failure mode if
              it is not is acceptable. Some cannot. I've dealt with programs
              that had security holes if they opened a file and it received
              descriptor 0, 1, or 2, because they assumed that stdin, stdout,
              and stderr were valid at program startup.

              --
              Michael Wojcik michael.wojcik@ microfocus.com

              Thanks for your prompt reply and thanks for your invitatin to your
              paradise. Based on Buddihism transmigration, I realize you, European,
              might be a philanthropist in previous life! -- supplied by Stacy Vickers

              Comment

              • Richard Tobin

                #8
                Re: parameters or stdin

                In article <da459e0lut@new s4.newsguy.com> ,
                Michael Wojcik <mwojcik@newsgu y.com> wrote:
                [color=blue]
                >Perhaps. We all write code that makes some assumptions. I merely
                >wanted to point out that this one - that stdin could be read
                >successfully - was not always justified.[/color]

                The assumption relevant to this discussion is not that stdin can be
                read. On the contrary, it's that the fact that stdin *can* be read
                implies nothing about whether it's the intended input for the program.
                I see no harm in ignoring the corner cases of unix when explaining how
                to decide where to read input from.

                To reiterate the possibly lost point: decide where to read from based
                on the arguments, not on the state of stdin.

                -- Richard

                Comment

                • CBFalconer

                  #9
                  Re: parameters or stdin

                  Richard Tobin wrote:[color=blue]
                  > Michael Wojcik <mwojcik@newsgu y.com> wrote:
                  >[color=green]
                  >> Perhaps. We all write code that makes some assumptions. I
                  >> merely wanted to point out that this one - that stdin could be
                  >> read successfully - was not always justified.[/color]
                  >
                  > The assumption relevant to this discussion is not that stdin can
                  > be read. On the contrary, it's that the fact that stdin *can* be
                  > read implies nothing about whether it's the intended input for the
                  > program. I see no harm in ignoring the corner cases of unix when
                  > explaining how to decide where to read input from.
                  >
                  > To reiterate the possibly lost point: decide where to read from
                  > based on the arguments, not on the state of stdin.[/color]

                  On most systems it is possible to decide whether or not stdin is
                  connected to an interactive keyboard with slightly non-portable
                  code (which in turn can be replaced by something that reports
                  not-a-keyboard portably). This allows some easy up-front
                  decisions, such as whether to emit a help screen and exit. Very
                  useful for filters.

                  --
                  "If you want to post a followup via groups.google.c om, don't use
                  the broken "Reply" link at the bottom of the article. Click on
                  "show options" at the top of the article, then click on the
                  "Reply" at the bottom of the article headers." - Keith Thompson


                  Comment

                  • Joe Wright

                    #10
                    Re: parameters or stdin

                    CBFalconer wrote:[color=blue]
                    > Richard Tobin wrote:
                    >[color=green]
                    >>Michael Wojcik <mwojcik@newsgu y.com> wrote:
                    >>
                    >>[color=darkred]
                    >>>Perhaps. We all write code that makes some assumptions. I
                    >>>merely wanted to point out that this one - that stdin could be
                    >>>read successfully - was not always justified.[/color]
                    >>
                    >>The assumption relevant to this discussion is not that stdin can
                    >>be read. On the contrary, it's that the fact that stdin *can* be
                    >>read implies nothing about whether it's the intended input for the
                    >>program. I see no harm in ignoring the corner cases of unix when
                    >>explaining how to decide where to read input from.
                    >>
                    >>To reiterate the possibly lost point: decide where to read from
                    >>based on the arguments, not on the state of stdin.[/color]
                    >
                    >
                    > On most systems it is possible to decide whether or not stdin is
                    > connected to an interactive keyboard with slightly non-portable
                    > code (which in turn can be replaced by something that reports
                    > not-a-keyboard portably). This allows some easy up-front
                    > decisions, such as whether to emit a help screen and exit. Very
                    > useful for filters.[/color]

                    Pray tell. Given foo, a program which takes no arguments and expects
                    input from stdin, I might invoke it two ways..

                    foo

                    in which case I am expected to enter data from the keyboard or..

                    foo < infile

                    in which case data comes to stdin from a file. How can I know from
                    within foo, which way foo was invoked?

                    --
                    Joe Wright
                    "Everything should be made as simple as possible, but not simpler."
                    --- Albert Einstein ---

                    Comment

                    • Chris Croughton

                      #11
                      Re: parameters or stdin

                      On Sat, 02 Jul 2005 10:02:57 -0400, Joe Wright
                      <joewwright@com cast.net> wrote:
                      [color=blue]
                      > CBFalconer wrote:[color=green]
                      >>
                      >> On most systems it is possible to decide whether or not stdin is
                      >> connected to an interactive keyboard with slightly non-portable
                      >> code (which in turn can be replaced by something that reports
                      >> not-a-keyboard portably). This allows some easy up-front
                      >> decisions, such as whether to emit a help screen and exit. Very
                      >> useful for filters.[/color]
                      >
                      > Pray tell. Given foo, a program which takes no arguments and expects
                      > input from stdin, I might invoke it two ways..
                      >
                      > foo
                      >
                      > in which case I am expected to enter data from the keyboard or..
                      >
                      > foo < infile
                      >
                      > in which case data comes to stdin from a file. How can I know from
                      > within foo, which way foo was invoked?[/color]

                      You can't do it portably. The C standard has no concept of what (if
                      anything) might be attached to stdin (or stdout or stderr for that
                      matter) or any other file stream.

                      OFF TOPIC:

                      On some systems there is an operating system call like isatty(int fd)
                      which returns a true value if the file descriptor (not FILE pointer)
                      refers to an interactive device. For instance, on a POSIX system (like
                      most modern Unix-derived ones) see



                      You will need to pass it the value 0 (zero) for the file descriptor of
                      stdin, or you can get the file descriptor of any FILE pointer using
                      fileno()



                      Windows with the POSIX layer installed may also support those functions
                      in console mode, as may some other non-Unix systems, but you need to
                      read the manuals for your system. Hopefully the above will give a clue
                      where to look. So on a POSIX compliant system you could write:

                      if (!isatty(fileno (stdin)))
                      {
                      fprintf(stderr, "Input not interactive!\n" );
                      exit(EXIT_FAILU RE);
                      }

                      However, there is no guarantee that a human is on the other end, it
                      could be a serial port connected to another computer for instance.

                      As CBFalconer said, you can then wrap those in a function of your own in
                      a module which is known to be implementation specific, so that the rest
                      of your code will be portable (and on a system without any way of
                      determining what is connected to stdin can just always return false or
                      whatever).

                      Chris C

                      Comment

                      • CBFalconer

                        #12
                        Re: parameters or stdin

                        Joe Wright wrote:[color=blue]
                        > CBFalconer wrote:
                        >[/color]
                        .... snip ...[color=blue][color=green]
                        >>
                        >> On most systems it is possible to decide whether or not stdin is
                        >> connected to an interactive keyboard with slightly non-portable
                        >> code (which in turn can be replaced by something that reports
                        >> not-a-keyboard portably). This allows some easy up-front
                        >> decisions, such as whether to emit a help screen and exit. Very
                        >> useful for filters.[/color]
                        >
                        > Pray tell. Given foo, a program which takes no arguments and
                        > expects input from stdin, I might invoke it two ways..
                        >
                        > foo
                        >
                        > in which case I am expected to enter data from the keyboard or..
                        >
                        > foo < infile
                        >
                        > in which case data comes to stdin from a file. How can I know
                        > from within foo, which way foo was invoked?[/color]

                        It is not properly portable, but I use the following, which is
                        arranged so that I do not have to inhibit proper checking in the
                        rest of the C file. If it doesn't work simply replace it by
                        something that does "return 0" and you are back where you are now.
                        The usage is simply:

                        if (akeyboard(stdi n)) helpandexit();
                        else {
                        /* use the redirected stdin */
                        }

                        and it is all independent of whether or not foo takes arguments.

                        /* ------------------- */

                        /* This is very likely to be non-portable */
                        /* DOES NOT check fp open for reading */
                        /* NULL fp is considered a keyboard here! */
                        static int akeyboard(FILE *fp)
                        {
                        #ifndef __TURBOC__ /* Turbo C is peculiar */
                        # ifdef __STDC__
                        /* This dirty operation allows gcc -ansi -pedantic */
                        extern int fileno(FILE *fp);
                        extern int isatty(int fn);
                        # endif
                        #endif
                        return ((fp != NULL) && isatty(fileno(f p)));
                        } /* akeyboard */

                        --
                        "If you want to post a followup via groups.google.c om, don't use
                        the broken "Reply" link at the bottom of the article. Click on
                        "show options" at the top of the article, then click on the
                        "Reply" at the bottom of the article headers." - Keith Thompson


                        Comment

                        Working...