Solved

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

Posted on 2004-09-09
24
200 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
Comment Utility
See
    man fstat
0
 
LVL 1

Author Comment

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

Expert Comment

by:Sjef Bosman
Comment Utility
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
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
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
Comment Utility
try man "istty".    Note that it may be possible to fool istty().

0
 
LVL 1

Author Comment

by:slavikn
Comment Utility
nova 335% man istty
No manual entry for istty
0
 
LVL 1

Author Comment

by:slavikn
Comment Utility
cmdline also doesn't exist.
0
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
cmdline does not exist ? which nix are you on ?

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

Author Comment

by:slavikn
Comment Utility
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
Comment Utility
Not if you own the process
0
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 1

Author Comment

by:slavikn
Comment Utility
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
Comment Utility
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
Comment Utility
> 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
Comment Utility
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
Comment Utility
Did you even bother to try fstat? Why use a cannot to kill an ant?
0
 
LVL 1

Author Comment

by:slavikn
Comment Utility
Give me a moment... I will
0
 
LVL 1

Author Comment

by:slavikn
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Sorry, use
    "%lX\n"
to print it in hex.
0
 
LVL 22

Expert Comment

by:grg99
Comment Utility
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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
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 for-loops in the C programming language.

772 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now