PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - main - php_open_temporary_file.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 52 65 80.0 %
Date: 2014-07-27 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2013 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Author: Zeev Suraski <zeev@zend.com>                                 |
      16             :    +----------------------------------------------------------------------+
      17             :  */
      18             : 
      19             : /* $Id$ */
      20             : 
      21             : #include "php.h"
      22             : 
      23             : #include <errno.h>
      24             : #include <sys/types.h>
      25             : #include <sys/stat.h>
      26             : #include <fcntl.h>
      27             : 
      28             : #ifdef PHP_WIN32
      29             : #define O_RDONLY _O_RDONLY
      30             : #include "win32/param.h"
      31             : #include "win32/winutil.h"
      32             : #elif defined(NETWARE)
      33             : #ifdef USE_WINSOCK
      34             : #include <novsock2.h>
      35             : #else
      36             : #include <sys/socket.h>
      37             : #endif
      38             : #include <sys/param.h>
      39             : #else
      40             : #include <sys/param.h>
      41             : #include <sys/socket.h>
      42             : #include <netinet/in.h>
      43             : #include <netdb.h>
      44             : #if HAVE_ARPA_INET_H
      45             : #include <arpa/inet.h>
      46             : #endif
      47             : #endif
      48             : #ifdef HAVE_SYS_TIME_H
      49             : #include <sys/time.h>
      50             : #endif
      51             : 
      52             : #ifdef HAVE_SYS_FILE_H
      53             : #include <sys/file.h>
      54             : #endif
      55             : 
      56             : #if !defined(P_tmpdir)
      57             : #define P_tmpdir ""
      58             : #endif
      59             : 
      60             : /* {{{ php_do_open_temporary_file */
      61             : 
      62             : /* Loosely based on a tempnam() implementation by UCLA */
      63             : 
      64             : /*
      65             :  * Copyright (c) 1988, 1993
      66             :  *      The Regents of the University of California.  All rights reserved.
      67             :  *
      68             :  * Redistribution and use in source and binary forms, with or without
      69             :  * modification, are permitted provided that the following conditions
      70             :  * are met:
      71             :  * 1. Redistributions of source code must retain the above copyright
      72             :  *    notice, this list of conditions and the following disclaimer.
      73             :  * 2. Redistributions in binary form must reproduce the above copyright
      74             :  *    notice, this list of conditions and the following disclaimer in the
      75             :  *    documentation and/or other materials provided with the distribution.
      76             :  * 3. All advertising materials mentioning features or use of this software
      77             :  *    must display the following acknowledgement:
      78             :  *      This product includes software developed by the University of
      79             :  *      California, Berkeley and its contributors.
      80             :  * 4. Neither the name of the University nor the names of its contributors
      81             :  *    may be used to endorse or promote products derived from this software
      82             :  *    without specific prior written permission.
      83             :  *
      84             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      85             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      86             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      87             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      88             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      89             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      90             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      91             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      92             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      93             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      94             :  * SUCH DAMAGE.
      95             :  */
      96             : 
      97       15011 : static int php_do_open_temporary_file(const char *path, const char *pfx, char **opened_path_p TSRMLS_DC)
      98             : {
      99             :         char *trailing_slash;
     100             :         char *opened_path;
     101             :         char cwd[MAXPATHLEN];
     102             :         cwd_state new_state;
     103       15011 :         int fd = -1;
     104             : #ifndef HAVE_MKSTEMP
     105             :         int open_flags = O_CREAT | O_TRUNC | O_RDWR
     106             : #ifdef PHP_WIN32
     107             :                 | _O_BINARY
     108             : #endif
     109             :                 ;
     110             : #endif
     111             : 
     112       15011 :         if (!path || !path[0]) {
     113           0 :                 return -1;
     114             :         }
     115             : 
     116             : #ifdef PHP_WIN32
     117             :         if (!php_win32_check_trailing_space(pfx, (const int)strlen(pfx))) {
     118             :                 SetLastError(ERROR_INVALID_NAME);
     119             :                 return -1;
     120             :         }
     121             : #endif
     122             : 
     123       15011 :         if (!VCWD_GETCWD(cwd, MAXPATHLEN)) {
     124           0 :                 cwd[0] = '\0';
     125             :         }
     126             : 
     127       15011 :         new_state.cwd = strdup(cwd);
     128       15011 :         new_state.cwd_length = strlen(cwd);
     129             : 
     130       15011 :         if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) {
     131          10 :                 free(new_state.cwd);
     132          10 :                 return -1;
     133             :         }
     134             : 
     135       15001 :         if (IS_SLASH(new_state.cwd[new_state.cwd_length - 1])) {
     136           0 :                 trailing_slash = "";
     137             :         } else {
     138       15001 :                 trailing_slash = "/";
     139             :         }
     140             : 
     141       15001 :         if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) {
     142           0 :                 efree(opened_path);
     143           0 :                 free(new_state.cwd);
     144           0 :                 return -1;
     145             :         }
     146             : 
     147             : #ifdef PHP_WIN32
     148             : 
     149             :         if (GetTempFileName(new_state.cwd, pfx, 0, opened_path)) {
     150             :                 /* Some versions of windows set the temp file to be read-only,
     151             :                  * which means that opening it will fail... */
     152             :                 if (VCWD_CHMOD(opened_path, 0600)) {
     153             :                         efree(opened_path);
     154             :                         free(new_state.cwd);
     155             :                         return -1;
     156             :                 }
     157             :                 fd = VCWD_OPEN_MODE(opened_path, open_flags, 0600);
     158             :         }
     159             : 
     160             : #elif defined(HAVE_MKSTEMP)
     161       15001 :         fd = mkstemp(opened_path);
     162             : #else
     163             :         if (mktemp(opened_path)) {
     164             :                 fd = VCWD_OPEN(opened_path, open_flags);
     165             :         }
     166             : #endif
     167             : 
     168       15385 :         if (fd == -1 || !opened_path_p) {
     169         384 :                 efree(opened_path);
     170             :         } else {
     171       14617 :                 *opened_path_p = opened_path;
     172             :         }
     173       15001 :         free(new_state.cwd);
     174       15001 :         return fd;
     175             : }
     176             : /* }}} */
     177             : 
     178             : /* Cache the chosen temporary directory. */
     179             : static char* temporary_directory;
     180             : 
     181       19376 : PHPAPI void php_shutdown_temporary_directory(void)
     182             : {
     183       19376 :         if (temporary_directory) {
     184         470 :                 free(temporary_directory);
     185         470 :                 temporary_directory = NULL;
     186             :         }
     187       19376 : }
     188             : 
     189             : /*
     190             :  *  Determine where to place temporary files.
     191             :  */
     192       15136 : PHPAPI const char* php_get_temporary_directory(void)
     193             : {
     194             :         /* Did we determine the temporary directory already? */
     195       15136 :         if (temporary_directory) {
     196       14666 :                 return temporary_directory;
     197             :         }
     198             : 
     199             : #ifdef PHP_WIN32
     200             :         /* We can't count on the environment variables TEMP or TMP,
     201             :          * and so must make the Win32 API call to get the default
     202             :          * directory for temporary files.  Note this call checks
     203             :          * the environment values TMP and TEMP (in order) first.
     204             :          */
     205             :         {
     206             :                 char sTemp[MAX_PATH];
     207             :                 DWORD len = GetTempPath(sizeof(sTemp),sTemp);
     208             :                 assert(0 < len);  /* should *never* fail! */
     209             :                 if (sTemp[len - 1] == DEFAULT_SLASH) {
     210             :                         temporary_directory = zend_strndup(sTemp, len - 1);
     211             :                 } else {
     212             :                         temporary_directory = zend_strndup(sTemp, len);
     213             :                 }
     214             :                 return temporary_directory;
     215             :         }
     216             : #else
     217             :         /* On Unix use the (usual) TMPDIR environment variable. */
     218             :         {
     219         470 :                 char* s = getenv("TMPDIR");
     220         470 :                 if (s && *s) {
     221           0 :                         int len = strlen(s);
     222             : 
     223           0 :                         if (s[len - 1] == DEFAULT_SLASH) {
     224           0 :                                 temporary_directory = zend_strndup(s, len - 1);
     225             :                         } else {
     226           0 :                                 temporary_directory = zend_strndup(s, len);
     227             :                         }
     228             : 
     229           0 :                         return temporary_directory;
     230             :                 }
     231             :         }
     232             : #ifdef P_tmpdir
     233             :         /* Use the standard default temporary directory. */
     234             :         if (P_tmpdir) {
     235         470 :                 temporary_directory = strdup(P_tmpdir);
     236         470 :                 return temporary_directory;
     237             :         }
     238             : #endif
     239             :         /* Shouldn't ever(!) end up here ... last ditch default. */
     240             :         temporary_directory = strdup("/tmp");
     241             :         return temporary_directory;
     242             : #endif
     243             : }
     244             : 
     245             : /* {{{ php_open_temporary_file
     246             :  *
     247             :  * Unlike tempnam(), the supplied dir argument takes precedence
     248             :  * over the TMPDIR environment variable
     249             :  * This function should do its best to return a file pointer to a newly created
     250             :  * unique file, on every platform.
     251             :  */
     252       14618 : PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, zend_bool open_basedir_check TSRMLS_DC)
     253             : {
     254             :         int fd;
     255             :         const char *temp_dir;
     256             : 
     257       14618 :         if (!pfx) {
     258           1 :                 pfx = "tmp.";
     259             :         }
     260       14618 :         if (opened_path_p) {
     261       14618 :                 *opened_path_p = NULL;
     262             :         }
     263             : 
     264       14618 :         if (!dir || *dir == '\0') {
     265             : def_tmp:
     266       14268 :                 temp_dir = php_get_temporary_directory();
     267             : 
     268       14268 :                 if (temp_dir && *temp_dir != '\0' && (!open_basedir_check || !php_check_open_basedir(temp_dir TSRMLS_CC))) {
     269       14267 :                         return php_do_open_temporary_file(temp_dir, pfx, opened_path_p TSRMLS_CC);
     270             :                 } else {
     271           1 :                         return -1;
     272             :                 }
     273             :         }
     274             : 
     275             :         /* Try the directory given as parameter. */
     276         744 :         fd = php_do_open_temporary_file(dir, pfx, opened_path_p TSRMLS_CC);
     277         744 :         if (fd == -1) {
     278             :                 /* Use default temporary directory. */
     279         394 :                 goto def_tmp;
     280             :         }
     281         350 :         return fd;
     282             : }
     283             : 
     284       13849 : PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC)
     285             : {
     286       13849 :         return php_open_temporary_fd_ex(dir, pfx, opened_path_p, 0 TSRMLS_CC);
     287             : }
     288             : 
     289           1 : PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC)
     290             : {
     291             :         FILE *fp;
     292           1 :         int fd = php_open_temporary_fd(dir, pfx, opened_path_p TSRMLS_CC);
     293             : 
     294           1 :         if (fd == -1) {
     295           0 :                 return NULL;
     296             :         }
     297             :         
     298           1 :         fp = fdopen(fd, "r+b");
     299           1 :         if (fp == NULL) {
     300           0 :                 close(fd);
     301             :         }
     302             :         
     303           1 :         return fp;
     304             : }
     305             : /* }}} */
     306             : 
     307             : /*
     308             :  * Local variables:
     309             :  * tab-width: 4
     310             :  * c-basic-offset: 4
     311             :  * End:
     312             :  * vim600: sw=4 ts=4 fdm=marker
     313             :  * vim<600: sw=4 ts=4
     314             :  */

Generated by: LCOV version 1.10

Generated at Sun, 27 Jul 2014 12:58:42 +0000 (4 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.