[prev in list] [next in list] [prev in thread] [next in thread] 

List:       php-internals
Subject:    [PHP-DEV] Suggestion: Add optional suffix to tempnam()
From:       Stefan Neufeind <neufeind () php ! net>
Date:       2014-01-11 19:15:28
Message-ID: 52D19850.1090104 () php ! net
[Download RAW message or body]

Hi,

I'd like to propose adding an optional $suffix to tempnam(). Please find
attached a patch that implements this against current master.

Help with this would be appreciated, especially if I did something
wrong, since it's my first php-src patch.

As you might expect, it can be used like
  echo tempnam('.', 'abc-', '.png');

We discussed the usecase lately in the TYPO3-community where there are
some cases where external tools would like to have a proper suffix for
temporary files. They currently use their own "workaround" to have a
tempnam() with suffix.


Kind regards,
 Stefan

["tempnam-add-suffix.patch" (text/x-patch)]

diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 4604f60..15fe41d 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -1094,9 +1094,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_file, 0, 0, 1)
 	ZEND_ARG_INFO(0, context)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO(arginfo_tempnam, 0)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_tempnam, 0, 0, 2)
 	ZEND_ARG_INFO(0, dir)
 	ZEND_ARG_INFO(0, prefix)
+	ZEND_ARG_INFO(0, suffix)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO(arginfo_tmpfile, 0)
diff --git a/ext/standard/file.c b/ext/standard/file.c
index 0dab6f2..27c8911 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -799,18 +799,18 @@ parse_eol:
 }
 /* }}} */
 
-/* {{{ proto string tempnam(string dir, string prefix)
+/* {{{ proto string tempnam(string dir, string prefix [, string suffix])
    Create a unique filename in a directory */
 PHP_FUNCTION(tempnam)
 {
-	char *dir, *prefix;
-	int dir_len, prefix_len;
+	char *dir, *prefix, *suffix = "";
+	int dir_len, prefix_len, suffix_len = 0;
 	size_t p_len;
 	char *opened_path;
 	char *p;
 	int fd;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ps", &dir, &dir_len, &prefix, \
&prefix_len) == FAILURE) { +	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \
"ps|s", &dir, &dir_len, &prefix, &prefix_len, &suffix, &suffix_len) == FAILURE) {  \
return;  }
 
@@ -825,7 +825,7 @@ PHP_FUNCTION(tempnam)
 
 	RETVAL_FALSE;
 
-	if ((fd = php_open_temporary_fd_ex(dir, p, &opened_path, 1 TSRMLS_CC)) >= 0) {
+	if ((fd = php_open_temporary_fd_ex(dir, p, &opened_path, 1 TSRMLS_CC, suffix)) >= \
0) {  close(fd);
 		RETVAL_STRING(opened_path, 0);
 	}
diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c
index ebe5350..871e90b 100644
--- a/main/php_open_temporary_file.c
+++ b/main/php_open_temporary_file.c
@@ -94,7 +94,7 @@
  * SUCH DAMAGE.
  */
 
-static int php_do_open_temporary_file(const char *path, const char *pfx, char \
**opened_path_p TSRMLS_DC) +static int php_do_open_temporary_file(const char *path, \
const char *pfx, char **opened_path_p TSRMLS_DC, const char *suffix)  {
 	char *trailing_slash;
 	char *opened_path;
@@ -138,7 +138,7 @@ static int php_do_open_temporary_file(const char *path, const \
char *pfx, char **  trailing_slash = "/";
 	}
 
-	if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) \
>= MAXPATHLEN) { +	if (spprintf(&opened_path, 0, "%s%s%sXXXXXX%s", new_state.cwd, \
> trailing_slash, pfx, suffix) >= MAXPATHLEN) {
 		efree(opened_path);
 		efree(new_state.cwd);
 		return -1;
@@ -158,7 +158,7 @@ static int php_do_open_temporary_file(const char *path, const \
char *pfx, char **  }
 
 #elif defined(HAVE_MKSTEMP)
-	fd = mkstemp(opened_path);
+	fd = mkstemps(opened_path, strlen(suffix));
 #else
 	if (mktemp(opened_path)) {
 		fd = VCWD_OPEN(opened_path, open_flags);
@@ -264,7 +264,7 @@ PHPAPI const char* php_get_temporary_directory(TSRMLS_D)
  * This function should do its best to return a file pointer to a newly created
  * unique file, on every platform.
  */
-PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char \
**opened_path_p, zend_bool open_basedir_check TSRMLS_DC) +PHPAPI int \
php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, \
zend_bool open_basedir_check TSRMLS_DC, const char *suffix)  {
 	int fd;
 	const char *temp_dir;
@@ -281,14 +281,14 @@ def_tmp:
 		temp_dir = php_get_temporary_directory(TSRMLS_C);
 
 		if (temp_dir && *temp_dir != '\0' && (!open_basedir_check || \
                !php_check_open_basedir(temp_dir TSRMLS_CC))) {
-			return php_do_open_temporary_file(temp_dir, pfx, opened_path_p TSRMLS_CC);
+			return php_do_open_temporary_file(temp_dir, pfx, opened_path_p TSRMLS_CC, \
suffix);  } else {
 			return -1;
 		}
 	}
 
 	/* Try the directory given as parameter. */
-	fd = php_do_open_temporary_file(dir, pfx, opened_path_p TSRMLS_CC);
+	fd = php_do_open_temporary_file(dir, pfx, opened_path_p TSRMLS_CC, suffix);
 	if (fd == -1) {
 		/* Use default temporary directory. */
 		goto def_tmp;
@@ -296,15 +296,15 @@ def_tmp:
 	return fd;
 }
 
-PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char \
**opened_path_p TSRMLS_DC) +PHPAPI int php_open_temporary_fd(const char *dir, const \
char *pfx, char **opened_path_p TSRMLS_DC, const char *suffix)  {
-	return php_open_temporary_fd_ex(dir, pfx, opened_path_p, 0 TSRMLS_CC);
+	return php_open_temporary_fd_ex(dir, pfx, opened_path_p, 0 TSRMLS_CC, suffix);
 }
 
-PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char \
**opened_path_p TSRMLS_DC) +PHPAPI FILE *php_open_temporary_file(const char *dir, \
const char *pfx, char **opened_path_p TSRMLS_DC, const char *suffix)  {
 	FILE *fp;
-	int fd = php_open_temporary_fd(dir, pfx, opened_path_p TSRMLS_CC);
+	int fd = php_open_temporary_fd(dir, pfx, opened_path_p TSRMLS_CC, suffix);
 
 	if (fd == -1) {
 		return NULL;
diff --git a/main/php_open_temporary_file.h b/main/php_open_temporary_file.h
index 873bffc..cdb4eee 100644
--- a/main/php_open_temporary_file.h
+++ b/main/php_open_temporary_file.h
@@ -22,9 +22,9 @@
 #define PHP_OPEN_TEMPORARY_FILE_H
 
 BEGIN_EXTERN_C()
-PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char \
                **opened_path_p TSRMLS_DC);
-PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char \
                **opened_path_p, zend_bool open_basedir_check TSRMLS_DC);
-PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char \
**opened_path_p TSRMLS_DC); +PHPAPI FILE *php_open_temporary_file(const char *dir, \
const char *pfx, char **opened_path_p TSRMLS_DC, const char *suffix); +PHPAPI int \
php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, \
zend_bool open_basedir_check TSRMLS_DC, const char *suffix); +PHPAPI int \
php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p \
TSRMLS_DC, const char *suffix);  PHPAPI const char \
*php_get_temporary_directory(TSRMLS_D);  PHPAPI void \
php_shutdown_temporary_directory(void);  END_EXTERN_C()
diff --git a/main/rfc1867.c b/main/rfc1867.c
index b1011e2..1700efa 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -1003,7 +1003,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
 				/* in non-debug mode we have no problem with 0-length files */
 				{
 #endif
-					fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, 1 \
TSRMLS_CC); +					fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", \
&temp_filename, 1 TSRMLS_CC, "");  upload_cnt--;
 					if (fd == -1) {
 						sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a \
                temporary file");
diff --git a/main/streams/php_stream_plain_wrapper.h \
b/main/streams/php_stream_plain_wrapper.h index 4370867..897042b 100644
--- a/main/streams/php_stream_plain_wrapper.h
+++ b/main/streams/php_stream_plain_wrapper.h
@@ -45,8 +45,8 @@ PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const \
char *mode STRE  PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC \
TSRMLS_DC);  #define php_stream_fopen_tmpfile()	_php_stream_fopen_tmpfile(0 \
STREAMS_CC TSRMLS_CC)  
-PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char \
                *pfx, char **opened_path STREAMS_DC TSRMLS_DC);
-#define php_stream_fopen_temporary_file(dir, pfx, \
opened_path)	_php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_CC \
TSRMLS_CC) +PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, \
const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC, const char *suffix); \
+#define php_stream_fopen_temporary_file(dir, pfx, opened_path, \
suffix)	_php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_CC \
TSRMLS_CC, (suffix))  
 /* This is a utility API for extensions that are opening a stream, converting it
  * to a FILE* and then closing it again.  Be warned that fileno() on the result
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index 6ddfc74..3cd9eeb 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -183,9 +183,9 @@ static php_stream *_php_stream_fopen_from_file_int(FILE *file, \
const char *mode  return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode);
 }
 
-PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char \
*pfx, char **opened_path STREAMS_DC TSRMLS_DC) +PHPAPI php_stream \
*_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char \
**opened_path STREAMS_DC TSRMLS_DC, const char *suffix)  {
-	int fd = php_open_temporary_fd(dir, pfx, opened_path TSRMLS_CC);
+	int fd = php_open_temporary_fd(dir, pfx, opened_path TSRMLS_CC, suffix);
 
 	if (fd != -1)	{
 		php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL);
@@ -204,7 +204,7 @@ PHPAPI php_stream *_php_stream_fopen_temporary_file(const char \
*dir, const char  PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC \
TSRMLS_DC)  {
 	char *opened_path = NULL;
-	int fd = php_open_temporary_fd(NULL, "php", &opened_path TSRMLS_CC);
+	int fd = php_open_temporary_fd(NULL, "php", &opened_path TSRMLS_CC, "");
 
 	if (fd != -1)	{
 		php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL);



-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic