c – linux, write() system call returns -1 while attempting to write to file – Education Career Blog

In the below program write() returns -1 while writing to a file.

   #include<sys/types.h>
   #include<sys/stat.h> 
   #include<fcntl.h>   
   #include<stdio.h>   
   #include<unistd.h> 
   #include<stdlib.h>
   int main() {

   int fd_r=0,fd_w=0;
   int w_ret=100;
   fd_r = open("reader.txt", O_RDONLY);

   fd_w = open("writer.txt",O_CREAT,S_IRWXU);

   char *buf = (char *)malloc(50);

   while(read(fd_r,buf,30))
   {

          w_ret =   write(fd_w,buf,30);
          printf("%d", w_ret);
   }
}

Questions: I am unable to debug why this is happening. Correction of code and suggestions as to how to debug such issues are highly appreciated

,

I don’t believe that O_CREAT is valid by itself for the flags: try O_CREAT | O_WRONLY.

One way to debug would be checking that the fd_w file descriptor is valid when you first open it.

“The parameter flags is one of O_RDONLY, O_WRONLY or O_RDWR which request opening the file read-only, write-only or read/write, respectively, bitwise-or’d with zero or more of the following…” http://www.linuxmanpages.com/man2/open.2.php

,

at the top of your program

#include <errno.h>

when your open or read returns -1, print the value of errno (defined in errno.h), then look in errno.h for what that error means (you will need this throughout your C life, so I gave you all of this rather than just the solution to this problem)

,

If you add some error handling, you can learn more. e.g.

  #include<sys/types.h>
   #include<sys/stat.h>
   #include<fcntl.h>
   #include<stdio.h>
   #include<unistd.h>
   #include<stdlib.h>
   int main() {

   int fd_r=0,fd_w=0;
   int w_ret=100;
   fd_r = open("reader.txt", O_RDONLY);
   if(fd_r == -1)
     perror("fd_r open");

   fd_w = open("writer.txt",O_CREAT,S_IRWXU);
   if(fd_w == -1)
     perror("fd_w open");

   char *buf = (char *)malloc(50);

   while(read(fd_r,buf,30))
   {

          w_ret =   write(fd_w,buf,30);
          if(w_ret == -1) {
            perror("write");
            break;
          }
          printf("%d", w_ret);
   }
}

When run , if “reader.txt” does not exist:

$ ./a.out
fd_r open: No such file or directory
write: Bad file descriptor

I.e. not surprisingly, open() failed because the file is missing.

When run, and “reader.txt” does exist:

$ ./a.out
write: Bad file descriptor

This is a bit more subtle, but the documentation for write (man 2 write) says:

EBADF fd is not a valid file
descriptor or is not open for writing.

Well. open() didn’t fail, so we do have a valid file descriptor. So it’s “is not open for writing.”

And indeed:

 open("writer.txt",O_CREAT,S_IRWXU);

Should be:

  open("writer.txt",O_CREAT|O_WRONLY,S_IRWXU);

Leave a Comment