Bad file descriptor
Asked Answered
B

4

22

I'm learning about file descriptors and I wrote this code:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int fdrd, fdwr, fdwt;
char c;

main (int argc, char *argv[]) {

    if((fdwt = open("output", O_CREAT, 0777)) == -1) {
        perror("Error opening the file:");
        exit(1);
    }

    char c = 'x';

    if(write(fdwt, &c, 1) == -1) {
        perror("Error writing the file:");
    }

    close(fdwt);
    exit(0);

}

, but I'm getting: Error writing the file:: Bad file descriptor

I don't know what could be wrong, since this is a very simple example.

Bromberg answered 5/6, 2011 at 19:57 Comment(2)
What is the val of fdwt on return from open( )? It should be a small integer, like less than 5. In fact, because no other fds are open in this code, it should be 3 (i.e., STDERR + 1).Propagandist
Incidentally, your code has several problematic bits. Those variables don't need to be global (few ever do), you should declare them in main. You also declare c twice, you don't need the char in char c the second time. At the same time, the second declaration of c in the middle of the function is only valid in C99, but you declare main without a return type -- which is invalid in C99, which eliminates the "implicit int" rule that was present in C89 and earlier versions of C. Most compilers should issue warnings for that, some will throw an error and refuse to compile.Caloric
S
31

Try this:

open("output", O_CREAT|O_WRONLY, 0777)
Shrier answered 5/6, 2011 at 20:2 Comment(4)
Wow! So fast! :) That worked! Now I have to find out why! Thank you very much!Bromberg
@Bromberg - It gave you a file descriptor, so the open didn't fail ... but the descriptor was not valid for writing.Pastry
Could you explain why O_WRONLY is required, and where 0777 comes from?Thremmatology
0777 is honestly a bad idea from a security perspective (but it's what the OP already had). The "other" permissions shouldn't contain write without a very good reason, nor should random data files be created with execute.Villagomez
F
11

According to the open(2) man page:

The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR.

So yes, as suggested by others, please change your open to open("output", O_CREAT|O_WRONLY, 0777));. Use O_RDWR if you need to read from the file. You may also want O_TRUNC -- see the man page for details.

Frayne answered 5/6, 2011 at 20:7 Comment(0)
M
10

I think O_CREAT alone is not enough. Try adding O_WRONLY as flag to the open command.

Meill answered 5/6, 2011 at 20:1 Comment(0)
C
0

My problem was that I used the S_IRUSR constant, which then, combined with O_CREAT created a file that can't be written to. So first run was OK, but on the second run I got the Bad file descriptor error message.

Using S_IRUSR | S_IWUSR solved the problem. Of course the badly created files have to be deleted.

int outfd = open("output.ppm", O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
Coppins answered 8/4, 2023 at 12:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.