SKM
SKM

Reputation: 29

Error while reading a file after creat system call

I am creating a file in read/write mode and writing a string into it. Then I am trying to read it into a buffer where I get read error.


#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int main()
{
    int fd,count,fd1;
    char buf[10];
    fd=creat("./smarak",S_IRWXU);
    if(fd<0)
    {
        perror("creat");
    }
    count=write(fd,"Hello smarak",7);
    printf("count=%d\n",count);
    count=read(fd,buf,7);
    printf("buf=%s\n",buf);
    printf("%d\n",count);
}

I get nothing in buf and also count is -1 which is read error. Why this error? Isn't it possible to read a file created by creat() system call?

Upvotes: 1

Views: 512

Answers (2)

Chandru
Chandru

Reputation: 1334

use lseek() function to set the position to the specified.

Try to use open() system call instead of creat() system call.

When you use creat() it will open the process as

root@Lenovo-G585:/proc/6988/fd$ ls -la
total 0
dr-x------ 2 root root  0 Sep 18 16:20 .
dr-xr-xr-x 8 root root  0 Sep 18 16:20 ..
lrwx------ 1 root root 64 Sep 18 16:20 0 -> /dev/pts/4
lrwx------ 1 root root 64 Sep 18 16:20 1 -> /dev/pts/4
lrwx------ 1 root root 64 Sep 18 16:20 2 -> /dev/pts/4
l-wx------ 1 root root 64 Sep 18 16:20 3 -> /tmp/smarak
 ^ 

Look ^ here.

The read permission is missing so you cannot able to read from that file. If you use open() system call like

fd=open("./smarak",O_CREAT|O_RDWR);

O_CREAT - Which is used to create a new file if doesn't exist.
O_RDWR  - Which is used to open a file for read and write mode.

By using open with the given argument, you can do your requirement. When using creat() it will open the file in O_CREAT|O_WRONLY|O_TRUNC.

O_TRUNC - Which is used to truncate remove the file content and keep 
          the cursor position in start of file.

Note: While using creat() it will truncate the file if already exist.

Upvotes: 0

DevSolar
DevSolar

Reputation: 70223

You need to reposition between writing and reading:

 count=write(fd,"Hello smarak",7);
 printf("count=%d\n",count);

 // added:
 if ( lseek( fd, 0, SEEK_SET ) < 0 )
 {
     perror("lseek");
 }

 count=read(fd,buf,7);
 printf("buf=%s\n",buf);
 printf("%d\n",count);

After your write, the current position in the file is right after what you have written. If you want to read that back in, you have to "rewind" the current position to the beginning of the file.

Check man lseek for details.

And I don't know how Unix calls handle this, but the C standard (C99, 7.19.5.3 The fopen function, section 6) has this to say:

[...] output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.

So you might be looking at undefined behaviour in your code sample.

Upvotes: 3

Related Questions