ID: 21641 User updated by: [EMAIL PROTECTED] Reported By: [EMAIL PROTECTED] -Status: Bogus +Status: Open Bug Type: Filesystem function related Operating System: Linux 2.4.18 PHP Version: 4CVS-2003-01-14 (stable) New Comment:
However, this causes problems for smaller values when the function that stream_read() is calling doesn't like it when the byte count is larger than its size. Consider this code (from the shared memory stream wrapper I am working on) function stream_read($count) { $data = shmop_read($this->shm,$this->pos,$count); $this->pos += strlen($data); return $data; } If the shared memory segment that $this->shm points to is less than 8192 bytes long, then shmop_read() complains that the count is out of range. Here's some sample code if you want to try (thanks to Xavier Noguer [[EMAIL PROTECTED]] who reported this to me): <?php class Stream_SHM { var $pos = 0; var $shm_key; var $size = 16384; // default size: 16k var $shm; function stream_open($path, $mode, $options, &$opened_path) { $url = parse_url($path); $this->shm_key = $url['host']; if ((! intval($this->shm_key)) && (! preg_match('/^0x[0-9a-f]+$/i', $this->shm_key))) { if ($options & STREAM_REPORT_ERRORS) { trigger_error("Stream_SHM::stream_open: $this->shm_key is not a valid shm key.",E_USER_ERROR); } return false; } if (intval($url['port'])) { $this->size = intval($url['port']); } if (($mode != 'a') && ($mode != 'c') && ($mode != 'w') && ($mode != 'n')) { if ($options & STREAM_REPORT_ERRORS) { trigger_error("Stream_SHM::stream_open: $mode is not a valid mode (must be one of: a c n w)",E_USER_ERROR); } return false; } if (! ($this->shm = shmop_open($this->shm_key,$mode,0600,$this->size))) { if ($options & STREAM_REPORT_ERRORS) { trigger_error('Stream_SHM::stream_open: shmop_open() failed'); } return false; } $this->size = shmop_size($this->shm); return true; } function stream_close() { shmop_close($this->shm); } function stream_read($count) { $data = shmop_read($this->shm,$this->pos,$count); $this->pos += strlen($data); return $data; } function stream_write($data) { $count = shmop_write($this->shm,$data,$this->pos); $this->pos += $count; return $count; } function stream_eof() { return ($this->pos == ($this->size - 1)); } function stream_tell() { return $this->pos; } function stream_seek($offset,$whence) { switch ($whence) { case SEEK_SET: if (($offset >= 0) && ($offset < $this->size)) { $this->pos = $offset; return true; } else { return false; } break; case SEEK_CUR: if (($offset >= 0) && (($this->pos + $offset) < $this->size)) { $this->pos += $offset; return true; } else { return false; } break; case SEEK_END: if (($this->size + $offset) >= 0) { $this->pos = $this->size + $offset; return true; } else { return false; } break; default: return false; } } function stream_flush() { return true; } } stream_register_wrapper('shm', 'Stream_SHM') or die("Can't register shm on Stream_SHM"); echo "\nUsing shm://0x0000:8192/\n"; $mem = fopen("shm://0x0000:8192/","c"); fwrite($mem, "hola\n"); rewind($mem); $data = fread($mem, 4); echo "$data\n"; fclose($mem); echo "\nUsing shm://0x0000:8191/\n"; $mem = fopen("shm://0x0000:8191/","c"); fwrite($mem, "hola\n"); rewind($mem); $data = fread($mem, 4); echo "$data\n"; fclose($mem); echo "\nUsing shmop_open() with size = 8191\n"; //shm://0x0000:8191/"; $mem = shmop_open(0x0000, "c", 0600, 8191); $shm_bytes_written = shmop_write($mem, "hola", 0); $data = shmop_read($mem, 0, 4); echo "$data\n"; shmop_close($mem); ?> The first example, with the stream and an 8192 byte segment, works fine. The last example, without the stream and with an 8191 byte segment, works fine. The middle example, however, with the stream and an 8191 byte segment fails, because the call to shmop_read() throws a "count is out of range" error. Previous Comments: ------------------------------------------------------------------------ [2003-01-14 15:09:37] [EMAIL PROTECTED] This is not a bug; PHP uses an internal read buffer 8192 bytes in length in order to be more efficient. You should note that fread() returns the correct number of bytes to your script. ------------------------------------------------------------------------ [2003-01-14 14:59:09] [EMAIL PROTECTED] The stream_read() method of a class registered with stream_register_wrapper() is always passed 8192 as a count of bytes to read no matter what the second argument is to an fread() on that stream. This is reproduceable with the following class and test code: <?php class Stream_File { var $fn; var $fp; function stream_open($path, $mode, $options, &$opened_path) { $url = parse_url($path); $this->fp = fopen($this->fn = $url['path'],$mode); return ($this->fp ? true : false); } function stream_close() { fclose($this->fp); } function stream_read($count) { error_log("stream_read: $count "); return fread($this->fp,$count); } function stream_write($data) { return fwrite($this->fp,$data); } function stream_eof() { return feof($this->fp); } function stream_tell() { return ftell($this->fp); } function stream_seek($offset,$whence) { return fseek($this->fp,$offset,$whence); } function stream_flush() { return fflush($this->fp); } } stream_register_wrapper('filetest', 'Stream_File') or die("Can't register filetest on Stream_File"); $fp = fopen("filetest://localhost/tmp/hello","w+"); fwrite($fp, "testing\n"); rewind($fp); $data = fread($fp, 10); echo "$data\n"; rewind($fp); $data = fread($fp,32000); echo "$data\n"; fclose($fp); ?> Each time fread() is called on the stream, the error_log() call in stream_read() prints: stream_read: 8192 instead of "stream_read: 10" or "stream_read: 32000" ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=21641&edit=1