From df0d009fb7e277fe4fa7cc35f1b2695a2bea8df5 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 4 Jun 2019 17:25:13 +0200 Subject: test build for https://bugs.php.net/77653 --- 4007.patch | 687 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ php.spec | 8 +- 2 files changed, 694 insertions(+), 1 deletion(-) create mode 100644 4007.patch diff --git a/4007.patch b/4007.patch new file mode 100644 index 0000000..9958737 --- /dev/null +++ b/4007.patch @@ -0,0 +1,687 @@ +From 730630808024373663a730be93d52c580334810d Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka +Date: Sun, 31 Mar 2019 16:56:17 +0100 +Subject: [PATCH 1/5] Fix logging in shutdown function + +--- + sapi/fpm/fpm/fpm_stdio.c | 20 +++++++-- + sapi/fpm/tests/log-bm-in-shutdown-fn.phpt | 49 +++++++++++++++++++++++ + 2 files changed, 65 insertions(+), 4 deletions(-) + create mode 100644 sapi/fpm/tests/log-bm-in-shutdown-fn.phpt + +diff --git a/sapi/fpm/fpm/fpm_stdio.c b/sapi/fpm/fpm/fpm_stdio.c +index 03d15cbf0d7c..75c4d8e9c262 100644 +--- a/sapi/fpm/fpm/fpm_stdio.c ++++ b/sapi/fpm/fpm/fpm_stdio.c +@@ -106,9 +106,11 @@ int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ + } + /* }}} */ + ++#define FPM_STDIO_CMD_FLUSH "\0fscf" ++ + int fpm_stdio_flush_child() /* {{{ */ + { +- return write(STDERR_FILENO, "\0", 1); ++ return write(STDERR_FILENO, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH)); + } + /* }}} */ + +@@ -162,10 +164,20 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + } + } else { + in_buf += res; +- /* if buffer ends with \0, then the stream will be finished */ +- if (!buf[in_buf - 1]) { ++ /* check if buffer should be flushed */ ++ if (!buf[in_buf - 1] && in_buf >= sizeof(FPM_STDIO_CMD_FLUSH) && ++ !memcmp(buf + in_buf - sizeof(FPM_STDIO_CMD_FLUSH), ++ FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) { ++ /* if buffer ends with flush cmd, then the stream will be finished */ ++ finish_log_stream = 1; ++ in_buf -= sizeof(FPM_STDIO_CMD_FLUSH); ++ } else if (!buf[0] && in_buf > sizeof(FPM_STDIO_CMD_FLUSH) && ++ !memcmp(buf, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) { ++ /* if buffer starts with flush cmd, then the stream will be finished */ + finish_log_stream = 1; +- in_buf--; ++ in_buf -= sizeof(FPM_STDIO_CMD_FLUSH); ++ /* move data behind the flush cmd */ ++ memmove(buf, buf + sizeof(FPM_STDIO_CMD_FLUSH), in_buf); + } + } + } +diff --git a/sapi/fpm/tests/log-bm-in-shutdown-fn.phpt b/sapi/fpm/tests/log-bm-in-shutdown-fn.phpt +new file mode 100644 +index 000000000000..f968bf9f08bc +--- /dev/null ++++ b/sapi/fpm/tests/log-bm-in-shutdown-fn.phpt +@@ -0,0 +1,49 @@ ++--TEST-- ++FPM: Log message in shutdown function ++--SKIPIF-- ++ ++--FILE-- ++start(); ++$tester->expectLogStartNotices(); ++$tester->request()->expectEmptyBody(); ++$tester->terminate(); ++$tester->expectFastCGIErrorMessage('e', 1050, 80); ++$tester->expectLogMessage('NOTICE: PHP message: ' . str_repeat('e', 80), 1050); ++$tester->close(); ++ ++?> ++Done ++--EXPECT-- ++Done ++--CLEAN-- ++ + +From 336ea9174b75fc33dd11a83f386df97b357b605f Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka +Date: Sun, 31 Mar 2019 17:55:29 +0100 +Subject: [PATCH 2/5] Move stdio flush behind request shutdown + +--- + sapi/fpm/fpm/fpm_main.c | 3 +++ + sapi/fpm/fpm/fpm_request.c | 2 -- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c +index 483fabe9d850..bfd82a1c2e11 100644 +--- a/sapi/fpm/fpm/fpm_main.c ++++ b/sapi/fpm/fpm/fpm_main.c +@@ -90,6 +90,7 @@ int __riscosify_control = __RISCOSIFY_STRICT_UNIX_SPECS; + #include "fpm.h" + #include "fpm_request.h" + #include "fpm_status.h" ++#include "fpm_stdio.h" + #include "fpm_conf.h" + #include "fpm_php.h" + #include "fpm_log.h" +@@ -1977,6 +1978,8 @@ consult the installation file that came with this distribution, or visit \n\ + + php_request_shutdown((void *) 0); + ++ fpm_stdio_flush_child(); ++ + requests++; + if (UNEXPECTED(max_requests && (requests == max_requests))) { + fcgi_request_set_keep(request, 0); +diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c +index 65f9c4ae441c..2aa503891ed9 100644 +--- a/sapi/fpm/fpm/fpm_request.c ++++ b/sapi/fpm/fpm/fpm_request.c +@@ -16,7 +16,6 @@ + #include "fpm_children.h" + #include "fpm_scoreboard.h" + #include "fpm_status.h" +-#include "fpm_stdio.h" + #include "fpm_request.h" + #include "fpm_log.h" + +@@ -200,7 +199,6 @@ void fpm_request_end(void) /* {{{ */ + #endif + proc->memory = memory; + fpm_scoreboard_proc_release(proc); +- fpm_stdio_flush_child(); + } + /* }}} */ + + +From a2c3ccb024b1a634e34dcff9573635e61a1fe1d7 Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka +Date: Sun, 21 Apr 2019 17:39:11 +0100 +Subject: [PATCH 3/5] Create a new IO ctrl pipe for flushing log stream + +--- + sapi/fpm/fpm/fpm_children.h | 4 +- + sapi/fpm/fpm/fpm_stdio.c | 79 ++++++++++++++++++++++++++----------- + 2 files changed, 58 insertions(+), 25 deletions(-) + +diff --git a/sapi/fpm/fpm/fpm_children.h b/sapi/fpm/fpm/fpm_children.h +index 9d9c1fa7cb31..d755b00e243d 100644 +--- a/sapi/fpm/fpm/fpm_children.h ++++ b/sapi/fpm/fpm/fpm_children.h +@@ -22,9 +22,9 @@ struct fpm_child_s { + struct fpm_child_s *prev, *next; + struct timeval started; + struct fpm_worker_pool_s *wp; +- struct fpm_event_s ev_stdout, ev_stderr; ++ struct fpm_event_s ev_stdout, ev_stderr, ev_ioctrl; + int shm_slot_i; +- int fd_stdout, fd_stderr; ++ int fd_stdout, fd_stderr, fd_ioctrl; + void (*tracer)(struct fpm_child_s *); + struct timeval slow_logged; + int idle_kill; +diff --git a/sapi/fpm/fpm/fpm_stdio.c b/sapi/fpm/fpm/fpm_stdio.c +index 75c4d8e9c262..0b41d1d8c676 100644 +--- a/sapi/fpm/fpm/fpm_stdio.c ++++ b/sapi/fpm/fpm/fpm_stdio.c +@@ -21,6 +21,7 @@ + + static int fd_stdout[2]; + static int fd_stderr[2]; ++static int fd_ioctrl[2]; + + int fpm_stdio_init_main() /* {{{ */ + { +@@ -106,11 +107,36 @@ int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ + } + /* }}} */ + +-#define FPM_STDIO_CMD_FLUSH "\0fscf" ++#define FPM_STDIO_CTRL_FLUSH "f" + + int fpm_stdio_flush_child() /* {{{ */ + { +- return write(STDERR_FILENO, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH)); ++ return write(fd_ioctrl[1], FPM_STDIO_CTRL_FLUSH, sizeof(FPM_STDIO_CTRL_FLUSH)); ++} ++/* }}} */ ++ ++static void fpm_stdio_child_ctrl(struct fpm_event_s *ev, short which, void *arg) /* {{{ */ ++{ ++ static const int max_buf_size = 16; ++ int fd = ev->fd; ++ char buf[max_buf_size]; ++ struct fpm_child_s *child; ++ int res; ++ ++ if (!arg) { ++ return; ++ } ++ child = (struct fpm_child_s *)arg; ++ ++ res = read(fd, buf, max_buf_size); ++ ++ if (res <= 0) { ++ return; ++ } ++ ++ if (!memcmp(buf, FPM_STDIO_CTRL_FLUSH, sizeof(FPM_STDIO_CTRL_FLUSH)) && child->log_stream) { ++ zlog_stream_finish(child->log_stream); ++ } + } + /* }}} */ + +@@ -124,7 +150,7 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + struct fpm_event_s *event; + int fifo_in = 1, fifo_out = 1; + int in_buf = 0; +- int read_fail = 0, finish_log_stream = 0, create_log_stream; ++ int read_fail = 0, create_log_stream; + int res; + struct zlog_stream *log_stream; + +@@ -164,21 +190,6 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + } + } else { + in_buf += res; +- /* check if buffer should be flushed */ +- if (!buf[in_buf - 1] && in_buf >= sizeof(FPM_STDIO_CMD_FLUSH) && +- !memcmp(buf + in_buf - sizeof(FPM_STDIO_CMD_FLUSH), +- FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) { +- /* if buffer ends with flush cmd, then the stream will be finished */ +- finish_log_stream = 1; +- in_buf -= sizeof(FPM_STDIO_CMD_FLUSH); +- } else if (!buf[0] && in_buf > sizeof(FPM_STDIO_CMD_FLUSH) && +- !memcmp(buf, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) { +- /* if buffer starts with flush cmd, then the stream will be finished */ +- finish_log_stream = 1; +- in_buf -= sizeof(FPM_STDIO_CMD_FLUSH); +- /* move data behind the flush cmd */ +- memmove(buf, buf + sizeof(FPM_STDIO_CMD_FLUSH), in_buf); +- } + } + } + +@@ -226,8 +237,6 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + close(child->fd_stderr); + child->fd_stderr = -1; + } +- } else if (finish_log_stream) { +- zlog_stream_finish(log_stream); + } + } + /* }}} */ +@@ -250,12 +259,25 @@ int fpm_stdio_prepare_pipes(struct fpm_child_s *child) /* {{{ */ + return -1; + } + +- if (0 > fd_set_blocked(fd_stdout[0], 0) || 0 > fd_set_blocked(fd_stderr[0], 0)) { ++ if (0 > pipe(fd_ioctrl)) { ++ zlog(ZLOG_SYSERROR, "failed to prepare the IO control pipe"); ++ close(fd_stdout[0]); ++ close(fd_stdout[1]); ++ close(fd_stderr[0]); ++ close(fd_stderr[1]); ++ return -1; ++ } ++ ++ if (0 > fd_set_blocked(fd_stdout[0], 0) || ++ 0 > fd_set_blocked(fd_stderr[0], 0) || ++ 0 > fd_set_blocked(fd_ioctrl[0], 0)) { + zlog(ZLOG_SYSERROR, "failed to unblock pipes"); + close(fd_stdout[0]); + close(fd_stdout[1]); + close(fd_stderr[0]); + close(fd_stderr[1]); ++ close(fd_ioctrl[0]); ++ close(fd_ioctrl[1]); + return -1; + } + return 0; +@@ -273,12 +295,17 @@ int fpm_stdio_parent_use_pipes(struct fpm_child_s *child) /* {{{ */ + + child->fd_stdout = fd_stdout[0]; + child->fd_stderr = fd_stderr[0]; ++ child->fd_ioctrl = fd_ioctrl[0]; + + fpm_event_set(&child->ev_stdout, child->fd_stdout, FPM_EV_READ, fpm_stdio_child_said, child); + fpm_event_add(&child->ev_stdout, 0); + + fpm_event_set(&child->ev_stderr, child->fd_stderr, FPM_EV_READ, fpm_stdio_child_said, child); + fpm_event_add(&child->ev_stderr, 0); ++ ++ fpm_event_set(&child->ev_ioctrl, child->fd_ioctrl, FPM_EV_READ, fpm_stdio_child_ctrl, child); ++ fpm_event_add(&child->ev_ioctrl, 0); ++ + return 0; + } + /* }}} */ +@@ -291,9 +318,12 @@ int fpm_stdio_discard_pipes(struct fpm_child_s *child) /* {{{ */ + + close(fd_stdout[1]); + close(fd_stderr[1]); ++ close(fd_ioctrl[1]); + + close(fd_stdout[0]); + close(fd_stderr[0]); ++ close(fd_ioctrl[0]); ++ + return 0; + } + /* }}} */ +@@ -303,8 +333,11 @@ void fpm_stdio_child_use_pipes(struct fpm_child_s *child) /* {{{ */ + if (child->wp->config->catch_workers_output) { + dup2(fd_stdout[1], STDOUT_FILENO); + dup2(fd_stderr[1], STDERR_FILENO); +- close(fd_stdout[0]); close(fd_stdout[1]); +- close(fd_stderr[0]); close(fd_stderr[1]); ++ close(fd_stdout[0]); ++ close(fd_stdout[1]); ++ close(fd_stderr[0]); ++ close(fd_stderr[1]); ++ close(fd_ioctrl[0]); + } else { + /* stdout of parent is always /dev/null */ + dup2(STDOUT_FILENO, STDERR_FILENO); + +From b6ad8cdf993f0f076dd05e8543b02f3bbf215a7b Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka +Date: Mon, 27 May 2019 16:24:28 +0100 +Subject: [PATCH 4/5] Revert "Create a new IO ctrl pipe for flushing log + stream" + +This reverts commit f6f37a799ebf0c0dc5dcace0dab527a1ff567b77. +--- + sapi/fpm/fpm/fpm_children.h | 4 +- + sapi/fpm/fpm/fpm_stdio.c | 79 +++++++++++-------------------------- + 2 files changed, 25 insertions(+), 58 deletions(-) + +diff --git a/sapi/fpm/fpm/fpm_children.h b/sapi/fpm/fpm/fpm_children.h +index d755b00e243d..9d9c1fa7cb31 100644 +--- a/sapi/fpm/fpm/fpm_children.h ++++ b/sapi/fpm/fpm/fpm_children.h +@@ -22,9 +22,9 @@ struct fpm_child_s { + struct fpm_child_s *prev, *next; + struct timeval started; + struct fpm_worker_pool_s *wp; +- struct fpm_event_s ev_stdout, ev_stderr, ev_ioctrl; ++ struct fpm_event_s ev_stdout, ev_stderr; + int shm_slot_i; +- int fd_stdout, fd_stderr, fd_ioctrl; ++ int fd_stdout, fd_stderr; + void (*tracer)(struct fpm_child_s *); + struct timeval slow_logged; + int idle_kill; +diff --git a/sapi/fpm/fpm/fpm_stdio.c b/sapi/fpm/fpm/fpm_stdio.c +index 0b41d1d8c676..75c4d8e9c262 100644 +--- a/sapi/fpm/fpm/fpm_stdio.c ++++ b/sapi/fpm/fpm/fpm_stdio.c +@@ -21,7 +21,6 @@ + + static int fd_stdout[2]; + static int fd_stderr[2]; +-static int fd_ioctrl[2]; + + int fpm_stdio_init_main() /* {{{ */ + { +@@ -107,36 +106,11 @@ int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ + } + /* }}} */ + +-#define FPM_STDIO_CTRL_FLUSH "f" ++#define FPM_STDIO_CMD_FLUSH "\0fscf" + + int fpm_stdio_flush_child() /* {{{ */ + { +- return write(fd_ioctrl[1], FPM_STDIO_CTRL_FLUSH, sizeof(FPM_STDIO_CTRL_FLUSH)); +-} +-/* }}} */ +- +-static void fpm_stdio_child_ctrl(struct fpm_event_s *ev, short which, void *arg) /* {{{ */ +-{ +- static const int max_buf_size = 16; +- int fd = ev->fd; +- char buf[max_buf_size]; +- struct fpm_child_s *child; +- int res; +- +- if (!arg) { +- return; +- } +- child = (struct fpm_child_s *)arg; +- +- res = read(fd, buf, max_buf_size); +- +- if (res <= 0) { +- return; +- } +- +- if (!memcmp(buf, FPM_STDIO_CTRL_FLUSH, sizeof(FPM_STDIO_CTRL_FLUSH)) && child->log_stream) { +- zlog_stream_finish(child->log_stream); +- } ++ return write(STDERR_FILENO, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH)); + } + /* }}} */ + +@@ -150,7 +124,7 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + struct fpm_event_s *event; + int fifo_in = 1, fifo_out = 1; + int in_buf = 0; +- int read_fail = 0, create_log_stream; ++ int read_fail = 0, finish_log_stream = 0, create_log_stream; + int res; + struct zlog_stream *log_stream; + +@@ -190,6 +164,21 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + } + } else { + in_buf += res; ++ /* check if buffer should be flushed */ ++ if (!buf[in_buf - 1] && in_buf >= sizeof(FPM_STDIO_CMD_FLUSH) && ++ !memcmp(buf + in_buf - sizeof(FPM_STDIO_CMD_FLUSH), ++ FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) { ++ /* if buffer ends with flush cmd, then the stream will be finished */ ++ finish_log_stream = 1; ++ in_buf -= sizeof(FPM_STDIO_CMD_FLUSH); ++ } else if (!buf[0] && in_buf > sizeof(FPM_STDIO_CMD_FLUSH) && ++ !memcmp(buf, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) { ++ /* if buffer starts with flush cmd, then the stream will be finished */ ++ finish_log_stream = 1; ++ in_buf -= sizeof(FPM_STDIO_CMD_FLUSH); ++ /* move data behind the flush cmd */ ++ memmove(buf, buf + sizeof(FPM_STDIO_CMD_FLUSH), in_buf); ++ } + } + } + +@@ -237,6 +226,8 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + close(child->fd_stderr); + child->fd_stderr = -1; + } ++ } else if (finish_log_stream) { ++ zlog_stream_finish(log_stream); + } + } + /* }}} */ +@@ -259,25 +250,12 @@ int fpm_stdio_prepare_pipes(struct fpm_child_s *child) /* {{{ */ + return -1; + } + +- if (0 > pipe(fd_ioctrl)) { +- zlog(ZLOG_SYSERROR, "failed to prepare the IO control pipe"); +- close(fd_stdout[0]); +- close(fd_stdout[1]); +- close(fd_stderr[0]); +- close(fd_stderr[1]); +- return -1; +- } +- +- if (0 > fd_set_blocked(fd_stdout[0], 0) || +- 0 > fd_set_blocked(fd_stderr[0], 0) || +- 0 > fd_set_blocked(fd_ioctrl[0], 0)) { ++ if (0 > fd_set_blocked(fd_stdout[0], 0) || 0 > fd_set_blocked(fd_stderr[0], 0)) { + zlog(ZLOG_SYSERROR, "failed to unblock pipes"); + close(fd_stdout[0]); + close(fd_stdout[1]); + close(fd_stderr[0]); + close(fd_stderr[1]); +- close(fd_ioctrl[0]); +- close(fd_ioctrl[1]); + return -1; + } + return 0; +@@ -295,17 +273,12 @@ int fpm_stdio_parent_use_pipes(struct fpm_child_s *child) /* {{{ */ + + child->fd_stdout = fd_stdout[0]; + child->fd_stderr = fd_stderr[0]; +- child->fd_ioctrl = fd_ioctrl[0]; + + fpm_event_set(&child->ev_stdout, child->fd_stdout, FPM_EV_READ, fpm_stdio_child_said, child); + fpm_event_add(&child->ev_stdout, 0); + + fpm_event_set(&child->ev_stderr, child->fd_stderr, FPM_EV_READ, fpm_stdio_child_said, child); + fpm_event_add(&child->ev_stderr, 0); +- +- fpm_event_set(&child->ev_ioctrl, child->fd_ioctrl, FPM_EV_READ, fpm_stdio_child_ctrl, child); +- fpm_event_add(&child->ev_ioctrl, 0); +- + return 0; + } + /* }}} */ +@@ -318,12 +291,9 @@ int fpm_stdio_discard_pipes(struct fpm_child_s *child) /* {{{ */ + + close(fd_stdout[1]); + close(fd_stderr[1]); +- close(fd_ioctrl[1]); + + close(fd_stdout[0]); + close(fd_stderr[0]); +- close(fd_ioctrl[0]); +- + return 0; + } + /* }}} */ +@@ -333,11 +303,8 @@ void fpm_stdio_child_use_pipes(struct fpm_child_s *child) /* {{{ */ + if (child->wp->config->catch_workers_output) { + dup2(fd_stdout[1], STDOUT_FILENO); + dup2(fd_stderr[1], STDERR_FILENO); +- close(fd_stdout[0]); +- close(fd_stdout[1]); +- close(fd_stderr[0]); +- close(fd_stderr[1]); +- close(fd_ioctrl[0]); ++ close(fd_stdout[0]); close(fd_stdout[1]); ++ close(fd_stderr[0]); close(fd_stderr[1]); + } else { + /* stdout of parent is always /dev/null */ + dup2(STDOUT_FILENO, STDERR_FILENO); + +From ffad6a9ff551fce04fc0b8dd905cf5db2aac7813 Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka +Date: Mon, 27 May 2019 16:29:09 +0100 +Subject: [PATCH 5/5] Refactor fpm_stdio_child_said + +--- + sapi/fpm/fpm/fpm_stdio.c | 80 ++++++++++++++-------------------------- + sapi/fpm/fpm/zlog.c | 8 ++-- + 2 files changed, 32 insertions(+), 56 deletions(-) + +diff --git a/sapi/fpm/fpm/fpm_stdio.c b/sapi/fpm/fpm/fpm_stdio.c +index 75c4d8e9c262..d7d2c4b0b229 100644 +--- a/sapi/fpm/fpm/fpm_stdio.c ++++ b/sapi/fpm/fpm/fpm_stdio.c +@@ -122,10 +122,8 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + struct fpm_child_s *child; + int is_stdout; + struct fpm_event_s *event; +- int fifo_in = 1, fifo_out = 1; +- int in_buf = 0; +- int read_fail = 0, finish_log_stream = 0, create_log_stream; +- int res; ++ int in_buf = 0, pos, start; ++ int read_fail = 0, create_log_stream; + struct zlog_stream *log_stream; + + if (!arg) { +@@ -153,59 +151,37 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + log_stream = child->log_stream; + } + +- while (fifo_in || fifo_out) { +- if (fifo_in) { +- res = read(fd, buf + in_buf, max_buf_size - 1 - in_buf); +- if (res <= 0) { /* no data */ +- fifo_in = 0; +- if (res == 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) { +- /* pipe is closed or error */ +- read_fail = (res < 0) ? res : 1; +- } +- } else { +- in_buf += res; +- /* check if buffer should be flushed */ +- if (!buf[in_buf - 1] && in_buf >= sizeof(FPM_STDIO_CMD_FLUSH) && +- !memcmp(buf + in_buf - sizeof(FPM_STDIO_CMD_FLUSH), +- FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) { +- /* if buffer ends with flush cmd, then the stream will be finished */ +- finish_log_stream = 1; +- in_buf -= sizeof(FPM_STDIO_CMD_FLUSH); +- } else if (!buf[0] && in_buf > sizeof(FPM_STDIO_CMD_FLUSH) && +- !memcmp(buf, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) { +- /* if buffer starts with flush cmd, then the stream will be finished */ +- finish_log_stream = 1; +- in_buf -= sizeof(FPM_STDIO_CMD_FLUSH); +- /* move data behind the flush cmd */ +- memmove(buf, buf + sizeof(FPM_STDIO_CMD_FLUSH), in_buf); +- } ++ while (1) { ++ in_buf = read(fd, buf, max_buf_size - 1); ++ if (in_buf <= 0) { /* no data */ ++ if (in_buf == 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) { ++ /* pipe is closed or error */ ++ read_fail = (in_buf < 0) ? in_buf : 1; + } ++ break; + } + +- if (fifo_out) { +- if (in_buf == 0) { +- fifo_out = 0; +- } else { +- char *nl; +- +- nl = memchr(buf, '\n', in_buf); +- if (nl) { +- /* we should print each new line int the new message */ +- int out_len = nl - buf; +- zlog_stream_str(log_stream, buf, out_len); ++ for (start = 0, pos = 0; pos < in_buf; pos++) { ++ switch (buf[pos]) { ++ case '\n': ++ zlog_stream_str(log_stream, buf + start, pos - start); + zlog_stream_finish(log_stream); +- /* skip new line */ +- out_len++; +- /* move data in the buffer */ +- memmove(buf, buf + out_len, in_buf - out_len); +- in_buf -= out_len; +- } else if (in_buf == max_buf_size - 1 || !fifo_in) { +- /* we should print if no more space in the buffer or no more data to come */ +- zlog_stream_str(log_stream, buf, in_buf); +- in_buf = 0; +- } ++ start = pos + 1; ++ break; ++ case '\0': ++ if (pos + sizeof(FPM_STDIO_CMD_FLUSH) <= in_buf && ++ !memcmp(buf + pos, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) { ++ zlog_stream_str(log_stream, buf + start, pos - start); ++ zlog_stream_finish(log_stream); ++ start = pos + sizeof(FPM_STDIO_CMD_FLUSH); ++ pos = start - 1; ++ } ++ break; + } + } ++ if (start < pos) { ++ zlog_stream_str(log_stream, buf + start, pos - start); ++ } + } + + if (read_fail) { +@@ -226,8 +202,6 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg) + close(child->fd_stderr); + child->fd_stderr = -1; + } +- } else if (finish_log_stream) { +- zlog_stream_finish(log_stream); + } + } + /* }}} */ +diff --git a/sapi/fpm/fpm/zlog.c b/sapi/fpm/fpm/zlog.c +index 09193fd5ac85..21bd614a9784 100644 +--- a/sapi/fpm/fpm/zlog.c ++++ b/sapi/fpm/fpm/zlog.c +@@ -720,14 +720,16 @@ ssize_t zlog_stream_format(struct zlog_stream *stream, const char *fmt, ...) /* + + ssize_t zlog_stream_str(struct zlog_stream *stream, const char *str, size_t str_len) /* {{{ */ + { ++ /* do not write anything if the stream is full or str is empty */ ++ if (str_len == 0 || stream->full) { ++ return 0; ++ } ++ + /* reset stream if it is finished */ + if (stream->finished) { + stream->finished = 0; + stream->len = 0; + stream->full = 0; +- } else if (stream->full) { +- /* do not write anything if the stream is full */ +- return 0; + } + + if (stream->use_buffer) { diff --git a/php.spec b/php.spec index d4a7ba9..03371fa 100644 --- a/php.spec +++ b/php.spec @@ -132,7 +132,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: %{?scl_prefix}php Version: %{upver}%{?rcver:~%{lower}} -Release: 1%{?dist} +Release: 2%{?dist} # All files licensed under PHP version 3.01, except # Zend is licensed under Zend # TSRM is licensed under BSD @@ -195,6 +195,7 @@ Patch91: php-7.2.0-oci8conf.patch Patch300: php-7.0.10-datetests.patch # WIP +Patch400: https://github.com/php/php-src/pull/4007.patch BuildRequires: bzip2-devel, curl-devel >= 7.9, %{db_devel} BuildRequires: httpd-devel >= 2.0.46-1, pam-devel @@ -947,6 +948,7 @@ low-level PHP extension for the libsodium cryptographic library. %patch300 -p1 -b .datetests # WIP patch +%patch400 -p1 -b .pr4007 # Prevent %%doc confusion over LICENSE files cp Zend/LICENSE Zend/ZEND_LICENSE @@ -1882,6 +1884,10 @@ fi %changelog +* Tue Jun 4 2019 Remi Collet - 7.3.6-2 +- test build for https://bugs.php.net/77653 + patch from https://github.com/php/php-src/pull/4007 + * Tue May 28 2019 Remi Collet - 7.3.6-1 - Update to 7.3.6 - http://www.php.net/releases/7_3_6.php -- cgit