Skip to content

fix setting pipe buffer size #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
import io
import os
import platform
import sys
import time
from fcntl import fcntl
from tempfile import TemporaryFile
from unittest import mock

import pytest

import wurlitzer
from wurlitzer import (
PIPE,
Expand Down Expand Up @@ -158,3 +162,18 @@ def test_pipe_max_size():
assert 65535 <= max_pipe_size <= 1024 * 1024
else:
assert max_pipe_size is None


@pytest.mark.skipif(
wurlitzer._get_max_pipe_size() is None, reason="requires _get_max_pipe_size"
)
def test_bufsize():
default_bufsize = wurlitzer._get_max_pipe_size()
with wurlitzer.pipes() as (stdout, stderr):
assert fcntl(sys.__stdout__, wurlitzer.F_GETPIPE_SZ) == default_bufsize
assert fcntl(sys.__stderr__, wurlitzer.F_GETPIPE_SZ) == default_bufsize

bufsize = 32768 # seems to only accept powers of two?
with wurlitzer.pipes(bufsize=bufsize) as (stdout, stderr):
assert fcntl(sys.__stdout__, wurlitzer.F_GETPIPE_SZ) == bufsize
assert fcntl(sys.__stderr__, wurlitzer.F_GETPIPE_SZ) == bufsize
14 changes: 7 additions & 7 deletions wurlitzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
try:
from fcntl import F_SETPIPE_SZ
except ImportError:
# ref: linux fcntl.h
# ref: linux uapi/linux/fcntl.h
F_SETPIPE_SZ = 1024 + 7
F_GETPIPE_SZ = 1024 + 8

libc = ctypes.CDLL(None)

Expand Down Expand Up @@ -200,17 +201,16 @@ def _setup_pipe(self, name):
self._save_fds[name] = save_fd

pipe_out, pipe_in = os.pipe()
dup2(pipe_in, real_fd)
os.close(pipe_in)
self._real_fds[name] = real_fd

# set max pipe buffer size (linux only)
if self._bufsize:
try:
fcntl(pipe_in, F_SETPIPE_SZ, self._bufsize)
except OSError:
# ignore failure to set pipe size
pass
warnings.warn("Failed to set pipe buffer size", RuntimeWarning)

dup2(pipe_in, real_fd)
os.close(pipe_in)
self._real_fds[name] = real_fd

# make pipe_out non-blocking
flags = fcntl(pipe_out, F_GETFL)
Expand Down