Hi,
>From the fopen(3) manual page on Solaris 2.6 (it is the same on Solaris 7
and Solaris 8):
When a file is opened with update mode (+ as the second or
third character in the mode argument), both input and output
may be performed on the associated stream. However, output
must not be directly followed by input without an interven-
ing call to fflush(3S) or to a file positioning function
(fseek(3S), fsetpos(3S) or rewind(3S)), and input must not
be directly followed by output without an intervening call
to a file positioning function, unless the input operation
encounters end-of-file.
The nasty behaviour remains even if we disable the buffering with call to
setbuf. This imposes a significant compatibility problem with the PHP file
io functions. The decision is to call explicitly fflush() when changing
the direction of the data flow.
I prepared a fix for this (it can be optimized and improved heavily), but
before I commit it I want to hear your opinion. Please see the attachment.
Thank you:
--
Alexander Feldman
Zend Technologies Ltd.
phone: +972 3 6139665 ext. 113, fax: +972 3 6139671
http://www.zend.com
diff -u ext/standard/config.m4 ../php-4.0.4pl1.fix/ext/standard/config.m4
--- ext/standard/config.m4 Wed Jul 19 19:19:40 2000
+++ ../php-4.0.4pl1.fix/ext/standard/config.m4 Mon Feb 19 20:48:43 2001
@@ -3,6 +3,57 @@
divert(3)dnl
dnl
+dnl Check if flush should be called explicitly after buffered io
+dnl
+AC_DEFUN(AC_FLUSH_IO,[
+ AC_CACHE_CHECK([whether flush should be called explicitly after a bufferered io],
+ac_cv_flush_io,[
+ AC_TRY_RUN( [
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+ char *filename = tmpnam(NULL);
+ char buffer[64];
+ int result = 0;
+
+ FILE *fp = fopen(filename, "wb");
+ if (NULL == fp)
+ return 0;
+ fputs("line 1\n", fp);
+ fputs("line 2\n", fp);
+ fclose(fp);
+
+ fp = fopen(filename, "rb+");
+ if (NULL == fp)
+ return 0;
+ fgets(buffer, sizeof(buffer), fp);
+ fputs("line 3\n", fp);
+ rewind(fp);
+ fgets(buffer, sizeof(buffer), fp);
+ if (0 != strcmp(buffer, "line 1\n"))
+ result = 1;
+ fgets(buffer, sizeof(buffer), fp);
+ if (0 != strcmp(buffer, "line 3\n"))
+ result = 1;
+ fclose(fp);
+ unlink(filename);
+
+ exit(result);
+}
+],[
+ ac_cv_flush_io="no"
+],[
+ ac_cv_flush_io="yes"
+],[
+ ac_cv_flush_io="no"
+])])
+ if test "$ac_cv_flush_io" = "yes"; then
+ AC_DEFINE(HAVE_FLUSHIO, 1, [Define if flush should be called explicitly after a
+buffered io.])
+ fi
+])
+
+dnl
dnl Check for crypt() capabilities
dnl
AC_DEFUN(AC_CRYPT_CAP,[
@@ -143,6 +194,7 @@
AC_CHECK_FUNCS(getcwd getwd)
AC_CRYPT_CAP
+AC_FLUSH_IO
divert(5)dnl
diff -u ext/standard/file.c ../php-4.0.4pl1.fix/ext/standard/file.c
--- ext/standard/file.c Thu Dec 14 16:34:51 2000
+++ ../php-4.0.4pl1.fix/ext/standard/file.c Mon Feb 19 20:55:59 2001
@@ -882,6 +882,10 @@
efree(buf);
RETVAL_FALSE;
} else {
+#ifdef HAVE_FLUSHIO
+ if (!issock)
+ fflush((FILE*)what);
+#endif
if (PG(magic_quotes_runtime)) {
return_value->value.str.val =
php_addslashes(buf,0,&return_value->value.str.len,1);
} else {
@@ -926,6 +930,10 @@
efree(buf);
RETVAL_FALSE;
} else {
+#ifdef HAVE_FLUSHIO
+ if (!issock)
+ fflush((FILE*)what);
+#endif
buf[0]=result;
buf[1]='\0';
return_value->value.str.val = buf;
@@ -1119,6 +1127,9 @@
if (issock){
ret = SOCK_WRITEL((*arg2)->value.str.val,num_bytes,socketd);
} else {
+#ifdef HAVE_FLUSHIO
+ fflush((FILE*)what);
+#endif
ret = fwrite((*arg2)->value.str.val,1,num_bytes,(FILE*)what);
}
RETURN_LONG(ret);
@@ -1731,6 +1742,9 @@
if (!issock) {
return_value->value.str.len = fread(return_value->value.str.val, 1,
len, (FILE*)what);
return_value->value.str.val[return_value->value.str.len] = 0;
+#ifdef HAVE_FLUSHIO
+ fflush((FILE*)what);
+#endif
} else {
return_value->value.str.len = SOCK_FREAD(return_value->value.str.val,
len, socketd);
}
--- main/php_config.h.in Thu Jan 11 20:39:35 2001
+++ ../php-4.0.4pl1.fix/main/php_config.h.in Mon Feb 19 20:56:35 2001
@@ -1547,6 +1547,9 @@
/* Whether the system supports BlowFish salt */
#undef PHP_BLOWFISH_CRYPT
+/* Define if flush should be called explicitly after a buffered io. */
+#undef HAVE_FLUSHIO
+
/* Whether to build standard as dynamic module */
#undef COMPILE_DL_STANDARD
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]