File: | home/maarten/src/libreoffice/core/sal/osl/unx/tempfile.cxx |
Warning: | line 329, column 9 Branch condition evaluates to a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
8 | * | |||
9 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | |||
12 | * contributor license agreements. See the NOTICE file distributed | |||
13 | * with this work for additional information regarding copyright | |||
14 | * ownership. The ASF licenses this file to you under the Apache | |||
15 | * License, Version 2.0 (the "License"); you may not use this file | |||
16 | * except in compliance with the License. You may obtain a copy of | |||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | |||
18 | */ | |||
19 | ||||
20 | #include <stdio.h> | |||
21 | #include <stdlib.h> | |||
22 | #include <sys/types.h> | |||
23 | #include <sys/stat.h> | |||
24 | #include <sys/time.h> | |||
25 | #include "system.hxx" | |||
26 | #include <osl/file.h> | |||
27 | #include <osl/thread.h> | |||
28 | #include <rtl/ustrbuf.h> | |||
29 | #include <osl/diagnose.h> | |||
30 | #include <sal/macros.h> | |||
31 | ||||
32 | #include "file_url.hxx" | |||
33 | #include "file_impl.hxx" | |||
34 | ||||
35 | #include <cassert> | |||
36 | ||||
37 | oslFileError SAL_CALL osl_getTempDirURL( rtl_uString** pustrTempDir ) | |||
38 | { | |||
39 | oslFileError error; | |||
40 | /* described in environ(7) */ | |||
41 | const char *pValue = getenv( "TMPDIR" ); | |||
42 | rtl_uString *ustrTempPath = nullptr; | |||
43 | ||||
44 | if ( !pValue ) | |||
45 | pValue = getenv( "TEMP" ); | |||
46 | ||||
47 | if ( !pValue ) | |||
48 | pValue = getenv( "TMP" ); | |||
49 | ||||
50 | if ( !pValue ) | |||
51 | pValue = "/tmp"; | |||
52 | ||||
53 | rtl_string2UString( &ustrTempPath, pValue, strlen( pValue ), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300 )) ); | |||
54 | assert(ustrTempPath)(static_cast <bool> (ustrTempPath) ? void (0) : __assert_fail ("ustrTempPath", "/home/maarten/src/libreoffice/core/sal/osl/unx/tempfile.cxx" , 54, __extension__ __PRETTY_FUNCTION__)); | |||
55 | error = osl_getFileURLFromSystemPath( ustrTempPath, pustrTempDir ); | |||
56 | rtl_uString_release( ustrTempPath ); | |||
57 | ||||
58 | return error; | |||
59 | } | |||
60 | ||||
61 | /****************************************************************** | |||
62 | * Generates a random unique file name. We're using the scheme | |||
63 | * from the standard c-lib function mkstemp to generate a more | |||
64 | * or less random unique file name | |||
65 | * | |||
66 | * @param rand_name | |||
67 | * receives the random name | |||
68 | ******************************************************************/ | |||
69 | ||||
70 | const char LETTERS[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; | |||
71 | const int COUNT_OF_LETTERS = SAL_N_ELEMENTS(LETTERS)(sizeof(sal_n_array_size(LETTERS))) - 1; | |||
72 | ||||
73 | #define RAND_NAME_LENGTH6 6 | |||
74 | ||||
75 | static void osl_gen_random_name_impl_(rtl_uString** rand_name) | |||
76 | { | |||
77 | static uint64_t value; | |||
78 | ||||
79 | char buffer[RAND_NAME_LENGTH6]; | |||
80 | struct timeval tv; | |||
81 | uint64_t v; | |||
82 | int i; | |||
83 | ||||
84 | gettimeofday(&tv, nullptr); | |||
85 | ||||
86 | value += (static_cast<uint64_t>(tv.tv_usec) << 16) ^ tv.tv_sec ^ getpid(); | |||
87 | ||||
88 | v = value; | |||
89 | ||||
90 | for (i = 0; i < RAND_NAME_LENGTH6; i++) | |||
91 | { | |||
92 | buffer[i] = LETTERS[v % COUNT_OF_LETTERS]; | |||
93 | v /= COUNT_OF_LETTERS; | |||
94 | } | |||
95 | ||||
96 | rtl_string2UString( | |||
97 | rand_name, | |||
98 | buffer, | |||
99 | RAND_NAME_LENGTH6, | |||
100 | RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11)), | |||
101 | OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300 ))); | |||
102 | ||||
103 | assert(*rand_name)(static_cast <bool> (*rand_name) ? void (0) : __assert_fail ("*rand_name", "/home/maarten/src/libreoffice/core/sal/osl/unx/tempfile.cxx" , 103, __extension__ __PRETTY_FUNCTION__)); | |||
104 | } | |||
105 | ||||
106 | /***************************************************************** | |||
107 | * Helper function | |||
108 | * Either use the directory provided or the result of | |||
109 | * osl_getTempDirUrl and return it as system path and file url | |||
110 | ****************************************************************/ | |||
111 | ||||
112 | static oslFileError osl_setup_base_directory_impl_( | |||
113 | rtl_uString* pustrDirectoryURL, | |||
114 | rtl_uString** ppustr_base_dir) | |||
115 | { | |||
116 | rtl_uString* dir_url = nullptr; | |||
117 | rtl_uString* dir = nullptr; | |||
118 | oslFileError error = osl_File_E_None; | |||
119 | ||||
120 | if (pustrDirectoryURL) | |||
121 | rtl_uString_assign(&dir_url, pustrDirectoryURL); | |||
122 | else | |||
123 | error = osl_getTempDirURL(&dir_url); | |||
124 | ||||
125 | if (error == osl_File_E_None) | |||
126 | { | |||
127 | error = osl_getSystemPathFromFileURL_Ex(dir_url, &dir); | |||
128 | rtl_uString_release(dir_url); | |||
129 | } | |||
130 | ||||
131 | if (error == osl_File_E_None) | |||
132 | { | |||
133 | rtl_uString_assign(ppustr_base_dir, dir); | |||
134 | rtl_uString_release(dir); | |||
135 | } | |||
136 | ||||
137 | return error; | |||
138 | } | |||
139 | ||||
140 | /***************************************************************** | |||
141 | * osl_setup_createTempFile_impl | |||
142 | * validate input parameter, setup variables | |||
143 | ****************************************************************/ | |||
144 | ||||
145 | static oslFileError osl_setup_createTempFile_impl_( | |||
146 | rtl_uString* pustrDirectoryURL, | |||
147 | oslFileHandle* pHandle, | |||
148 | rtl_uString** ppustrTempFileURL, | |||
149 | rtl_uString** ppustr_base_dir, | |||
150 | bool* b_delete_on_close) | |||
151 | { | |||
152 | oslFileError osl_error; | |||
153 | ||||
154 | OSL_PRECOND(((nullptr != pHandle) || (nullptr != ppustrTempFileURL)), "Invalid parameter!")do { if (true && (!(((nullptr != pHandle) || (nullptr != ppustrTempFileURL))))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/tempfile.cxx" ":" "154" ": "), "%s", "Invalid parameter!"); } } while (false ); | |||
155 | ||||
156 | if ((pHandle == nullptr) && (ppustrTempFileURL == nullptr)) | |||
157 | { | |||
158 | osl_error = osl_File_E_INVAL; | |||
159 | } | |||
160 | else | |||
161 | { | |||
162 | osl_error = osl_setup_base_directory_impl_( | |||
163 | pustrDirectoryURL, ppustr_base_dir); | |||
164 | ||||
165 | *b_delete_on_close = (ppustrTempFileURL == nullptr); | |||
166 | } | |||
167 | ||||
168 | return osl_error; | |||
169 | } | |||
170 | ||||
171 | /***************************************************************** | |||
172 | * Create a unique file in the specified directory and return | |||
173 | * its name | |||
174 | ****************************************************************/ | |||
175 | ||||
176 | static oslFileError osl_create_temp_file_impl_( | |||
177 | const rtl_uString* pustr_base_directory, | |||
178 | oslFileHandle* file_handle, | |||
179 | rtl_uString** ppustr_temp_file_name) | |||
180 | { | |||
181 | rtl_uString* rand_name = nullptr; | |||
182 | sal_uInt32 len_base_dir = 0; | |||
183 | rtl_uString* tmp_file_path = nullptr; | |||
184 | rtl_uString* tmp_file_url = nullptr; | |||
185 | sal_Int32 capacity = 0; | |||
186 | oslFileError osl_error = osl_File_E_None; | |||
187 | sal_Int32 offset_file_name; | |||
188 | const sal_Unicode* puchr; | |||
189 | ||||
190 | OSL_PRECOND(pustr_base_directory, "Invalid Parameter")do { if (true && (!(pustr_base_directory))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/tempfile.cxx" ":" "190" ": "), "%s", "Invalid Parameter"); } } while (false ); | |||
191 | OSL_PRECOND(file_handle, "Invalid Parameter")do { if (true && (!(file_handle))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/tempfile.cxx" ":" "191" ": "), "%s", "Invalid Parameter"); } } while (false ); | |||
192 | OSL_PRECOND(ppustr_temp_file_name, "Invalid Parameter")do { if (true && (!(ppustr_temp_file_name))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sal/osl/unx/tempfile.cxx" ":" "192" ": "), "%s", "Invalid Parameter"); } } while (false ); | |||
193 | ||||
194 | len_base_dir = rtl_uString_getLength(pustr_base_directory); | |||
195 | ||||
196 | rtl_uString_new_WithLength( | |||
197 | &tmp_file_path, | |||
198 | (len_base_dir + 1 + RAND_NAME_LENGTH6)); | |||
199 | capacity = len_base_dir + 1 + RAND_NAME_LENGTH6; | |||
200 | ||||
201 | rtl_uStringbuffer_insert( | |||
202 | &tmp_file_path, | |||
203 | &capacity, | |||
204 | 0, | |||
205 | rtl_uString_getStr(const_cast<rtl_uString*>(pustr_base_directory)), | |||
206 | len_base_dir); | |||
207 | ||||
208 | offset_file_name = len_base_dir; | |||
209 | ||||
210 | puchr = rtl_uString_getStr(tmp_file_path); | |||
211 | ||||
212 | /* ensure that the last character is a '/' */ | |||
213 | ||||
214 | if (puchr[len_base_dir - 1] != '/') | |||
215 | { | |||
216 | rtl_uStringbuffer_insert_ascii( | |||
217 | &tmp_file_path, | |||
218 | &capacity, | |||
219 | len_base_dir, | |||
220 | "/", | |||
221 | 1); | |||
222 | ||||
223 | offset_file_name++; | |||
224 | } | |||
225 | ||||
226 | while(true) /* try until success */ | |||
227 | { | |||
228 | osl_gen_random_name_impl_(&rand_name); | |||
229 | ||||
230 | rtl_uStringbuffer_insert( | |||
231 | &tmp_file_path, | |||
232 | &capacity, | |||
233 | offset_file_name, | |||
234 | rtl_uString_getStr(rand_name), | |||
235 | rtl_uString_getLength(rand_name)); | |||
236 | ||||
237 | osl_error = osl_getFileURLFromSystemPath( | |||
238 | tmp_file_path, &tmp_file_url); | |||
239 | ||||
240 | if (osl_error == osl_File_E_None) | |||
241 | { | |||
242 | osl_error = openFile( | |||
243 | tmp_file_url, | |||
244 | file_handle, | |||
245 | osl_File_OpenFlag_Read0x00000001L | | |||
246 | osl_File_OpenFlag_Write0x00000002L | | |||
247 | osl_File_OpenFlag_Create0x00000004L, | |||
248 | S_IRUSR0400 | S_IWUSR0200); | |||
249 | } | |||
250 | ||||
251 | /* in case of error osl_File_E_EXIST we simply try again else we give up */ | |||
252 | ||||
253 | if (osl_error != osl_File_E_EXIST) | |||
254 | { | |||
255 | rtl_uString_release(rand_name); | |||
256 | ||||
257 | if (tmp_file_url) | |||
258 | rtl_uString_release(tmp_file_url); | |||
259 | ||||
260 | break; | |||
261 | } | |||
262 | } /* while(1) */ | |||
263 | ||||
264 | if (osl_error
| |||
265 | rtl_uString_assign(ppustr_temp_file_name, tmp_file_path); | |||
266 | ||||
267 | rtl_uString_release(tmp_file_path); | |||
268 | ||||
269 | return osl_error; | |||
270 | } | |||
271 | ||||
272 | oslFileError SAL_CALL osl_createTempFile( | |||
273 | rtl_uString* pustrDirectoryURL, | |||
274 | oslFileHandle* pHandle, | |||
275 | rtl_uString** ppustrTempFileURL) | |||
276 | { | |||
277 | rtl_uString* base_directory = nullptr; | |||
278 | oslFileHandle temp_file_handle; | |||
| ||||
279 | bool b_delete_on_close; | |||
280 | oslFileError osl_error; | |||
281 | ||||
282 | osl_error = osl_setup_createTempFile_impl_( | |||
283 | pustrDirectoryURL, | |||
284 | pHandle, | |||
285 | ppustrTempFileURL, | |||
286 | &base_directory, | |||
287 | &b_delete_on_close); | |||
288 | ||||
289 | if (osl_error
| |||
290 | return osl_error; | |||
291 | ||||
292 | rtl_uString* temp_file_name = nullptr; | |||
293 | osl_error = osl_create_temp_file_impl_( | |||
294 | base_directory, &temp_file_handle, &temp_file_name); | |||
295 | ||||
296 | rtl_uString* temp_file_url = nullptr; | |||
297 | if (osl_error
| |||
298 | { | |||
299 | osl_error = osl_getFileURLFromSystemPath(temp_file_name, &temp_file_url); | |||
300 | rtl_uString_release(temp_file_name); | |||
301 | } | |||
302 | ||||
303 | if (osl_error
| |||
304 | { | |||
305 | if (b_delete_on_close) | |||
306 | { | |||
307 | osl_error = osl_removeFile(temp_file_url); | |||
308 | ||||
309 | if (osl_error == osl_File_E_None) | |||
310 | { | |||
311 | *pHandle = temp_file_handle; | |||
312 | temp_file_handle = nullptr; | |||
313 | } | |||
314 | } | |||
315 | else | |||
316 | { | |||
317 | if (pHandle) | |||
318 | { | |||
319 | *pHandle = temp_file_handle; | |||
320 | temp_file_handle = nullptr; | |||
321 | } | |||
322 | ||||
323 | rtl_uString_assign(ppustrTempFileURL, temp_file_url); | |||
324 | } | |||
325 | ||||
326 | rtl_uString_release(temp_file_url); | |||
327 | } | |||
328 | ||||
329 | if (temp_file_handle) | |||
| ||||
330 | osl_closeFile(temp_file_handle); | |||
331 | ||||
332 | rtl_uString_release(base_directory); | |||
333 | ||||
334 | return osl_error; | |||
335 | } | |||
336 | ||||
337 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |