How can I read and write from files using the headers fcntl.h and unistd.h?

Rontogiannis Aristofanis picture Rontogiannis Aristofanis · Dec 22, 2012 · Viewed 19.4k times · Source

I'm trying to learn how to use the header files <fcntl.h> and <unistd.h>. I have created a small example to test the workings of their procedures, but it didn't work as expected. Here is my code:

#include <fcntl.h>
#include <unistd.h>

int main() {
  int in=open( "test.in", O_RDONLY, S_IREAD );
  int *a=new int[ 10 ];
  read( in, a, 10 );
  int out=open( "test.out", O_WRONLY, S_IWRITE );
  write( out, a, 10 );
  close( in ); close( out );
  return 0;
}

The input file was: 1 2 3 4 5 6 7 8 9 10

The program compiled normally, but it didn't create any output files. Could anyone tell me what is wrong with my code? Thanks in advance.

Answer

Andreas Florath picture Andreas Florath · Dec 22, 2012

Divide et impera.

The part for writing:

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

int main() {
  int const a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  int const out { open( "testnums.out", 
          O_WRONLY | O_CREAT, S_IWRITE | S_IREAD) };
  if(out==-1) {
    perror("Cannot open file");
    return 1;
  }
  ssize_t const written { write( out, a, sizeof(a) ) };
  if(written<0) {
    perror("Write error");
  }
  close( out );

  return 0;
}

When compiled and executed:

$ g++ -std=c++0x -Wall -Wextra tout.cc
$ ./a.out

it writes out the 'a' array:

$ hexdump testnums.out 
0000000 0001 0000 0002 0000 0003 0000 0004 0000
0000010 0005 0000 0006 0000 0007 0000 0008 0000
0000020 0009 0000 000a 0000                    
0000028

Please note that this is not portable - each compiler / architecture might have some different output here.

Here is the part to read this in again and write it to stdout:

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

int main() {

  int const in { open( "testnums.out", O_RDONLY ) };

  if(in==-1) {
    perror("Cannot open file");
    return 1;
  }

  int a[10];
  ssize_t const r { read( in, a, sizeof(a) ) };
  if(r!=sizeof(a)) {
    fprintf(stderr, "Could not read complete array.");
    return 1;
  }
  if(r<0) {
     perror("Read error");
     close(in);
     return 1;
  }
  close(in);

  for(unsigned int i(0); i<sizeof(a)/sizeof(int); ++i) {
    printf("%d ", a[i]);
  }
  printf("\n");

  return 0;
 }

Compile and execute:

$ g++ -std=c++0x -Wall -Wextra tin.cc
$ ./a.out
1 2 3 4 5 6 7 8 9 10 

General: In your code there are a lot of small issues (like: checking for return values is completely missing, not all needed header files are included, wrong number of bytes is written, ...) You might want to read the different man pages like

$ man 2 open
$ man 2 read
$ man 2 write
$ man 2 close