Skip to content

Commit 6d9c521

Browse files
committed
Fix logging in shutdown function
1 parent 39d04f1 commit 6d9c521

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

sapi/fpm/fpm/fpm_stdio.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,11 @@ int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
106106
}
107107
/* }}} */
108108

109+
#define FPM_STDIO_CMD_FLUSH "\0fscf"
110+
109111
int fpm_stdio_flush_child() /* {{{ */
110112
{
111-
return write(STDERR_FILENO, "\0", 1);
113+
return write(STDERR_FILENO, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH));
112114
}
113115
/* }}} */
114116

@@ -173,10 +175,20 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg)
173175
}
174176
} else {
175177
in_buf += res;
176-
/* if buffer ends with \0, then the stream will be finished */
177-
if (!buf[in_buf - 1]) {
178+
/* check if buffer should be flushed */
179+
if (!buf[in_buf - 1] && in_buf >= sizeof(FPM_STDIO_CMD_FLUSH) &&
180+
!memcmp(buf + in_buf - sizeof(FPM_STDIO_CMD_FLUSH),
181+
FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) {
182+
/* if buffer ends with flush cmd, then the stream will be finished */
183+
finish_log_stream = 1;
184+
in_buf -= sizeof(FPM_STDIO_CMD_FLUSH);
185+
} else if (!buf[0] && in_buf > sizeof(FPM_STDIO_CMD_FLUSH) &&
186+
!memcmp(buf, FPM_STDIO_CMD_FLUSH, sizeof(FPM_STDIO_CMD_FLUSH))) {
187+
/* if buffer starts with flush cmd, then the stream will be finished */
178188
finish_log_stream = 1;
179-
in_buf--;
189+
in_buf -= sizeof(FPM_STDIO_CMD_FLUSH);
190+
/* move data behind the flush cmd */
191+
memmove(buf, buf + sizeof(FPM_STDIO_CMD_FLUSH), in_buf);
180192
}
181193
}
182194
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--TEST--
2+
FPM: Log message in shutdown function
3+
--SKIPIF--
4+
<?php include "skipif.inc"; ?>
5+
--FILE--
6+
<?php
7+
8+
require_once "tester.inc";
9+
10+
$cfg = <<<EOT
11+
[global]
12+
error_log = {{FILE:LOG}}
13+
log_limit = 1024
14+
log_buffering = yes
15+
[unconfined]
16+
listen = {{ADDR}}
17+
pm = dynamic
18+
pm.max_children = 5
19+
pm.start_servers = 1
20+
pm.min_spare_servers = 1
21+
pm.max_spare_servers = 3
22+
catch_workers_output = yes
23+
EOT;
24+
25+
$code = <<<EOT
26+
<?php
27+
register_shutdown_function(function() {
28+
error_log(str_repeat('e', 80));
29+
});
30+
EOT;
31+
32+
$tester = new FPM\Tester($cfg, $code);
33+
$tester->start();
34+
$tester->expectLogStartNotices();
35+
$tester->request()->expectEmptyBody();
36+
$tester->terminate();
37+
$tester->expectFastCGIErrorMessage('e', 1050, 80);
38+
$tester->expectLogMessage('NOTICE: PHP message: ' . str_repeat('e', 80), 1050);
39+
$tester->close();
40+
41+
?>
42+
Done
43+
--EXPECT--
44+
Done
45+
--CLEAN--
46+
<?php
47+
require_once "tester.inc";
48+
FPM\Tester::clean();
49+
?>

0 commit comments

Comments
 (0)