简体   繁体   中英

Create unbuffered file descriptor in C under linux

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 (eg /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).

So a call to write() will copy the contents directly into the buffer provided by read()

Is this even possible

No. Only when using splice() or sendfile() or similar system call. This strongly depends on what the actual file descriptor refers to.

is there always a buffer in between? If it's possible than how to achieve this?

No. You can:

  • fifo / pipe
    • use splice() or sendfile()
    • use shared memory instead
  • local or tcp socket
    • open /proc/mem and write directly into the hardware.
    • write/use a specific kernel device driver that does the same
    • (I do not know, but maybe copy_from_user allows copying straight to a hardware address)
  • using stdin/stdout
    • file descriptor is just a pointer - both stdin and stdout can refer to a tcp socket, to a fifo, or to anything else
    • this depends on what the file descriptor refers to
  • virtual kernel file (eg /proc/uptime)
    • depends on the actual "virtual kernel file" implementation
    • most, if not all, implement seeking/support partial reading or use struct seq_file , which has to have an intermediary buffer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM