For testing purposes I want to create a fully unbuffered file descriptor under linux in C. It shall have a reading and a writing side. It can be one of:
- fifo
- pipe
- local or tcp socket
- using stdin/stdout
- virtual kernel file (e.g. /proc/uptime)
(I think the list is complete)
So a call to write() will copy the contents directly into the buffer provided by read().
Is this even possible or is there always a buffer in between? If it's possible than how to achieve this?
This is my code:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char** argv)
{
int fd = socket(AF_INET, SOCK_STREAM, 0);
int len = 0;
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, 4);
struct sockaddr_in serv_addr = {};
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(80);
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
char buf;
read(fd, &buf, 1);
return 0;
}
But the data is not read directly into buf. The reason is that my setsockopt() call does not really set the receiving buffer to zero. Instead it is set to the minimum value 256 as can be read on man page socket(7).
No. Only when using
splice()
orsendfile()
or similar system call. This strongly depends on what the actual file descriptor refers to.No. You can:
splice()
orsendfile()
/proc/mem
and write directly into the hardware.copy_from_user
allows copying straight to a hardware address)struct seq_file
, which has to have an intermediary buffer.