|
Home > Archive > Unix Programming > July 2006 > open returns lessthan equal to 2
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
open returns lessthan equal to 2
|
|
| gauravkadyan@gmail.com 2006-07-19, 8:04 am |
| Hi
I am having this code in a server
if ((fd = open (path, O_RDWR , 0660)) == FAIL)
{
FATAL_EXIT ();
}
else if (fd <= 2)/* stdio */
{
FATAL_EXIT ();
}
it does not always go into the "else if" part , but sometimes it does.
what i need to know is why does it go into elseif even though i havent
closed any of the stdout,stderr or stdin streams !!
Regards,
Gaurav Kadyan
| |
| Rainer Temme 2006-07-19, 8:04 am |
| gauravkadyan@gmail.com wrote:
> if ((fd = open (path, O_RDWR , 0660)) == FAIL)
> {
> FATAL_EXIT ();
> }
> else if (fd <= 2)/* stdio */
> {
> FATAL_EXIT ();
> }
> it does not always go into the "else if" part , but sometimes it does.
Gaurav,
open() is required to return the smallest available
filedescriptor on success. So, if it returs something in the
0,1,2 range, then this filedescriptor was available (meaning,
was not opened before this call to open). It is not necessarily
YOU who closed this filedescriptor, it can be either inherited
from the parentprocess, or elsewhere in the coding of your
server-process.
Don't forget, the fd's 0,1,2 are nothing special from the viewpoint
of low-level-IO. They can be used as all the other fds. Only
high-level-IO treats them as stdin, stdout,stderr. A programm that
doesn't use highlevel-IO can (in principle) use them for low-level-IO.
Warning: It is wise for a program that uses only low-level-IO (or that
doesn't use stdin.stdout,stderr) to close these fd's and open them on
/dev/null ... to avoid that they are used for normal low-level-IO.
This seems to contradict what I wrote before. Well, the reason is, that
there might be still some sick library-routines left, that use stderr to
output something. (I remember a "domain error" appearing on stderr, when
one of the exponential functions was called with an invalid argiment).
Rainer
| |
| Pascal Bourguignon 2006-07-19, 8:04 am |
| gauravkadyan@gmail.com writes:
> I am having this code in a server
>
> if ((fd = open (path, O_RDWR , 0660)) == FAIL)
> {
> FATAL_EXIT ();
> }
> else if (fd <= 2)/* stdio */
> {
> FATAL_EXIT ();
> }
>
> it does not always go into the "else if" part , but sometimes it does.
> what i need to know is why does it go into elseif even though i havent
> closed any of the stdout,stderr or stdin streams !!
The stdin=0,stdout=1,stderr=2 convention really depends on the calling
process. That's what is usually done by the shells, but what about an
application launched from a GUI manager? Or merely, a process
fork/exec'ed by a random program.
--
__Pascal Bourguignon__ http://www.informatimago.com/
PUBLIC NOTICE AS REQUIRED BY LAW: Any use of this product, in any
manner whatsoever, will increase the amount of disorder in the
universe. Although no liability is implied herein, the consumer is
warned that this process will ultimately lead to the heat death of
the universe.
| |
| Rainer Temme 2006-07-19, 8:04 am |
| Pascal Bourguignon wrote:
> The stdin=0,stdout=1,stderr=2 convention really depends on the calling
> process.
Yes, a point that is often forgotten ...
look at this small snippet of code:
$ cat x.c
#include <stdio.h>
int main(int c,char **v)
{
FILE *f;
int fd;
fclose(stdin);
fd=open("x.c",1);
printf("fd=%d\n",fd);
f=freopen(v[1],"r",stdin);
printf("f=%p stdin=%p fileno=%d\n",f,stdin,fileno(f));
}
$ x x.c
fd=0
f=0x40132720 stdin=0x40132720 fileno=3
first stdin is fclose()d
second an fd is opened on "x.c"
it gets fd==0 (to be expected)
stdin is reopened
the output shows, that f==stdin, and that now the fd associated with
stdin is no longer fd==0 but fd==3
Rainer
| |
| GauravKadyan 2006-07-19, 8:04 am |
| So that should mean that somewhere the code is actually closing the
stdio related fds !!
i will now investigate in that direction.
Thanks for your replies,
Gaurav Kadyan
Rainer Temme wrote:
> Pascal Bourguignon wrote:
>
>
> Yes, a point that is often forgotten ...
>
> look at this small snippet of code:
>
> $ cat x.c
>
> #include <stdio.h>
>
> int main(int c,char **v)
> {
> FILE *f;
> int fd;
>
> fclose(stdin);
> fd=open("x.c",1);
> printf("fd=%d\n",fd);
> f=freopen(v[1],"r",stdin);
> printf("f=%p stdin=%p fileno=%d\n",f,stdin,fileno(f));
> }
>
> $ x x.c
> fd=0
> f=0x40132720 stdin=0x40132720 fileno=3
>
> first stdin is fclose()d
> second an fd is opened on "x.c"
> it gets fd==0 (to be expected)
> stdin is reopened
> the output shows, that f==stdin, and that now the fd associated with
> stdin is no longer fd==0 but fd==3
>
> Rainer
| |
| davids@webmaster.com 2006-07-20, 7:51 am |
|
GauravKadyan wrote:
> So that should mean that somewhere the code is actually closing the
> stdio related fds !!
> i will now investigate in that direction.
If it only happens after awhile, then yes. If it happens immediately,
then you started out with the stdio related fds available and your
first 'open' got the lowest available 'fd'.
You should definitely sanitize your environment when your code starts
up. One thing to make sure is that fd's 0, 1, and 2 are in use. If not,
you can open "/dev/null" and put it there. You may also want to 'close'
any other fds you inherited if you weren't expecting them.
*If* getting <= 2 is a problem for you, then you need to make sure that
doesn't happen by burning fd's 0, 1, and 2 at process startup if they
are not in use. If that's not a problem, don't test for it. ;)
DS
|
|
|
|
|