I know there are many questions here that talk about write, read system calls and file descriptors in C. I tried searching a bit but I really couldn't find what I'm looking for so...
EOF on new line when reading from STDIN_FILENO?
Let's say I have this code in test.c
:
int main(void){
char buff[8];
int res;
res=read(STDIN_FILENO, buff, 8);
assert(res!=-1);
res=write(STDOUT_FILENO, buff, res);
assert(res!=-1);
return 0
}
with header files included and all. Why do I have this behavior when executing the file test
?
$ ./test
1
1
$ ./test
11$
In the first execution I use a new line (enter) while in the second execution I use ctrl+d to put an eof. Why does a new line character act like an eof in this case?
I mean read should try to read 8 characters. Shouldn't it have waited in the first execution? what if I wanted to type '1\n2\n3'
in the buffer? How to make my program work?
I've got two ideas but I don't know how to verify them:
- Is this behavior related in any way to how processes read from a pipe? The idea of reading only what's in there even if more could be coming? If so: how to make the read call a blocking system call? (I hope I'm not misusing the term).
- Could the terminal be putting an EOF character when a new line character is typed? I don't think it's true but if I type
123456789
+enter while executingtest
stops taking input after the enter key, uses characters from 1 to 8 and the terminal executes 9 as command (which means it takes the 9 and the newline character). I just don't get it.
Why is the program still working if STDIN_FILENO and STDOUT_FILENO are switched by mistake?
So now I have another code, test2.c
:
int main(void){
char buff[8];
int res;
res=read(STDOUT_FILENO, buff, 8);
assert(res!=-1);
res=write(STDIN_FILENO, buff, res);
assert(res!=-1);
return 0;
}
And I have the same behavior in both cases. Why don't read and write fail with EBADF
? Could this be some subtle tty-shell interaction thing I'm not aware of?
Thanks!!
N.B: If you have any suggestions on how to improve this question or the title please let me know.