3

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.

Rontogiannis Aristofanis
  • 8,883
  • 8
  • 41
  • 58

3 Answers3

4

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
Andreas Florath
  • 4,418
  • 22
  • 32
  • I'm copying your code, and your `#include`s but I get errors about the mode parameter `S_IREAD` `S_IREAD` "was not delcared in this scope. I've tried `S_IWUSR` and `S_IRUSR` too – John Jul 16 '14 at 13:15
2

The flag you use for opening the second file, O_WRONLY will not create the output file is this one don't exist, you may want to try other flags, like O_CREATE or O_APPEND. This link should be useful to you, as you may want to use several flags to handle file creation and behavior while writing in it ! Good luck =)

tsukasan
  • 118
  • 5
0

From opengroup

#include <fcntl.h>
...
int fd;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
char *filename = "/tmp/file";
...
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
...

just compare with your code.

Sergei Nikulov
  • 5,029
  • 23
  • 36