Quelle tempfile.cxx
Sprache: C
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project .
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice :
*
* Licensed to the Apache Software Foundation ( ASF ) under one or more
* contributor license agreements . See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership . The ASF licenses this file to you under the Apache
* License , Version 2 . 0 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy of
* the License at http : //www.apache.org/licenses/LICENSE-2.0 .
*/
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <osl/file.h>
#include <osl/thread.h>
#include <rtl/ustrbuf.h>
#include <osl/diagnose.h>
#include <sal/macros.h>
#include "file_url.hxx"
#include "file_impl.hxx"
#include <cassert>
oslFileError SAL_CALL osl_getTempDirURL( rtl_uString** pustrTempDir )
{
oslFileError error;
/* described in environ(7) */
const char *pValue = getenv( "TMPDIR" );
rtl_uString *ustrTempPath = nullptr;
if ( !pValue )
pValue = getenv( "TEMP" );
if ( !pValue )
pValue = getenv( "TMP" );
if ( !pValue )
pValue = "/tmp" ;
auto nLen = strlen(pValue);
while (nLen > 1 && pValue[nLen - 1 ] == '/' ) // Allow path consisting of single "/"
--nLen;
rtl_string2UString( &ustrTempPath, pValue, nLen, osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
assert(ustrTempPath);
error = osl_getFileURLFromSystemPath( ustrTempPath, pustrTempDir );
rtl_uString_release( ustrTempPath );
return error;
}
/******************************************************************
* Generates a random unique file name . We ' re using the scheme
* from the standard c - lib function mkstemp to generate a more
* or less random unique file name
*
* @ param rand_name
* receives the random name
******************************************************************/
const char LETTERS[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" ;
const int COUNT_OF_LETTERS = SAL_N_ELEMENTS(LETTERS) - 1 ;
#define RAND_NAME_LENGTH 6
static void osl_gen_random_name_impl_(rtl_uString** rand_name)
{
static uint64_t value;
char buffer[RAND_NAME_LENGTH];
struct timeval tv;
uint64_t v;
int i;
gettimeofday(&tv, nullptr);
value += (static_cast <uint64_t>(tv.tv_usec) << 16 ) ^ tv.tv_sec ^ getpid();
v = value;
for (i = 0 ; i < RAND_NAME_LENGTH; i++)
{
buffer[i] = LETTERS[v % COUNT_OF_LETTERS];
v /= COUNT_OF_LETTERS;
}
rtl_string2UString(
rand_name,
buffer,
RAND_NAME_LENGTH,
RTL_TEXTENCODING_ASCII_US,
OSTRING_TO_OUSTRING_CVTFLAGS);
assert(*rand_name);
}
/*****************************************************************
* Helper function
* Either use the directory provided or the result of
* osl_getTempDirUrl and return it as system path and file url
****************************************************************/
static oslFileError osl_setup_base_directory_impl_(
rtl_uString* pustrDirectoryURL,
rtl_uString** ppustr_base_dir)
{
rtl_uString* dir_url = nullptr;
rtl_uString* dir = nullptr;
oslFileError error = osl_File_E_None;
if (pustrDirectoryURL)
rtl_uString_assign(&dir_url, pustrDirectoryURL);
else
error = osl_getTempDirURL(&dir_url);
if (error == osl_File_E_None)
{
error = getSystemPathFromFileURL_Ex(dir_url, &dir);
rtl_uString_release(dir_url);
}
if (error == osl_File_E_None)
{
rtl_uString_assign(ppustr_base_dir, dir);
rtl_uString_release(dir);
}
return error;
}
/*****************************************************************
* osl_setup_createTempFile_impl
* validate input parameter , setup variables
****************************************************************/
static oslFileError osl_setup_createTempFile_impl_(
rtl_uString* pustrDirectoryURL,
oslFileHandle* pHandle,
rtl_uString** ppustrTempFileURL,
rtl_uString** ppustr_base_dir,
bool * b_delete_on_close)
{
oslFileError osl_error;
OSL_PRECOND(((nullptr != pHandle) || (nullptr != ppustrTempFileURL)), "Invalid parameter!" );
if ((pHandle == nullptr) && (ppustrTempFileURL == nullptr))
{
osl_error = osl_File_E_INVAL;
}
else
{
osl_error = osl_setup_base_directory_impl_(
pustrDirectoryURL, ppustr_base_dir);
*b_delete_on_close = (ppustrTempFileURL == nullptr);
}
return osl_error;
}
/*****************************************************************
* Create a unique file in the specified directory and return
* its name
****************************************************************/
static oslFileError osl_create_temp_file_impl_(
const rtl_uString* pustr_base_directory,
oslFileHandle* file_handle,
rtl_uString** ppustr_temp_file_name)
{
rtl_uString* rand_name = nullptr;
sal_uInt32 len_base_dir = 0 ;
rtl_uString* tmp_file_path = nullptr;
rtl_uString* tmp_file_url = nullptr;
sal_Int32 capacity = 0 ;
oslFileError osl_error = osl_File_E_None;
sal_Int32 offset_file_name;
const sal_Unicode* puchr;
OSL_PRECOND(pustr_base_directory, "Invalid Parameter" );
OSL_PRECOND(file_handle, "Invalid Parameter" );
OSL_PRECOND(ppustr_temp_file_name, "Invalid Parameter" );
len_base_dir = rtl_uString_getLength(pustr_base_directory);
rtl_uString_new_WithLength(
&tmp_file_path,
(len_base_dir + 1 + RAND_NAME_LENGTH));
capacity = len_base_dir + 1 + RAND_NAME_LENGTH;
rtl_uStringbuffer_insert(
&tmp_file_path,
&capacity,
0 ,
rtl_uString_getStr(const_cast <rtl_uString*>(pustr_base_directory)),
len_base_dir);
offset_file_name = len_base_dir;
puchr = rtl_uString_getStr(tmp_file_path);
/* ensure that the last character is a '/' */
if (puchr[len_base_dir - 1 ] != '/' )
{
rtl_uStringbuffer_insert_ascii(
&tmp_file_path,
&capacity,
len_base_dir,
"/" ,
1 );
offset_file_name++;
}
while (true ) /* try until success */
{
osl_gen_random_name_impl_(&rand_name);
rtl_uStringbuffer_insert(
&tmp_file_path,
&capacity,
offset_file_name,
rtl_uString_getStr(rand_name),
rtl_uString_getLength(rand_name));
osl_error = osl_getFileURLFromSystemPath(
tmp_file_path, &tmp_file_url);
if (osl_error == osl_File_E_None)
{
osl_error = openFile(
tmp_file_url,
file_handle,
osl_File_OpenFlag_Read |
osl_File_OpenFlag_Write |
osl_File_OpenFlag_Create,
S_IRUSR | S_IWUSR);
}
/* in case of error osl_File_E_EXIST we simply try again else we give up */
if (osl_error != osl_File_E_EXIST)
{
rtl_uString_release(rand_name);
if (tmp_file_url)
rtl_uString_release(tmp_file_url);
break ;
}
} /* while(1) */
if (osl_error == osl_File_E_None)
rtl_uString_assign(ppustr_temp_file_name, tmp_file_path);
rtl_uString_release(tmp_file_path);
return osl_error;
}
oslFileError SAL_CALL osl_createTempFile(
rtl_uString* pustrDirectoryURL,
oslFileHandle* pHandle,
rtl_uString** ppustrTempFileURL)
{
rtl_uString* base_directory = nullptr;
oslFileHandle temp_file_handle = nullptr;
bool b_delete_on_close;
oslFileError osl_error;
osl_error = osl_setup_createTempFile_impl_(
pustrDirectoryURL,
pHandle,
ppustrTempFileURL,
&base_directory,
&b_delete_on_close);
if (osl_error != osl_File_E_None)
return osl_error;
rtl_uString* temp_file_name = nullptr;
osl_error = osl_create_temp_file_impl_(
base_directory, &temp_file_handle, &temp_file_name);
rtl_uString* temp_file_url = nullptr;
if (osl_error == osl_File_E_None)
{
osl_error = osl_getFileURLFromSystemPath(temp_file_name, &temp_file_url);
rtl_uString_release(temp_file_name);
}
if (osl_error == osl_File_E_None)
{
if (b_delete_on_close)
{
osl_error = osl_removeFile(temp_file_url);
if (osl_error == osl_File_E_None)
{
*pHandle = temp_file_handle;
temp_file_handle = nullptr;
}
}
else
{
if (pHandle)
{
*pHandle = temp_file_handle;
temp_file_handle = nullptr;
}
rtl_uString_assign(ppustrTempFileURL, temp_file_url);
}
rtl_uString_release(temp_file_url);
}
if (temp_file_handle)
osl_closeFile(temp_file_handle);
rtl_uString_release(base_directory);
return osl_error;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 in Prozent C=96 H=90 G=93
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland
2026-10-10
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=1126864
#Domains=1897691