LCOV - code coverage report
Current view: top level - sal/osl/unx - tempfile.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 95 105 90.5 %
Date: 2012-08-25 Functions: 6 6 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 28 50 56.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : /*****************************************************************/
      30                 :            : /* Includes                                                      */
      31                 :            : /*****************************************************************/
      32                 :            : 
      33                 :            : #include <stdio.h>
      34                 :            : #include <stdlib.h>
      35                 :            : #include <sys/types.h>
      36                 :            : #include <sys/stat.h>
      37                 :            : #include <sys/time.h>
      38                 :            : #include "system.h"
      39                 :            : #include <osl/file.h>
      40                 :            : #include <osl/thread.h>
      41                 :            : #include <rtl/ustrbuf.h>
      42                 :            : #include <osl/diagnose.h>
      43                 :            : #include <sal/macros.h>
      44                 :            : 
      45                 :            : #ifndef _FILE_URL_H_
      46                 :            : #include "file_url.h"
      47                 :            : #endif
      48                 :            : 
      49                 :       5008 : oslFileError SAL_CALL osl_getTempDirURL( rtl_uString** pustrTempDir )
      50                 :            : {
      51                 :            :     oslFileError error;
      52                 :            :     /* described in environ(7) */
      53                 :       5008 :     const char *pValue = getenv( "TMPDIR" );
      54                 :       5008 :     rtl_uString *ustrTempPath = NULL;
      55                 :            : 
      56         [ -  + ]:       5008 :     if ( !pValue )
      57                 :          0 :         pValue = getenv( "TEMP" );
      58                 :            : 
      59         [ -  + ]:       5008 :     if ( !pValue )
      60                 :          0 :         pValue = getenv( "TMP" );
      61                 :            : 
      62         [ -  + ]:       5008 :     if ( !pValue )
      63                 :          0 :         pValue = "/tmp";
      64                 :            : 
      65                 :       5008 :     rtl_string2UString( &ustrTempPath, pValue, strlen( pValue ), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
      66                 :            :     OSL_ASSERT(ustrTempPath != NULL);
      67                 :       5008 :     error = osl_getFileURLFromSystemPath( ustrTempPath, pustrTempDir );
      68                 :       5008 :     rtl_uString_release( ustrTempPath );
      69                 :            : 
      70                 :       5008 :     return error;
      71                 :            : }
      72                 :            : 
      73                 :            : /******************************************************************
      74                 :            :  * Generates a random unique file name. We're using the scheme
      75                 :            :  * from the standard c-lib function mkstemp to generate a more
      76                 :            :  * or less random unique file name
      77                 :            :  *
      78                 :            :  * @param rand_name
      79                 :            :  *        receives the random name
      80                 :            :  ******************************************************************/
      81                 :            : 
      82                 :            : static const char LETTERS[]        = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
      83                 :            : static const int  COUNT_OF_LETTERS = SAL_N_ELEMENTS(LETTERS) - 1;
      84                 :            : 
      85                 :            : #define RAND_NAME_LENGTH 6
      86                 :            : 
      87                 :      43348 : static void osl_gen_random_name_impl_(rtl_uString** rand_name)
      88                 :            : {
      89                 :            :     static uint64_t value;
      90                 :            : 
      91                 :            :     char     buffer[RAND_NAME_LENGTH];
      92                 :            :     struct   timeval tv;
      93                 :            :     uint64_t v;
      94                 :            :     int      i;
      95                 :            : 
      96                 :      43348 :     gettimeofday(&tv, NULL);
      97                 :            : 
      98                 :      43348 :     value += ((uint64_t)tv.tv_usec << 16) ^ tv.tv_sec ^ getpid();
      99                 :            : 
     100                 :      43348 :     v = value;
     101                 :            : 
     102         [ +  + ]:     303436 :     for (i = 0; i < RAND_NAME_LENGTH; i++)
     103                 :            :     {
     104                 :     260088 :         buffer[i] = LETTERS[v % COUNT_OF_LETTERS];
     105                 :     260088 :         v        /= COUNT_OF_LETTERS;
     106                 :            :     }
     107                 :            : 
     108                 :      43348 :     rtl_string2UString(
     109                 :            :             rand_name,
     110                 :            :             buffer,
     111                 :            :             RAND_NAME_LENGTH,
     112                 :            :             RTL_TEXTENCODING_ASCII_US,
     113                 :            :             OSTRING_TO_OUSTRING_CVTFLAGS);
     114                 :            :     OSL_ASSERT(*rand_name != NULL);
     115                 :      43348 : }
     116                 :            : 
     117                 :            : /*****************************************************************
     118                 :            :  * Helper function
     119                 :            :  * Either use the directory provided or the result of
     120                 :            :  * osl_getTempDirUrl and return it as system path and file url
     121                 :            :  ****************************************************************/
     122                 :            : 
     123                 :      43348 : static oslFileError osl_setup_base_directory_impl_(
     124                 :            :     rtl_uString*  pustrDirectoryURL,
     125                 :            :     rtl_uString** ppustr_base_dir)
     126                 :            : {
     127                 :      43348 :     rtl_uString* dir_url = 0;
     128                 :      43348 :     rtl_uString* dir     = 0;
     129                 :      43348 :     oslFileError error   = osl_File_E_None;
     130                 :            : 
     131         [ +  + ]:      43348 :     if (pustrDirectoryURL)
     132                 :      38716 :         rtl_uString_assign(&dir_url, pustrDirectoryURL);
     133                 :            :     else
     134                 :       4632 :         error = osl_getTempDirURL(&dir_url);
     135                 :            : 
     136         [ +  - ]:      43348 :     if (osl_File_E_None == error)
     137                 :            :     {
     138                 :      43348 :         error = osl_getSystemPathFromFileURL_Ex(dir_url, &dir, FURL_DENY_RELATIVE);
     139                 :      43348 :         rtl_uString_release(dir_url);
     140                 :            :     }
     141                 :            : 
     142         [ +  - ]:      43348 :     if (osl_File_E_None == error)
     143                 :            :     {
     144                 :      43348 :         rtl_uString_assign(ppustr_base_dir, dir);
     145                 :      43348 :         rtl_uString_release(dir);
     146                 :            :     }
     147                 :            : 
     148                 :      43348 :     return error;
     149                 :            : }
     150                 :            : 
     151                 :            : /*****************************************************************
     152                 :            :  * osl_setup_createTempFile_impl
     153                 :            :  * validate input parameter, setup variables
     154                 :            :  ****************************************************************/
     155                 :            : 
     156                 :      43348 :  static oslFileError osl_setup_createTempFile_impl_(
     157                 :            :      rtl_uString*   pustrDirectoryURL,
     158                 :            :     oslFileHandle* pHandle,
     159                 :            :     rtl_uString**  ppustrTempFileURL,
     160                 :            :     rtl_uString**  ppustr_base_dir,
     161                 :            :     sal_Bool*      b_delete_on_close)
     162                 :            :  {
     163                 :            :      oslFileError osl_error;
     164                 :            : 
     165                 :            :     OSL_PRECOND(((0 != pHandle) || (0 != ppustrTempFileURL)), "Invalid parameter!");
     166                 :            : 
     167 [ +  + ][ -  + ]:      43348 :     if ((0 == pHandle) && (0 == ppustrTempFileURL))
     168                 :            :     {
     169                 :          0 :         osl_error = osl_File_E_INVAL;
     170                 :            :     }
     171                 :            :     else
     172                 :            :     {
     173                 :      43348 :         osl_error = osl_setup_base_directory_impl_(
     174                 :            :             pustrDirectoryURL, ppustr_base_dir);
     175                 :            : 
     176                 :      43348 :         *b_delete_on_close = (0 == ppustrTempFileURL);
     177                 :            :     }
     178                 :            : 
     179                 :      43348 :     return osl_error;
     180                 :            :  }
     181                 :            : 
     182                 :            : /*****************************************************************
     183                 :            :  * Create a unique file in the specified directory and return
     184                 :            :  * it's name
     185                 :            :  ****************************************************************/
     186                 :            : 
     187                 :      43348 : static oslFileError osl_create_temp_file_impl_(
     188                 :            :     const rtl_uString* pustr_base_directory,
     189                 :            :     oslFileHandle* file_handle,
     190                 :            :     rtl_uString** ppustr_temp_file_name)
     191                 :            : {
     192                 :      43348 :     rtl_uString*        rand_name        = 0;
     193                 :      43348 :     sal_uInt32          len_base_dir     = 0;
     194                 :      43348 :     rtl_uString*        tmp_file_path    = 0;
     195                 :      43348 :     rtl_uString*        tmp_file_url     = 0;
     196                 :      43348 :     sal_Int32           capacity         = 0;
     197                 :      43348 :     oslFileError        osl_error        = osl_File_E_None;
     198                 :            :     sal_Int32           offset_file_name;
     199                 :            :     const sal_Unicode*  puchr;
     200                 :            : 
     201                 :            :     OSL_PRECOND(pustr_base_directory, "Invalid Parameter");
     202                 :            :     OSL_PRECOND(file_handle, "Invalid Parameter");
     203                 :            :     OSL_PRECOND(ppustr_temp_file_name, "Invalid Parameter");
     204                 :            : 
     205                 :      43348 :     len_base_dir = rtl_uString_getLength(pustr_base_directory);
     206                 :            : 
     207                 :      43348 :     rtl_uStringbuffer_newFromStr_WithLength(
     208                 :            :         &tmp_file_path,
     209                 :      43348 :         rtl_uString_getStr((rtl_uString*)pustr_base_directory),
     210                 :            :         len_base_dir);
     211                 :            : 
     212                 :      43348 :     rtl_uStringbuffer_ensureCapacity(
     213                 :            :         &tmp_file_path,
     214                 :            :         &capacity,
     215                 :      43348 :         (len_base_dir + 1 + RAND_NAME_LENGTH));
     216                 :            : 
     217                 :      43348 :     offset_file_name = len_base_dir;
     218                 :            : 
     219                 :      43348 :     puchr = rtl_uString_getStr(tmp_file_path);
     220                 :            : 
     221                 :            :     /* ensure that the last character is a '/' */
     222                 :            : 
     223         [ +  + ]:      43348 :     if ((sal_Unicode)'/' != puchr[len_base_dir - 1])
     224                 :            :     {
     225                 :      43228 :         rtl_uStringbuffer_insert_ascii(
     226                 :            :             &tmp_file_path,
     227                 :            :             &capacity,
     228                 :            :             len_base_dir,
     229                 :            :             "/",
     230                 :            :             1);
     231                 :            : 
     232                 :      43228 :         offset_file_name++;
     233                 :            :     }
     234                 :            : 
     235                 :            :     while(1) /* try until success */
     236                 :            :     {
     237                 :      43348 :         osl_gen_random_name_impl_(&rand_name);
     238                 :            : 
     239                 :      86696 :         rtl_uStringbuffer_insert(
     240                 :            :             &tmp_file_path,
     241                 :            :             &capacity,
     242                 :            :             offset_file_name,
     243                 :      43348 :             rtl_uString_getStr(rand_name),
     244                 :            :             rtl_uString_getLength(rand_name));
     245                 :            : 
     246                 :      43348 :         osl_error = osl_getFileURLFromSystemPath(
     247                 :            :             tmp_file_path, &tmp_file_url);
     248                 :            : 
     249         [ +  - ]:      43348 :         if (osl_File_E_None == osl_error)
     250                 :            :         {
     251                 :            :             /* RW permission for the user only! */
     252                 :      43348 :             mode_t old_mode = umask(077);
     253                 :            : 
     254                 :      43348 :             osl_error = osl_openFile(
     255                 :            :                 tmp_file_url,
     256                 :            :                 file_handle,
     257                 :            :                 osl_File_OpenFlag_Read |
     258                 :            :                 osl_File_OpenFlag_Write |
     259                 :            :                 osl_File_OpenFlag_Create);
     260                 :            : 
     261                 :      43348 :             umask(old_mode);
     262                 :            :         }
     263                 :            : 
     264                 :            :         /* in case of error osl_File_E_EXIST we simply try again else we give up */
     265                 :            : 
     266 [ -  + ][ #  # ]:      43348 :         if ((osl_File_E_None == osl_error) || (osl_error != osl_File_E_EXIST))
     267                 :            :         {
     268         [ +  - ]:      43348 :             if (rand_name)
     269                 :      43348 :                 rtl_uString_release(rand_name);
     270                 :            : 
     271         [ +  - ]:      43348 :             if (tmp_file_url)
     272                 :      43348 :                 rtl_uString_release(tmp_file_url);
     273                 :            : 
     274                 :      43348 :             break;
     275                 :            :         }
     276                 :          0 :     } /* while(1) */
     277                 :            : 
     278         [ +  - ]:      43348 :     if (osl_File_E_None == osl_error)
     279                 :      43348 :         rtl_uString_assign(ppustr_temp_file_name, tmp_file_path);
     280                 :            : 
     281         [ +  - ]:      43348 :     if (tmp_file_path)
     282                 :      43348 :         rtl_uString_release(tmp_file_path);
     283                 :            : 
     284                 :      43348 :     return osl_error;
     285                 :            : }
     286                 :            : 
     287                 :            : /*****************************************************************
     288                 :            :  * osl_createTempFile
     289                 :            :  *****************************************************************/
     290                 :            : 
     291                 :      43348 : oslFileError SAL_CALL osl_createTempFile(
     292                 :            :     rtl_uString*   pustrDirectoryURL,
     293                 :            :     oslFileHandle* pHandle,
     294                 :            :     rtl_uString**  ppustrTempFileURL)
     295                 :            : {
     296                 :      43348 :     rtl_uString*  base_directory     = 0;
     297                 :      43348 :     rtl_uString*  temp_file_name     = 0;
     298                 :            :     oslFileHandle temp_file_handle;
     299                 :            :     sal_Bool      b_delete_on_close;
     300                 :            :     oslFileError  osl_error;
     301                 :            : 
     302                 :      43348 :     osl_error = osl_setup_createTempFile_impl_(
     303                 :            :         pustrDirectoryURL,
     304                 :            :         pHandle,
     305                 :            :         ppustrTempFileURL,
     306                 :            :         &base_directory,
     307                 :            :         &b_delete_on_close);
     308                 :            : 
     309         [ -  + ]:      43348 :     if (osl_File_E_None != osl_error)
     310                 :          0 :         return osl_error;
     311                 :            : 
     312                 :      43348 :     osl_error = osl_create_temp_file_impl_(
     313                 :            :         base_directory, &temp_file_handle, &temp_file_name);
     314                 :            : 
     315         [ +  - ]:      43348 :     if (osl_File_E_None == osl_error)
     316                 :            :     {
     317                 :      43348 :         rtl_uString* temp_file_url = 0;
     318                 :            : 
     319                 :            :         /* assuming this works */
     320                 :      43348 :         osl_getFileURLFromSystemPath(temp_file_name, &temp_file_url);
     321                 :            : 
     322         [ -  + ]:      43348 :         if (b_delete_on_close)
     323                 :            :         {
     324                 :          0 :             osl_error = osl_removeFile(temp_file_url);
     325                 :            : 
     326         [ #  # ]:          0 :             if (osl_File_E_None == osl_error)
     327                 :          0 :                 *pHandle = temp_file_handle;
     328                 :            :             else
     329                 :          0 :                 osl_closeFile(temp_file_handle);
     330                 :            :         }
     331                 :            :         else
     332                 :            :         {
     333         [ +  + ]:      43348 :             if (pHandle)
     334                 :      38476 :                 *pHandle = temp_file_handle;
     335                 :            :             else
     336                 :       4872 :                 osl_closeFile(temp_file_handle);
     337                 :            : 
     338                 :      43348 :             rtl_uString_assign(ppustrTempFileURL, temp_file_url);
     339                 :            :         }
     340                 :            : 
     341         [ +  - ]:      43348 :         if (temp_file_url)
     342                 :      43348 :             rtl_uString_release(temp_file_url);
     343                 :            : 
     344         [ +  - ]:      43348 :         if (temp_file_name)
     345                 :      43348 :             rtl_uString_release(temp_file_name);
     346                 :            :     }
     347                 :            : 
     348         [ +  - ]:      43348 :     if (base_directory)
     349                 :      43348 :         rtl_uString_release(base_directory);
     350                 :            : 
     351                 :      43348 :     return osl_error;
     352                 :            : }
     353                 :            : 
     354                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10