From: Derick Rethans Date: Sun, 7 Oct 2001 18:34:44 +0000 (+0000) Subject: @- Added mmapfile(), read a file into a variabele with mmap (Ilia A, Derick) X-Git-Tag: PRE_PARAMETER_PARSING_API~44 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=62fb3d63c51c834c4854d10b7674e42ddca2daa8;p=php @- Added mmapfile(), read a file into a variabele with mmap (Ilia A, Derick) - Added mmapfile(), read a file into a variabele with mmap (Patch by: Ilia A. ) --- diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index a0fe897118..e6e136d3ea 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -576,6 +576,9 @@ function_entry basic_functions[] = { PHP_FE(pclose, NULL) PHP_FE(popen, NULL) PHP_FE(readfile, NULL) +#if HAVE_MMAP + PHP_FE(mmapfile, NULL) +#endif PHP_FE(rewind, NULL) PHP_FE(rmdir, NULL) PHP_FE(umask, NULL) diff --git a/ext/standard/file.c b/ext/standard/file.c index 970a8309ae..fadfa664f2 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1633,6 +1633,89 @@ PHP_FUNCTION(readfile) } /* }}} */ + +#if HAVE_MMAP + +/* {{{ proto string mmapfile (string filename [, int bytes_to_read]) + Read a file into a variable with mmap */ +PHP_FUNCTION(mmapfile) +{ + zval **arg1, **arg2; + int in, bytes_to_read = 0; + char *data; + char *in_addr; + struct stat f_stat; + + memset (&f_stat, 0, sizeof (stat)); + + /* check args */ + switch (ARG_COUNT(ht)) { + case 1: + if (zend_get_parameters_ex (1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + break; + case 2: + if (zend_get_parameters_ex (2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long_ex (arg2); + bytes_to_read = (*arg2)->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + convert_to_string_ex (arg1); + + if ((in = open ((*arg1)->value.str.val, O_RDONLY)) == -1) { + php_error (E_WARNING, "can't re-open input file for mmap"); + RETURN_FALSE; + } + + if (fstat (in, &f_stat)) { + php_error (E_WARNING, "cannot get file information"); + RETURN_FALSE; + } + + if (!bytes_to_read) { + bytes_to_read = f_stat.st_size; + } else { + bytes_to_read = (bytes_to_read < f_stat.st_size) ? bytes_to_read : f_stat.st_size; + } + + if ((in_addr = mmap (NULL, bytes_to_read, PROT_READ, MAP_SHARED, in, 0)) == (char*) -1) { + php_error (E_WARNING, "can't mmap file"); + RETURN_FALSE; + } + + data = emalloc (bytes_to_read + 1); + data[bytes_to_read + 1] = '\0'; + + if (!memcpy(data, in_addr, bytes_to_read)) { + efree (data); + php_error (E_WARNING, "cannot copy file to memory"); + RETURN_FALSE; + } + + if (munmap(in_addr, bytes_to_read)) { + efree (data); + php_error (E_WARNING, "cannot unmap the file"); + RETURN_FALSE; + } + + if (close(in)) { + efree (data); + php_error (E_WARNING, "cannot close file"); + RETURN_FALSE; + } + + RETURN_STRINGL(data, bytes_to_read + 1, 0); +} +/* }}} */ + +#endif + + /* {{{ proto int umask([int mask]) Return or change the umask */ PHP_FUNCTION(umask) @@ -1659,6 +1742,8 @@ PHP_FUNCTION(umask) } /* }}} */ + + /* {{{ proto int fpassthru(int fp) Output all remaining data from a file pointer */ diff --git a/ext/standard/file.h b/ext/standard/file.h index b12a72838c..e3cdc4aad9 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -48,6 +48,9 @@ PHP_FUNCTION(mkdir); PHP_FUNCTION(rmdir); PHP_FUNCTION(fpassthru); PHP_FUNCTION(readfile); +#if HAVE_MMAP +PHP_FUNCTION(mmapfile); +#endif PHP_FUNCTION(umask); PHP_FUNCTION(rename); PHP_FUNCTION(unlink);