From: Alexander Feldman Date: Sun, 11 Mar 2001 10:08:27 +0000 (+0000) Subject: Fixed a compatibility problem is some file functions (fgets, fputs, fread, X-Git-Tag: php-4.0.5RC1~31 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=397c76d7877cdc82b0e7bf7901ad7dbbd7e84163;p=php 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. --- 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 @@ -2,6 +2,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 +#include + +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 @@ -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 {