Files
Jakub ZelenkaandDavid Carlier 32a0f3b6cf IO copy API for stream copying (#20399)
This introduces new API for fd copying and modifies
php_stream_copy_to_stream_ex to use it. The implementation is separated
for various platforms and the end result have couple of implications:

- sendfile is used for copying file to generic fd (e.g. sockets) on all
  platforms except Windows that use TransmitFile
- splice is used for copying between generic fds (e.g. sockets) on
  Linux
- copy_file_range should get used on alpine linux with directly using
  syscall (as musl does not seem to implement it)
- copy_file_range is used in the loop so it is used multiple times for
  files bigger than 2GB on Linux.
- file mmap for copying is removed as it allowed crashing PHP when
  another process modified mapped file - this was used as a fallback
  for file copying. Sendfile should partially replace it.
- File to file copying was optimized on Windows with use of ReadFile
  and WriteFile.

This also adds various tests including Linux unit tests.

Closes GH-20399

Co-authored-by: David Carlier <devnexen@gmail.com>
2026-07-19 17:15:16 +02:00

35 lines
1.1 KiB
Makefile

CC = gcc
CFLAGS = -g -Wall -I../../ -I../../Zend -I../../main -I../../TSRM -I. -I..
COMMON_LDFLAGS = ../../.libs/libphp.a -lcmocka -lpthread -lm -ldl -lresolv -lutil
# Update paths in .github/workflows/unit-tests.yml when adding new test to make it run in PR when such file changes
TESTS = main/test_network main/test_io_copy
main/test_network_SRC = main/test_network.c
main/test_network_LDFLAGS = $(COMMON_LDFLAGS) -Wl,--wrap=connect,--wrap=poll,--wrap=getsockopt,--wrap=gettimeofday
main/test_io_copy_SRC = main/test_io_copy.c
main/test_io_copy_LDFLAGS = $(COMMON_LDFLAGS) -Wl,--wrap=copy_file_range,--wrap=sendfile,--wrap=splice,--wrap=read,--wrap=write,--wrap=poll,--wrap=setsockopt
# Build all tests
all: $(TESTS)
# Build rule for each test
$(TESTS):
$(CC) $(CFLAGS) -o $@.out $($(basename $@)_SRC) $($(basename $@)_LDFLAGS)
# Run all tests
.PHONY: test
test: $(TESTS)
@echo "Running all tests..."
@for test in $(TESTS); do \
echo "Running $$test..."; \
$$test.out || exit 1; \
done
# Clean tests
.PHONY: clean
clean:
@for test in $(TESTS); do \
rm -f $$test.out; \
done