 |
|
 |
|
|
 |
Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-06-07 06:19 PM
Machine 1 :
bash-3.00$ uname -a
SunOS <hostname> 5.10 Generic_118822-30 sun4u sparc SUNW,Sun-Fire-280R
bash-3.00$ gcc -v
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/
specs
gcc version 2.95.3 20010315 (release)
Machine 2:
bash-2.05b$ uname -a
Linux <hostname> 2.4.21-4.EL #1 Fri Oct 3 18:13:58 EDT 2003 i686 i686
i386 GNU/Linux
bash-2.05b$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --
disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-
redhat-linux
Thread model: posix
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-20)
bash-2.05b$ cat fgets_fail_test.c
#include<stdio.h>
#include <string.h>
#include<stdlib.h>
/* Demo fgets failed by Raxit Sheth & Gaurav Gupta */
int main()
{
char spcontent[100],sendrepfile[100];
FILE *spfp=NULL;
memset(sendrepfile,0,100);
strcpy(sendrepfile,"/tmp/filenotexists");
if ((spfp = fopen(sendrepfile, "r")) == (FILE *)NULL)
{
printf("error in opening file %s",sendrepfile);fflush(stdout);
}
memset(spcontent, 0, sizeof(spcontent));
while (fgets(spcontent,40, spfp)!=NULL)
{
printf("The value of spcontent is
[%s]",spcontent);fflush(stdout);;
}
return 0;
}
<simillar core dump occurs on both the system>
bash-2.05b$ gcc -Wall fgets_fail_test.c -o test
bash-2.05b$ ./test
error in opening file /tmp/filenotexistsSegmentation fault (core
dumped)
bash-2.05b$ gdb ./test ./core.27887
GNU gdb Red Hat Linux (5.3.90-0.20030710.40rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "i386-redhat-linux-gnu"...(no debugging
symbols found)...Using host libthread_db library "/lib/tls/
libthread_db.so.1".
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/tls/libc.so.6...(no debugging symbols
found)...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols
found)...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0xb7506444 in fgets () from /lib/tls/libc.so.6
(gdb) where
#0 0xb7506444 in fgets () from /lib/tls/libc.so.6
#1 0x0804854b in main ()
(gdb) frame 0
#0 0xb7506444 in fgets () from /lib/tls/libc.so.6
(gdb) print errno
Cannot access memory at address 0xb74a7008
char *fgets(char *s, int n, FILE *stream)
Qry : What is the Behaviour if stream is NULL. ?
As per our understanding fgets should return NULL < and internally
gets should put check on stream, if it is not NULL then only should do
additional access of stream.
please ignore if it is known and would be great if you can point out
in the implementation detail.
--Gaurav Gupta & Raxit Sheth
http://www.barcamp.org/BarCampMumbaiOct2007 <----BarCampMumbaiOct2007
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-06-07 06:19 PM
Sheth Raxit wrote:
[...]
> char *fgets(char *s, int n, FILE *stream)
> Qry : What is the Behaviour if stream is NULL. ?
>
> As per our understanding fgets should return NULL < and internally
> gets should put check on stream, if it is not NULL then only should do
> additional access of stream.
[...]
I see no direct reference in the standard to what should happen. The
closest thing I see (and it's not very close) is 7.19.3p4:
The value of a pointer to a FILE object is indeterminate after
the associated file is closed (including the standard text
streams).
However, I can tell you that the system I'm currently on has an
ASSERT(stream != NULL) near the top of fgets(), so it won't allow
such a value.
My guess is that this is UB.
--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:ThisIsASpamTrap@gmail.com>
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-07-07 12:20 AM
Sheth Raxit wrote:
> Machine 1 :
> bash-3.00$ uname -a
> SunOS <hostname> 5.10 Generic_118822-30 sun4u sparc SUNW,Sun-Fire-280R
>
> bash-3.00$ gcc -v
> Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/
> specs
> gcc version 2.95.3 20010315 (release)
>
>
> Machine 2:
> bash-2.05b$ uname -a
> Linux <hostname> 2.4.21-4.EL #1 Fri Oct 3 18:13:58 EDT 2003 i686 i686
> i386 GNU/Linux
>
> bash-2.05b$ gcc -v
> Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
> Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
> infodir=/usr/share/info --enable-shared --enable-threads=posix --
> disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-
> redhat-linux
> Thread model: posix
> gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-20)
>
>
>
> bash-2.05b$ cat fgets_fail_test.c
> #include<stdio.h>
> #include <string.h>
> #include<stdlib.h>
>
> /* Demo fgets failed by Raxit Sheth & Gaurav Gupta */
>
> int main()
> {
> char spcontent[100],sendrepfile[100];
> FILE *spfp=NULL;
> memset(sendrepfile,0,100);
> strcpy(sendrepfile,"/tmp/filenotexists");
> if ((spfp = fopen(sendrepfile, "r")) == (FILE *)NULL)
> {
> printf("error in opening file %s",sendrepfile);fflush(stdout);
> }
> memset(spcontent, 0, sizeof(spcontent));
>
> while (fgets(spcontent,40, spfp)!=NULL)
What do you expect this to do if spfp contains the NULL pointer? It is
supposed to contain a pointer to a stream (FILE *) so anything is possible.
Robert
> [snip]
>
> --Gaurav Gupta & Raxit Sheth
> http://www.barcamp.org/BarCampMumbaiOct2007 <----BarCampMumbaiOct2007
>
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-07-07 12:20 AM
Sheth Raxit wrote:
> Machine 1 :
> bash-3.00$ uname -a
> SunOS <hostname> 5.10 Generic_118822-30 sun4u sparc SUNW,Sun-Fire-280R
>
> bash-3.00$ gcc -v
> Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/
> specs
> gcc version 2.95.3 20010315 (release)
>
>
> Machine 2:
> bash-2.05b$ uname -a
> Linux <hostname> 2.4.21-4.EL #1 Fri Oct 3 18:13:58 EDT 2003 i686 i686
> i386 GNU/Linux
>
> bash-2.05b$ gcc -v
> Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
> Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
> infodir=/usr/share/info --enable-shared --enable-threads=posix --
> disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-
> redhat-linux
> Thread model: posix
> gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-20)
>
>
>
> bash-2.05b$ cat fgets_fail_test.c
> #include<stdio.h>
> #include <string.h>
> #include<stdlib.h>
>
> /* Demo fgets failed by Raxit Sheth & Gaurav Gupta */
>
> int main()
> {
> char spcontent[100],sendrepfile[100];
> FILE *spfp=NULL;
> memset(sendrepfile,0,100);
> strcpy(sendrepfile,"/tmp/filenotexists");
> if ((spfp = fopen(sendrepfile, "r")) == (FILE *)NULL)
> {
> printf("error in opening file %s",sendrepfile);fflush(stdout);
> }
> memset(spcontent, 0, sizeof(spcontent));
>
> while (fgets(spcontent,40, spfp)!=NULL)
> {
> printf("The value of spcontent is
> [%s]",spcontent);fflush(stdout);;
> }
> return 0;
> }
>
>
> <simillar core dump occurs on both the system>
> bash-2.05b$ gcc -Wall fgets_fail_test.c -o test
> bash-2.05b$ ./test
> error in opening file /tmp/filenotexistsSegmentation fault (core
> dumped)
> bash-2.05b$ gdb ./test ./core.27887
> GNU gdb Red Hat Linux (5.3.90-0.20030710.40rh)
> Copyright 2003 Free Software Foundation, Inc.
> GDB is free software, covered by the GNU General Public License, and
> you are
> welcome to change it and/or distribute copies of it under certain
> conditions.
> Type "show copying" to see the conditions.
> There is absolutely no warranty for GDB. Type "show warranty" for
> details.
> This GDB was configured as "i386-redhat-linux-gnu"...(no debugging
> symbols found)...Using host libthread_db library "/lib/tls/
> libthread_db.so.1".
>
> Core was generated by `./test'.
> Program terminated with signal 11, Segmentation fault.
> Reading symbols from /lib/tls/libc.so.6...(no debugging symbols
> found)...done.
> Loaded symbols for /lib/tls/libc.so.6
> Reading symbols from /lib/ld-linux.so.2...(no debugging symbols
> found)...done.
> Loaded symbols for /lib/ld-linux.so.2
> #0 0xb7506444 in fgets () from /lib/tls/libc.so.6
> (gdb) where
> #0 0xb7506444 in fgets () from /lib/tls/libc.so.6
> #1 0x0804854b in main ()
> (gdb) frame 0
> #0 0xb7506444 in fgets () from /lib/tls/libc.so.6
> (gdb) print errno
> Cannot access memory at address 0xb74a7008
>
>
> char *fgets(char *s, int n, FILE *stream)
> Qry : What is the Behaviour if stream is NULL. ?
>
> As per our understanding fgets should return NULL < and internally
> gets should put check on stream, if it is not NULL then only should do
> additional access of stream.
>
> please ignore if it is known and would be great if you can point out
> in the implementation detail.
>
>
> --Gaurav Gupta & Raxit Sheth
> http://www.barcamp.org/BarCampMumbaiOct2007 <----BarCampMumbaiOct2007
>
The C99 standard of C says:
7.19.7.2 The fgets function
Synopsis
#include <stdio.h>
char *fgets(char * restrict s, int n, FILE * restrict stream);
Description
The fgets function reads at most one less than the
number of characters specified by n from the stream
pointed to by stream into the array pointed to by s.
No additional characters are read after a new-line
character (which is retained) or after end-of-file.
A null character is written immediately after the
last character read into the array.
Returns
The fgets function returns s if successful. If
end-of-file is encountered and no characters have been
read into the array, the contents of the array remain
unchanged and a null pointer is returned. If a read
error occurs during the operation, the array contents
are indeterminate and a null pointer is returned.
----------------------------------------------------
Nothing is said about
File stream is NULL
int n is <= 0
char *s is NULL
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-07-07 12:20 AM
Sheth Raxit <raxitsheth2000@gmail.com> writes:
> Machine 1 :
> bash-3.00$ uname -a
[SNIP]
> Machine 2:
> bash-2.05b$ uname -a
[SNIP]
The details of your system aren't relevant to your problem. (If they
were, comp.lang.c probably wouldn't be the place to ask about it.)
I've redirected followups to comp.lang.c (which probably won't do any
good.)
> bash-2.05b$ cat fgets_fail_test.c
> #include<stdio.h>
> #include <string.h>
> #include<stdlib.h>
>
> /* Demo fgets failed by Raxit Sheth & Gaurav Gupta */
>
> int main()
> {
> char spcontent[100],sendrepfile[100];
> FILE *spfp=NULL;
> memset(sendrepfile,0,100);
> strcpy(sendrepfile,"/tmp/filenotexists");
> if ((spfp = fopen(sendrepfile, "r")) == (FILE *)NULL)
> {
> printf("error in opening file %s",sendrepfile);fflush(stdout);
> }
> memset(spcontent, 0, sizeof(spcontent));
>
> while (fgets(spcontent,40, spfp)!=NULL)
> {
> printf("The value of spcontent is
> [%s]",spcontent);fflush(stdout);;
> }
> return 0;
> }
>
>
> <simillar core dump occurs on both the system>
[SNIP]
The formatting of your code makes it difficult to read. Here's a
cleaned-up version:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Demo fgets failed by Raxit Sheth & Gaurav Gupta */
int main()
{
char spcontent[100], sendrepfile[100];
FILE *spfp = NULL;
memset(sendrepfile, 0, 100);
strcpy(sendrepfile, "/tmp/filenotexists");
if ((spfp = fopen(sendrepfile, "r")) == (FILE *)NULL)
{
printf("error in opening file %s", sendrepfile);
fflush(stdout);
}
memset(spcontent, 0, sizeof(spcontent));
while (fgets(spcontent, 40, spfp) != NULL)
{
printf("The value of spcontent is [%s]", spcontent);
fflush(stdout);
}
return 0;
}
You check whether the fopen() call succeeded or not. If it fails, you
print an error message.
You then attempt to read from the file *even if the fopen() call
failed*.
fgets() is not required to check whether its third argument is valid;
it can simply assume that it is. The standard's description (I'll use
'*'s to denote boldface) is:
The *fgets* function reads at most one less than the number of
characters specified by *n* from the stream pointed to by *stream*
into the array pointed to by *s*.
If there is no "stream pointed to by *stream*", then the behavior is
undefined. A segmentation fault is not surprising.
If you fail to open the file, don't try to read from it.
A few other remarks:
You don't use anything from <stdlib.h>.
'int main(void)' is preferred to 'int main()', though both are valid.
Avoid "magic numbers" like 100. Define a symbolic constant so that
you only have to change it in one place. You use a literal 100 in one
memset call, sizeof() in the other.
Both memsets are unnecessary. spcontent and sendrepfile are used to
hold strings; it doesn't matter what's in the array past the
terminating '\0'.
The cast to FILE* is unnecessary (as are most casts); you can just
compare the result of fopen() to NULL.
You print your error message to stdout. Error messages should normally
be written to stderr.
Your outputs should be terminated with '\n' unless you have a specific
reason not to. In particular, you should definitely have a '\n' at
the very end of your program's output.
The fflush(stdout) calls should be on lines by themselves; I almost
didn't notice them before I reformatted your code.
You declare spcontent as an array of 100 characters, but you only
attempt read at most 40 characters into it. Using symbolic constants
(say, '#define MAX_LINE_LENGTH 40') would make it easier to keep these
consistent.
You have a double semicolon on the second fflush() call. It happens
to be harmless, but there's no reason for it.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-07-07 12:20 AM
Sheth Raxit wrote:
<snip>
> <simillar core dump occurs on both the system>
> bash-2.05b$ gcc -Wall fgets_fail_test.c -o test
> bash-2.05b$ ./test
> error in opening file /tmp/filenotexistsSegmentation fault (core
> dumped)
<snip>
> char *fgets(char *s, int n, FILE *stream)
> Qry : What is the Behaviour if stream is NULL. ?
Then the behaviour is undefined, meaning that anything can happen
(including a crash as you experienced).
fgets() is defined to read characters from the stream pointed at by the
argument stream, but a null-pointer does not refer to any stream.
>
> As per our understanding fgets should return NULL < and internally
> gets should put check on stream, if it is not NULL then only should do
> additional access of stream.
Your understanding is incorrect. There is no such requirement for
fgets().
The fgets() implementation may simply assume that all pointers passed
into it are valid. Some may have implemented a precondition check on
this assumption, but that is certainly not universal. And a failed
check may just as easily be regarded as a fatal error.
>
> please ignore if it is known and would be great if you can point out
> in the implementation detail.
>
>
> --Gaurav Gupta & Raxit Sheth
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-07-07 06:20 AM
On Thu, 06 Sep 2007 20:27:49 +0200, jacob navia
<jacob@jacob.remcomp.fr> wrote in comp.lang.c:
[snip original post]
> The C99 standard of C says:
>
> 7.19.7.2 The fgets function
> Synopsis
> #include <stdio.h>
> char *fgets(char * restrict s, int n, FILE * restrict stream);
> Description
> The fgets function reads at most one less than the
> number of characters specified by n from the stream
> pointed to by stream into the array pointed to by s.
> No additional characters are read after a new-line
> character (which is retained) or after end-of-file.
> A null character is written immediately after the
> last character read into the array.
>
> Returns
> The fgets function returns s if successful. If
> end-of-file is encountered and no characters have been
> read into the array, the contents of the array remain
> unchanged and a null pointer is returned. If a read
> error occurs during the operation, the array contents
> are indeterminate and a null pointer is returned.
> ----------------------------------------------------
> Nothing is said about
>
> File stream is NULL
> int n is <= 0
> char *s is NULL
I would expect better from an implementer:
"7.1.4 Use of library functions
1 Each of the following statements applies unless explicitly stated
otherwise in the detailed descriptions that follow: If an argument to
a function has an invalid value (such as a value outside the domain of
the function, or a pointer outside the address space of the program,
or a null pointer, or a pointer to non-modifable storage when the
corresponding parameter is not const-qualifed) or a type (after
promotion) not expected by a function with variable number of
arguments, the behavior is undefined."
This makes passing a null pointer to almost all library functions
illegal, without requiring such text in each and every single function
description.
There are several functions that specifically document accepting null
pointers, such as free(), strto..., and a few others. fgets() is not
among them.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-07-07 06:20 AM
On Thu, 06 Sep 2007 10:38:55 -0700, Sheth Raxit
<raxitsheth2000@gmail.com> wrote in comp.lang.c:
[snip]
> char *fgets(char *s, int n, FILE *stream)
> Qry : What is the Behaviour if stream is NULL. ?
>
> As per our understanding fgets should return NULL < and internally
> gets should put check on stream, if it is not NULL then only should do
> additional access of stream.
Where does your understanding come from? It is totally incorrect.
> please ignore if it is known and would be great if you can point out
> in the implementation detail.
Section 7.1.4 paragraph 1 of the C language standard makes it quite
clear that passing a null pointer to a function that does not document
accepting a null pointer is undefined behavior.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-07-07 12:24 PM
On Sep 7, 1:08 pm, Casper H.S. Dik <Casper....@Sun.COM> wrote:
> Kenneth Brody <kenbr...@spamcop.net> writes:
>
> Since he's not passing a pointer to a STREAM I'd also say it's UB.
Yes It is Undefined Behaviour, But Don't you feel, standard **should**
impose this to return NULL.
I am asking to first make change in standard to have "few Undefined
Behaviour" when platform can handle. Technically platform may return
NULL, and handle this test case. Let me know if i am buffling
something/everything. ?
-Raxit
>
> Casper
> --
> Expressed in this posting are my opinions. They are in no way related
> to opinions held by my employer, Sun Microsystems.
> Statements on Sun products included here are not gospel and may
> be fiction rather than truth.
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Qry : Behaviour of fgets -- ? |
 |
 |
|
|
09-07-07 12:24 PM
On Sep 7, 1:36 pm, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
> On 6 Sep, 18:38, Sheth Raxit <raxitsheth2...@gmail.com> wrote:
>
> <snip>
>
>
>
>
> why the strcpy()? why not:-
This is not a point of Query ? why are we having trouble with strcpy/
individual coding style ?
Is it not confirming to std. ?
ignored
[ Post a follow-up to this message ]
|
|
|
 |
|
|
|
|
Sponsored Links |
 |
 |
|
|
 |
All times are GMT. The time now is 07:07 PM. |
 |
|
|
 |
|
 |
|
|
 |
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
|
|
|
|
Medical and Health forum | Computer Games Reviews | Graphics design forum
|
 |
|
 |
|