Skip to content

Commit e2bd3b1

Browse files
MaxKellermanndevnexen
authored andcommitted
main/streams/plain_wrapper: skip lseek(SEEK_CUR) for newly opened files
A file that has just been opened is known to be at offset zero, and the lseek(SEEK_CUR) system call to determine the current offset can be skipped. Closes #8540.
1 parent c756e97 commit e2bd3b1

File tree

5 files changed

+16
-5
lines changed

5 files changed

+16
-5
lines changed

NEWS

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ PHP NEWS
1717
enums). (ilutov)
1818
. Fixed bug GH-8810 (Incorrect lineno in backtrace of multi-line function
1919
calls). (ilutov)
20+
. Optimised code path for newly created file with the stream plain wrapper. (Max Kellermann)
2021

2122
- Curl:
2223
. Added new constants from cURL 7.62 to 7.80. (Pierrick)

UPGRADING.INTERNALS

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ PHP 8.2 INTERNALS UPGRADE NOTES
3737
- zend_object_count_elements_t
3838
- zend_object_get_closure_t
3939
- zend_object_do_operation_t
40+
* Added a new zero_position argument to php_stream_fopen_from_fd_rel to reflect
41+
if this a newly created file so the current file offset needs not to be checked.
4042

4143
========================
4244
2. Build system changes

main/php_streams.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ END_EXTERN_C()
6565

6666
#define php_stream_fopen_with_path_rel(filename, mode, path, opened, options) _php_stream_fopen_with_path((filename), (mode), (path), (opened), (options) STREAMS_REL_CC)
6767

68-
#define php_stream_fopen_from_fd_rel(fd, mode, persistent_id) _php_stream_fopen_from_fd((fd), (mode), (persistent_id) STREAMS_REL_CC)
68+
#define php_stream_fopen_from_fd_rel(fd, mode, persistent_id, zero_position) _php_stream_fopen_from_fd((fd), (mode), (persistent_id), (zero_position) STREAMS_REL_CC)
6969
#define php_stream_fopen_from_file_rel(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_REL_CC)
7070

7171
#define php_stream_fopen_from_pipe_rel(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_REL_CC)

main/streams/php_stream_plain_wrapper.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char
3232
PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC);
3333
#define php_stream_fopen_from_file(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_CC)
3434

35-
PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC);
36-
#define php_stream_fopen_from_fd(fd, mode, persistent_id) _php_stream_fopen_from_fd((fd), (mode), (persistent_id) STREAMS_CC)
35+
PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id, bool zero_position STREAMS_DC);
36+
#define php_stream_fopen_from_fd(fd, mode, persistent_id) _php_stream_fopen_from_fd((fd), (mode), (persistent_id), false STREAMS_CC)
3737

3838
PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STREAMS_DC);
3939
#define php_stream_fopen_from_pipe(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_CC)

main/streams/plain_wrapper.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ static void detect_is_seekable(php_stdio_stream_data *self) {
274274
#endif
275275
}
276276

277-
PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC)
277+
PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id, bool zero_position STREAMS_DC)
278278
{
279279
php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id);
280280

@@ -285,6 +285,9 @@ PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const cha
285285
if (!self->is_seekable) {
286286
stream->flags |= PHP_STREAM_FLAG_NO_SEEK;
287287
stream->position = -1;
288+
} else if (zero_position) {
289+
ZEND_ASSERT(zend_lseek(self->fd, 0, SEEK_CUR) == 0);
290+
stream->position = 0;
288291
} else {
289292
stream->position = zend_lseek(self->fd, 0, SEEK_CUR);
290293
#ifdef ESPIPE
@@ -1141,7 +1144,12 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, zen
11411144
if (options & STREAM_OPEN_FOR_INCLUDE) {
11421145
ret = php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id);
11431146
} else {
1144-
ret = php_stream_fopen_from_fd_rel(fd, mode, persistent_id);
1147+
/* skip the lseek(SEEK_CUR) system call to
1148+
* determine the current offset because we
1149+
* know newly opened files are at offset zero
1150+
* (unless the file has been opened in
1151+
* O_APPEND mode) */
1152+
ret = php_stream_fopen_from_fd_rel(fd, mode, persistent_id, (open_flags & O_APPEND) == 0);
11451153
}
11461154

11471155
if (ret) {

0 commit comments

Comments
 (0)