Sim. Tem a ver com ^D realmente faz: basta parar a chamada atual read(2) .
Se o programa fizer int rdbytes = read(fd, buffer, sizeof buffer); e você pressionar ^D inbetween, read() retornará com os bytes atualmente lidos no buffer, retornando seu número. O mesmo acontece na terminação da linha; o \n no final é sempre entregue.
Portanto, apenas ^D no início de uma linha ou após a outra ^D tem o efeito desejado de ter read() return 0 , sinalizando EOF.