What code can my program call to behave similarly to pressing Ctrl+D in a terminal? That is, to cause a read
function called on STDIN to return 0
in a child process, but without having this "STDIN" file descriptor closed in the parent process?
I'm trying to understand how the EOF condition is communicated to a process in Linux.
It appears read
returning 0
is only advisory, and you can actually carry on reading after encountering such an EOF condition. Consider the following program:
#include <unistd.h>
#include <stdio.h>
void terminate_buf(char *buf, ssize_t len)
{
if(len > 0) {
buf[len-1] = '\0';
} else {
buf[0] = '\0';
}
}
int main()
{
int r;
char buf[1024];
while(1) {
r = read(0, buf, 1024);
terminate_buf(buf, r);
printf("read %d bytes: %s\n", r, buf);
}
return 0;
}
If you compile (gcc -o reader reader.c
, assuming you named it reader.c) and run this program in a terminal, then press Ctrl+D, then input foobar
Enter, you will see this:
$ ./reader
read 0 bytes:
foobar
read 7 bytes: foobar
indicating it's totally possible to read meaningful data after an EOF event has occurred. You can press Ctrl+D multiple times on a line of its own, followed by some text, and reader
will carry on reading your data as if nothing had happened (after printing "read 0 bytes: " for each press of Ctrl+D). The file descriptor remains open.
So what's going on here and how can I replicate this behaviour? How can I cause a child process to see some data after seeing EOF? Is there a way to do it using just regular file I/O (and perhaps ioctl
s), or do I need to open a pty? Calling write
with a count of 0 doesn't seem to work, read
doesn't even return on the other end. What is EOF, really?
mypipe[1]
so that the child sees EOF onmypipe[0]
, and communication can keep on happening afterwards. As for the situation I'm trying to solve – there isn't any particular, but I am wondering if I can send multiple "logical" files to a process' stdin this way. – uukgoblin May 24 '20 at 22:51