Skip to content

sendfile for sockets neglects pseudo files on Linux#93300

@illia-v

Description

@illia-v

Bug report

socket.socket.sendfile and asyncio.base_events.BaseEventLoop.sock_sendfile rely on st_size to determine an amount of bytes to be sent if count is not provided.

But st_size is equal to zero for pseudo files like /proc/cpuinfo on Linux. Therefore, the methods send no data for such files.

Related code

cpython/Lib/socket.py

Lines 355 to 360 in a637c09

try:
fsize=os.fstat(fileno).st_size
exceptOSErroraserr:
raise_GiveupOnSendfile(err) # not a regular file
ifnotfsize:
return0# empty file

try:
fsize=os.fstat(fileno).st_size
exceptOSError:
raiseexceptions.SendfileNotAvailableError("not a regular file")
blocksize=countifcountelsefsize
ifnotblocksize:
return0# empty file

Example

Assuming nc -lkU some.sock and ./python -m asyncio run in the same directory:

>>>importasyncio>>>importsocket>>>sock=socket.socket(socket.AF_UNIX) >>>loop=asyncio.get_running_loop() >>>awaitloop.sock_connect(sock, "./some.sock") >>>withopen("/proc/cpuinfo", "rb") ascpuinfo_file: ... os.fstat(cpuinfo_file.fileno()).st_size ... awaitloop.sock_sendfile(sock, cpuinfo_file) ... sock.sendfile(cpuinfo_file) ... len(cpuinfo_file.read()) ... 00018294

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions