Search code examples
cfile-descriptor

Is any operation needed prior to write(fd,...?


I wrote code below

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main() {

    int fd = 3;
    char c[100] = "Testing\n";
    ssize_t nbytes = write(fd, (void *) c, strlen(c));
    return 0;
}

compiled/linked, and executed

$ ./io
$ ./io 3> io_3.txt

The first line produced no output. The second line gave me file io_3.txt containing Testing. This is all expected behaviour (I guess).

Even if in my tests it produced the expected output, I am not certain if, to avoid potential problems, undefined behavior, etc., I should do anything prior to the first write, like checking if fd=3 is in use (and in that case, how... this may apply), if it is suitably open, etc.

And I am not certain if I should perform some action after the last write, for the same reasons.

Perhaps the way I did is "non-risky", the only potential issue being that nothing is written, which I could detect by checking the value of nbytes... I wouldn't know.

Any clarification is welcome.


Solution

  • If you write a program like this, executing it without fd 3 open is a usage bug. Normally the only file descriptors that should be used by number without having opened them yourself are 0 (stdin), 1 (stdout), and 2 (stderr). If a program needs to take additional pre-opened file descriptors as input, the standard idiom is to pass the fd numbers on the command line or environment variables rather than hard-coding them. For example:

    int main(int argc, char **argv) {
        if (argc<2 || !isdigit(argv[1][0])) return 1;
        int fd = strtol(argv[1], 0, 0);
        char c[100] = "Testing\n";
        ssize_t nbytes = write(fd, (void *) c, strlen(c));
        return 0;
    }
    

    In practice, a trivial program like yours is probably safe with the write just failing if fd 3 wasn't open. But as soon as you do anything that might open file descriptors (possibly internal to the implementation, like syslog, or date/time functions opening timezone data, or message translation catalogs, etc.), it might happen that fd 3 now refers to such an open file, and you wrongly attempt a write to it. Using file descriptors like this is a serious bug.