Skip to content

Commit ab6300e

Browse files
committed
io: fix linux timeout handling for splice
1 parent 13c6e5d commit ab6300e

1 file changed

Lines changed: 10 additions & 18 deletions

File tree

main/io/php_io_copy_linux.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -151,27 +151,21 @@ static ssize_t php_io_linux_sendfile(int src_fd, int dest_fd, size_t maxlen)
151151
}
152152

153153
#ifdef HAVE_SPLICE
154-
static ssize_t php_io_linux_splice_from_pipe(int pipe_fd, int dest_fd, size_t maxlen)
154+
static ssize_t php_io_linux_splice_from_pipe(php_io_fd *src, int dest_fd, size_t maxlen)
155155
{
156156
size_t total_copied = 0;
157157
size_t remaining = (maxlen == PHP_IO_COPY_ALL) ? SIZE_MAX : maxlen;
158158

159159
while (remaining > 0) {
160160
int ready = php_io_linux_wait_for_data(src);
161161
if (ready == 0) {
162-
/* timeout */
163162
break;
164163
} else if (ready < 0) {
165-
if (total_copied == 0) {
166-
close(pipefd[0]);
167-
close(pipefd[1]);
168-
return -1;
169-
}
170-
break;
164+
return total_copied > 0 ? (ssize_t) total_copied : -1;
171165
}
172166

173167
size_t to_copy = (remaining < SSIZE_MAX) ? remaining : SSIZE_MAX;
174-
ssize_t result = splice(pipe_fd, NULL, dest_fd, NULL, to_copy, 0);
168+
ssize_t result = splice(src->fd, NULL, dest_fd, NULL, to_copy, 0);
175169

176170
if (result > 0) {
177171
total_copied += result;
@@ -182,7 +176,7 @@ static ssize_t php_io_linux_splice_from_pipe(int pipe_fd, int dest_fd, size_t ma
182176
break;
183177
} else {
184178
if (total_copied == 0) {
185-
return php_io_generic_copy_fallback(pipe_fd, dest_fd, maxlen);
179+
return php_io_generic_copy_fallback(src->fd, dest_fd, maxlen);
186180
}
187181
break;
188182
}
@@ -191,11 +185,11 @@ static ssize_t php_io_linux_splice_from_pipe(int pipe_fd, int dest_fd, size_t ma
191185
return total_copied > 0 ? (ssize_t) total_copied : -1;
192186
}
193187

194-
static ssize_t php_io_linux_splice_via_pipe(int src_fd, int dest_fd, size_t maxlen)
188+
static ssize_t php_io_linux_splice_via_pipe(php_io_fd *src, int dest_fd, size_t maxlen)
195189
{
196190
int pipefd[2];
197191
if (pipe(pipefd) == -1) {
198-
return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen);
192+
return php_io_generic_copy_fallback(src->fd, dest_fd, maxlen);
199193
}
200194

201195
size_t total_copied = 0;
@@ -217,12 +211,12 @@ static ssize_t php_io_linux_splice_via_pipe(int src_fd, int dest_fd, size_t maxl
217211

218212
size_t to_copy = (remaining < SSIZE_MAX) ? remaining : SSIZE_MAX;
219213

220-
ssize_t in_pipe = splice(src_fd, NULL, pipefd[1], NULL, to_copy, 0);
214+
ssize_t in_pipe = splice(src->fd, NULL, pipefd[1], NULL, to_copy, 0);
221215
if (in_pipe < 0) {
222216
close(pipefd[0]);
223217
close(pipefd[1]);
224218
if (total_copied == 0) {
225-
return php_io_generic_copy_fallback(src_fd, dest_fd, maxlen);
219+
return php_io_generic_copy_fallback(src->fd, dest_fd, maxlen);
226220
}
227221
return (ssize_t) total_copied;
228222
}
@@ -234,7 +228,6 @@ static ssize_t php_io_linux_splice_via_pipe(int src_fd, int dest_fd, size_t maxl
234228
while (pipe_remaining > 0) {
235229
ssize_t out = splice(pipefd[0], NULL, dest_fd, NULL, pipe_remaining, 0);
236230
if (out <= 0) {
237-
/* drain pipe before closing */
238231
char drain_buf[1024];
239232
while (pipe_remaining > 0) {
240233
size_t to_drain = (pipe_remaining < sizeof(drain_buf))
@@ -281,18 +274,17 @@ ssize_t php_io_linux_copy(php_io_fd *src, php_io_fd *dest, size_t maxlen)
281274
return php_io_linux_sendfile(src->fd, dest->fd, maxlen);
282275
}
283276

284-
/* sendfile also works for file to pipe on Linux */
285277
if (src->fd_type == PHP_IO_FD_FILE && dest->fd_type == PHP_IO_FD_PIPE) {
286278
return php_io_linux_sendfile(src->fd, dest->fd, maxlen);
287279
}
288280

289281
#ifdef HAVE_SPLICE
290282
if (src->fd_type == PHP_IO_FD_PIPE) {
291-
return php_io_linux_splice_from_pipe(src->fd, dest->fd, maxlen);
283+
return php_io_linux_splice_from_pipe(src, dest->fd, maxlen);
292284
}
293285

294286
if (src->fd_type == PHP_IO_FD_SOCKET) {
295-
return php_io_linux_splice_via_pipe(src->fd, dest->fd, maxlen);
287+
return php_io_linux_splice_via_pipe(src, dest->fd, maxlen);
296288
}
297289
#endif
298290

0 commit comments

Comments
 (0)