Reputation: 327
Got no warning compiling with gcc -Wall -W -g3 <inputfile.c> but binary doesn't show anything and not getting $ prompt. gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13). I've taken it from the book Unix System Programming by Keith Haviland. Example of read() call.
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#define BUFSIZE 512
int main()
{
char buffer[BUFSIZE];
int fd;
ssize_t nread;
long total = 0;
if( (fd = open("fi.txt", O_RDONLY) == -1)){
printf("error in opening file\n");
exit(1);
}
while( (nread = read(fd, buffer, BUFSIZE))>0)
total += nread;
printf("Total characters: %ld\n", total);
exit(0);
}
I can't understand what gdb shows. fi.txt contains only one word, Hello.
:
.
(gdb) s
13 if( (fd = open("fi.txt", O_RDONLY) == -1)){
(gdb) s
open () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) print fd
No symbol "fd" in current context.
(gdb) s
0xb7fdbbd0 in __kernel_vsyscall ()
(gdb) s
Single stepping until exit from function __kernel_vsyscall,
which has no line number information.
main () at usp5.c:17
17 while( (nread = read(fd, buffer, BUFSIZE))>0)
(gdb) print fd
$1 = 0
(gdb) s
read () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) s
0xb7fdbbd0 in __kernel_vsyscall ()
(gdb) s
Single stepping until exit from function __kernel_vsyscall,
which has no line number information.
s
main () at usp5.c:19
19 printf("Total characters: %ld\n", total);
(gdb) print total
$2 = 0
(gdb) print nread
$3 = 2
(gdb) s
__printf (format=0x804863d "Total characters: %ld\n") at printf.c:28
28 printf.c: No such file or directory.
(gdb) print total
No symbol "total" in current context.
(gdb) s
__x86.get_pc_thunk.bx () at ../sysdeps/i386/i686/multiarch/strcat.S:55
55 ../sysdeps/i386/i686/multiarch/strcat.S: No such file or directory.
(gdb) s
__printf (format=0x804863d "Total characters: %ld\n") at printf.c:32
32 printf.c: No such file or directory.
(gdb) s
33 in printf.c
(gdb) list
28 in printf.c
(gdb) s
_IO_vfprintf_internal (s=0xb7fb4e80 <_IO_2_1_stdout_>, format=0x804863d "Total characters: %ld\n",
ap=0xbfffed84 "") at vfprintf.c:222
222 vfprintf.c: No such file or directory.
(gdb) list
......
It goes on and on printing similar messages.
Upvotes: 0
Views: 420
Reputation: 70981
[too long for a comment:]
Referring best practise debugging: If seemingly simple code fails, look for hidden unnecessarily complex but essential constructs and take them apart. In the case you show there are two such constructs:
Opening the file:
if ((fd = open("fi.txt", O_RDONLY) == -1))
{
perror("open() failed");
...
This could be written:
fd = open("fi.txt", O_RDONLY);
if (fd == -1)
{
perror("open() failed");
...
Reading from the file:
while ((nread = read(fd, buffer, BUFSIZE)) > 0)
The could be written:
nread = read(fd, buffer, BUFSIZE);
while(nread > 0)
{
...
nread = read(fd, buffer, BUFSIZE);
}
if (nread == -1) /* Add as much error checking as possible. */
{
perror("read() failed)");
}
Or more using only one call to read()
, but separating error handling, for the cost of an additional if
this way:
do
{
nread = read(fd, buffer, BUFSIZE);
if (nread == -1) /* Add as much error checking as possible. */
{
perror("read() failed)");
}
else
{
...
}
} while (nread > 0);
Upvotes: 0
Reputation: 30597
You have misplaced brackets here:
if( (fd = open("fi.txt", O_RDONLY) == -1)){
which results in fd being set to 0, rather than the return value of open. Thus you are actually reading from fd 0 (STDIN).
It should be:
if( (fd = open("fi.txt", O_RDONLY)) == -1){
Upvotes: 3
Reputation: 5763
I think you just make a low level mistake:
change this line code:
if( (fd = open("fi.txt", O_RDONLY) == -1)){
to
if( (fd = open("fi.txt", O_RDONLY)) == -1){
then you will get correct result.
because your code will make fd = 0, and 0 is the stdin, so the progrm always wait your input.
Upvotes: 1