running cacti on a low memory server I stumbled upon a very ghastly error condition. When the system was short on memory apache looped when I tried to open a rrd and threw tons of "fgets(): supplied argument is not a valid stream resource" into the httpd error log file.
It took me a while until I didn't only look at the error itself but the error before that... php wasn't able to popen the rrdtool in lib/rrd.h, line 97 because there wasn't memory left.
The point here is that popen returns $fp as "FALSE" in this case, which isn't the same as "unset". Later on (line 117) it is checked if $fp is set... if it is (but it is false) the script enters a loop (while (!feof($fp)) which will never happen).
I figure it is better to escape this condition and to unset $fp if it won't popen correctly. I figure that the same will happen under Windos, so I added a check there, too.
Code: Select all
-bash-3.2# diff -c rrd.php.old rrd.php
*** rrd.php.old Mon Dec 29 15:29:54 2008
--- rrd.php Mon Dec 29 15:30:22 2008
***************
*** 95,100 ****
--- 95,103 ----
if (sizeof($rrd_struc) == 0) {
session_write_close();
$fp = popen(read_config_option("path_rrdtool") . escape_command(" $command_line"), "r");
+ if (!$fp) {
+ unset($fp);
+ }
}else{
fwrite(rrd_get_fd($rrd_struc, RRDTOOL_PIPE_CHILD_READ), escape_command(" $command_line") . "\r\n");
fflush(rrd_get_fd($rrd_struc, RRDTOOL_PIPE_CHILD_READ));
***************
*** 104,109 ****
--- 107,115 ----
if (sizeof($rrd_struc) == 0) {
session_write_close();
$fp = popen(read_config_option("path_rrdtool") . escape_command(" $command_line"), "rb");
+ if (!$fp) {
+ unset($fp);
+ }
}else{
fwrite(rrd_get_fd($rrd_struc, RRDTOOL_PIPE_CHILD_READ), escape_command(" $command_line") . "\r\n");
fflush(rrd_get_fd($rrd_struc, RRDTOOL_PIPE_CHILD_READ));
Cheers
Knallfrosch