summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Feldman <sasha@php.net>2001-03-11 10:08:27 +0000
committerAlexander Feldman <sasha@php.net>2001-03-11 10:08:27 +0000
commit397c76d7877cdc82b0e7bf7901ad7dbbd7e84163 (patch)
treea3094026116b622adcc5c4348a0dab64c93b45c0
parentba12d0b4b1698de4daf894657ec6d21676e95e43 (diff)
downloadphp-git-397c76d7877cdc82b0e7bf7901ad7dbbd7e84163.tar.gz
Fixed a compatibility problem is some file functions (fgets, fputs, fread,
fwrite). The ANSI standard says that if a file is opened in read/write mode, fseek() should be called before switching from reading to writing and vice versa.
-rw-r--r--NEWS4
-rw-r--r--ext/standard/config.m452
-rw-r--r--ext/standard/file.c16
3 files changed, 72 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index fdad917b50..77002037fd 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP 4.0 NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 200?, Version 4.0.5
+- Fixed a compatibility problem in some file functions (fgets, fputs, fread,
+ fwrite). The ANSI standard says that if a file is opened in read/write
+ mode, fseek() should be called before switching from reading to writing
+ and vice versa. (alex@zend.com)
- Fixed argument checking for call_user_func* functions and allowed
specifying array($obj, 'method') syntax for call_user_func_array. (Andrei)
- Fixed parent::method() to also work with runtime bindings (Zeev, Zend Engine)
diff --git a/ext/standard/config.m4 b/ext/standard/config.m4
index 9752ba0d42..d1c7cfd5a0 100644
--- a/ext/standard/config.m4
+++ b/ext/standard/config.m4
@@ -3,6 +3,57 @@ dnl $Id$ -*- sh -*-
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_LIB(pam, pam_start, [
AC_CHECK_FUNCS(getcwd getwd)
AC_CRYPT_CAP
+AC_FLUSH_IO
divert(5)dnl
diff --git a/ext/standard/file.c b/ext/standard/file.c
index b1500e37d8..2808d41a6b 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -918,6 +918,11 @@ PHP_FUNCTION(fgets)
buf = emalloc(sizeof(char) * (len + 1));
/* needed because recv doesnt put a null at the end*/
memset(buf,0,len+1);
+#ifdef HAVE_FLUSHIO
+ if (!issock) {
+ fseek((FILE*)what, 0, SEEK_CUR);
+ }
+#endif
if (FP_FGETS(buf, len, socketd, (FILE*)what, issock) == NULL) {
efree(buf);
RETVAL_FALSE;
@@ -961,6 +966,11 @@ PHP_FUNCTION(fgetc) {
socketd=*(int*)what;
}
+#ifdef HAVE_FLUSHIO
+ if (!issock) {
+ fseek((FILE*)what, 0, SEEK_CUR);
+ }
+#endif
buf = emalloc(sizeof(int));
if ((result = FP_FGETC(socketd, (FILE*)what, issock)) == EOF) {
efree(buf);
@@ -1159,6 +1169,9 @@ PHP_FUNCTION(fwrite)
if (issock){
ret = SOCK_WRITEL((*arg2)->value.str.val,num_bytes,socketd);
} else {
+#ifdef HAVE_FLUSHIO
+ fseek((FILE*)what, 0, SEEK_CUR);
+#endif
ret = fwrite((*arg2)->value.str.val,1,num_bytes,(FILE*)what);
}
RETURN_LONG(ret);
@@ -1794,6 +1807,9 @@ PHP_FUNCTION(fread)
/* needed because recv doesnt put a null at the end*/
if (!issock) {
+#ifdef HAVE_FLUSHIO
+ fseek((FILE*)what, 0, SEEK_CUR);
+#endif
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;
} else {