Solved

Detect where input comes from: stdin or using "<"

Posted on 2004-09-09
24
205 Views
Last Modified: 2010-04-15
Hi,

My program recieves commands (one by one), and executes them.
It can be ran with a filename (./my_prog 01.in),
or without parameters (in this case stdin will be used).

If the input comes from a file, I print the command on screen.
If the input comes from stdin, I don't print (because it's already on screen).

The problem is that one can run the program this way:
./my_prog < 01.in
The program will know it recieves commands not from a file, and won't print
the command, but it won't be visible on screen too.

How can I detect if the input comes from stdin or using "<"?
0
Comment
Question by:slavikn
  • 10
  • 6
  • 5
  • +1
24 Comments
 
LVL 46

Expert Comment

by:Sjef Bosman
ID: 12014383
See
    man fstat
0
 
LVL 1

Author Comment

by:slavikn
ID: 12014419
Sorry, I didn't found the info I need. Could you please be more specific?
0
 
LVL 46

Expert Comment

by:Sjef Bosman
ID: 12014518
Sorry.

The fstat systemcall will give you info about an open filedescriptor.
    int fstat(int filedescr, struct stat *buf)

You have to include sys/types.h, sys/stat.h and unistd.h, on Linux that is.

There are several macros defined, like S_ISREG to find out if the file is a regular file, etc.

Search Google using linux fstat, all manuals are on the Internet.
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 45

Expert Comment

by:sunnycoder
ID: 12014754
Hi slavikn,

ls -l /proc/<pid>/fd

or

cat /proc/<pid>/cmdline

first will give you the name of the file which 0 points to ... If it is not a tty and your program does not run in background, then you have a file ... you can verify it using stat or fstat

cmdline method will give you the command line that was used to start your process ... You can search for redirection using strchr

getpid() will give you the pid of your process ... you can use popen() to launch the cat command and read in the result

refer to their man pages for more information. If you need any clarifications, feel free to post back.

cheers
sunnycoder
0
 
LVL 22

Expert Comment

by:grg99
ID: 12015310
try man "istty".    Note that it may be possible to fool istty().

0
 
LVL 1

Author Comment

by:slavikn
ID: 12015368
nova 335% man istty
No manual entry for istty
0
 
LVL 1

Author Comment

by:slavikn
ID: 12015382
cmdline also doesn't exist.
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 12015392
cmdline does not exist ? which nix are you on ?

what are the contents of /proc/<any pid>
0
 
LVL 1

Author Comment

by:slavikn
ID: 12015405
ah... I see... I hav to read that file...
/proc/<pid>/cmdline

if the user has minimal rights (UNIX), won't there be access problems?
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 12015414
Not if you own the process
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 12015418
I meant ... there will be no rights issues if you own the process ... A normal user can inspect proc for its own processes only
0
 
LVL 1

Author Comment

by:slavikn
ID: 12015441
Thanks sunnycoder. I accepted your anwser.
Is there a more elegant way to read the result of "cat" than pipes?
Well, pipes ARE elegant, but I thought there might be something simpler...
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 12015459
popen is perhaps the simplest one to use ...

I must add that this solution has limited portability as all (?) linux support proc filesystem but other platforms like windows and some unix do not
0
 
LVL 1

Author Comment

by:slavikn
ID: 12015556
> I must add that this solution has limited portability as all (?) linux support proc filesystem but other platforms like windows and some unix do not

Don't worry about that. It's a university project (an SQL interpreter, i.e. parses and performs SQL commands on virtual database) which will be checked on Unix in the labs.  :-)
0
 
LVL 1

Author Comment

by:slavikn
ID: 12015574
Oops.... I accepted when I saw that the command line was really in that file, BUT:
it shows the command until "<" , and stops there.
So I don't see if "<" was used or not.  :(
0
 
LVL 46

Expert Comment

by:Sjef Bosman
ID: 12015708
Did you even bother to try fstat? Why use a cannot to kill an ant?
0
 
LVL 1

Author Comment

by:slavikn
ID: 12015840
Give me a moment... I will
0
 
LVL 1

Author Comment

by:slavikn
ID: 12015981
First of all, I asked to cancel the acception of the incorrect answer.
Secondly, I've just tried fstat, but didn't manage to use it (read a couple of pages from google). I don't know which marco to use to find out whether "<" was used or not.
0
 
LVL 46

Accepted Solution

by:
Sjef Bosman earned 50 total points
ID: 12016110
http://www.die.net/doc/linux/man/man2/fstat.2.html

See in the middle somewhere, there are the macros described.

Easiest approach: write a very small program that only does an fstat on standard input. So little more than:

int main() {
    struct stat statbuf;

    fstat(0, &statbuf);
    printf("%d\n", S_ISREG(statbuf.st_mode));
    return 0;
}

Adapt it to your needs, then call
    prog
and
    prog < somefile
Test also
    cat somefile | prog

If < is used, then fstat will say that it's a regular file.
0
 
LVL 1

Author Comment

by:slavikn
ID: 12016503
Thanks 2/3 of it works.
This one: "cat 01.sql | ./sql04c"
prints "redirected_input = 0", though.
But never mind that. "<" is enough. Thanks.
I'll ask the moderators to accept your answer instead.
0
 
LVL 46

Expert Comment

by:Sjef Bosman
ID: 12016714
Try to
    printf("%ld\n", (long)statbuf.st_mode);
to see the differences (if any).

My Lunix-knowledge is getting a bit rusty, I'd have to try myself to find out what it does on my system. Some other day perhaps :)
0
 
LVL 46

Expert Comment

by:Sjef Bosman
ID: 12016724
Sorry, use
    "%lX\n"
to print it in hex.
0
 
LVL 22

Expert Comment

by:grg99
ID: 12016961
Sorry, minor type, should be "isatty":
ISATTY(3)           Linux Programmer's Manual           ISATTY(3)

NAME
       isatty - does this descriptor refer to a terminal

SYNOPSIS
       #include <unistd.h>

       int isatty ( int desc );

DESCRIPTION
       returns  1  if  desc  is an open descriptor connected to a
       terminal and 0 else.

CONFORMING TO
       SVID, AT&T, X/OPEN, BSD 4.3

SEE ALSO
       fstat(2), ttyname(3)

Linux                     April 20, 1995                        1


0

Featured Post

The New “Normal” in Modern Enterprise Operations

DevOps for the modern enterprise offers many benefits — increased agility, productivity, and more, but digital transformation isn’t easy, especially if you’re not addressing the right issues. Register for the webinar to dive into the “new normal” for enterprise modern ops.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

860 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question