1

This is my code :

#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#define FILE "./test.txt"
char buf[20]="Hello, World!";
int main()
{
    int fd;
    if((fd=open(FILE,O_EXCL|O_CREAT))==-1)
    {
        printf("File Already EXIST!\n");
        if((fd=open(FILE,O_RDWR))==-1)
        {
            perror("open error");
            exit(1);
        }
    }
    else 
    {
        if((fd=open(FILE,O_RDWR|O_CREAT,0666))==-1)
        {
            perror("create error");
            exit(1);
        }
    }
    if(write(fd,buf,sizeof(buf))==-1)
    {
        perror("write error");
        exit(1);
    }
    else printf("Write Done.\n");
    return 0;
}

When I run the program, strange things happen. The text file's mode is different each time I run it (to test the create function, I rm the text file after running the program). So, why does this happen?

tshepang
  • 12,111
  • 21
  • 91
  • 136
mtfly
  • 35
  • 6
  • It would be worth adding some debug output to find out which way the file was created. – Steve Barnes Oct 09 '13 at 04:53
  • 5
    `#define FILE "./test.txt"` is a bad idea. `FILE` is a struct defined in `` and it is used for standard (non-POSIX) file handling. **Just don't do this.** Fix your code and come back when you eliminated all the undefined behaviors. (Where, seriously, you people are getting these ideas??) –  Oct 09 '13 at 04:56
  • While I 100% agree that using `#define FILE` is horrid, it does not actually cause any problem (undefined behaviour) in this code (by fluke, for the most part, but still, no problems). – Jonathan Leffler Oct 09 '13 at 05:52

1 Answers1

2

You should compile with all warnings and debug info (gcc -Wall -g).

 #define FILE "./test.txt"

is inappropriate (conflicts with FILE from <stdio.h>) and should be

 #define FILE_NAME "./test.txt"

then

 if((fd=open(FILE,O_EXCL|O_CREAT))==-1)

is wrong. open(2) needs a third mode argument (when passing O_CREAT at least).

The kernel needs a mode when creating any file, e.g. thru open with O_CREAT. When opening an existing file, the mode is useless, so is documented as unneeded, but something useless is passed to the kernel.

Some garbage is passed instead of the missing third argument (and that explains the non-reproducible undefined behavior). Try instead

 fd = open(FILE_NAME, O_EXCL|O_CREAT, 0640);
 if (fd < 0)

BTW, you could also use strace(1) on your program to understand the syscalls it is doing.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547