Using O_Rdwr vs O_Rdonly | O_Wronly

In my simple program:

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

using namespace std;

int main(int argc, char *argv[]) {
    stringstream ss;
    ss << "What does the quick brown fox say?" << endl;

    int file_descriptor = open("/dev/tty", O_RDONLY | O_WRONLY);
    write(file_descriptor, ss.str().c_str(), ss.str().size());
}

I open the terminal stream using the combination O_RDONLY | O_WRONLY, and this seems to work fine. I get that you should use O_RDWR because it makes clearer semantic sense, but my question is why bother creating a whole other flag if joining two existing flags already works? Is there some historical reason for this, or am I just overlooking something, and this really doesn't actually work?

3

2 Answers

O_RDONLY | O_WRONLY (at least on my Linux machine) is not the same thing as O_RDWR.

#define O_RDONLY         00
#define O_WRONLY         01
#define O_RDWR           02

The fact that it works seems like a bug/feature/coincidence rather than "it works because it should work that way".

4

From Linux manual page for open(2):

Unlike the other values that can be specified in flags, the access mode values O_RDONLY, O_WRONLY, and O_RDWR do not specify individual bits. Rather, they define the low order two bits of flags, and are defined respectively as 0, 1, and 2. In other words, the combination O_RDONLY | O_WRONLY is a logical error, and certainly does not have the same meaning as O_RDWR.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Sarah Jenkins

Sarah Jenkins

Senior Technology Editor & AI Specialist

Sarah Jenkins is a veteran tech journalist with over 12 years of experience covering artificial intelligence, mobile innovations, and digital ethics. Her insights have appeared in leading technology publications worldwide.

Share this article
Twitter Facebook Pinterest