skip to Main Content

Hi I’m on Linux WSL Debian and I’ve the following code:

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

int main(int argc, char *argv[]) {
    int fd = open("file.dat", O_RDONLY | O_WRONLY);
    write(fd, "ciao", strlen("ciao"));
    close(fd);
}

Why don’t works?

2

Answers


  1. You need the header <unistd.h> to get the declarations of write() and close(). The only other header you need is <fcntl.h> for open().

    I’ve also kept <stdio.h> so I can use perror() if open() fails.

    Since you’re only writing to the file, you don’t need O_RDONLY in the open modes. If you want to read and write, you should use O_RDWR instead. These three flags are mutually exclusive.

    #include <unistd.h>
    #include <fcntl.h>
    #include <stdio.h>
    
    int main(int argc, char* argv[]) {
        int fd=open("file.dat",O_WRONLY);
        if (fd < 0) {
            perror("open failed");
            return 1;
        }
        write(fd,"ciao",strlen("ciao"));
        close(fd);
    }
    

    Note that this will not create the file if it doesn’t already exist. If you want that, you need to add the O_CREAT flag and another argument with the permissions that should be given to the file if it’s created.

    Login or Signup to reply.
  2. Many bugs:

    • Must include unistd.h for the declaration of write.
    • O_RDONLY and O_WRONLY (and O_RDWR) are mutually exclusive. If you want to open a file for read and write you have to use O_RDWR. Since you are not actually reading from the file, you should use O_WRONLY alone.
    • It is very rare to want to use O_WRONLY without O_CREAT and one (exactly one; these three are also mutually exclusive) of O_APPEND, O_EXCL, and O_TRUNC. Assuming that you do want O_CREAT, you must also supply a third argument, which should be the octal constant 0666 unless you have a specific reason to use some other value.
    • write(fd, "ciao", strlen("ciao")) should be write(fd, "ciaon", strlen("ciaon")) unless you have a specific reason to be creating a text file with an incomplete last line.
    • Because you are writing to a file, you need to check for errors on all three of the open, write, and close calls. (The fact that close can fail is a bug in its specification, but one that we are permanently stuck with. It’s safe to ignore errors in close for files that were opened for reading, but not writing.)

    Also some style corrections:

    • The code as shown only needs unistd.h, fcntl.h, and string.h; it should also be including stdio.h, because it should also be making calls to perror. None of the other headers should be included (unless this is cut down from a much larger program).
    • Declare main as int main(void) unless you are actually going to use argc and argv.
    • Don’t use the C99 license to fall off the end of main; the last line of main should be return 0;.
    • For historical reasons, in C, the opening curly brace of a function definition should always be placed on a line by itself, even if all other opening curly braces are "cuddled" with their parent control flow construct.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search