GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 81 / 0 / 81
Functions: 100.0% 1 / 0 / 1
Branches: 100.0% 105 / 0 / 105

fx_directory_default_set.c
Line Branch Exec Source
1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 * Copyright (c) 2026-present Eclipse ThreadX contributors
4 *
5 * This program and the accompanying materials are made available under the
6 * terms of the MIT License which is available at
7 * https://opensource.org/licenses/MIT.
8 *
9 * SPDX-License-Identifier: MIT
10 **************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** FileX Component */
17 /** */
18 /** Directory */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define FX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "fx_api.h"
29 #include "fx_system.h"
30 #include "fx_file.h"
31 #include "fx_utility.h"
32 #include "fx_directory.h"
33
34 #ifndef FX_NO_LOCAL_PATH
35 FX_LOCAL_PATH_SETUP
36 #endif
37
38
39 /**************************************************************************/
40 /* */
41 /* FUNCTION RELEASE */
42 /* */
43 /* _fx_directory_default_set PORTABLE C */
44 /* 6.1 */
45 /* AUTHOR */
46 /* */
47 /* William E. Lamie, Microsoft Corporation */
48 /* */
49 /* DESCRIPTION */
50 /* */
51 /* This function sets the default directory of the media to the path */
52 /* specified by the caller. If this path is not found, an error code */
53 /* is returned. */
54 /* */
55 /* INPUT */
56 /* */
57 /* media_ptr Media control block pointer */
58 /* new_path_name New path to set current */
59 /* working directory to */
60 /* */
61 /* OUTPUT */
62 /* */
63 /* return status */
64 /* */
65 /* CALLS */
66 /* */
67 /* _fx_directory_search Search for the directory name */
68 /* in the directory structure */
69 /* _fx_utility_absolute_path_get Get absolute path */
70 /* */
71 /* CALLED BY */
72 /* */
73 /* Application Code */
74 /* */
75 /**************************************************************************/
76 2461 UINT _fx_directory_default_set(FX_MEDIA *media_ptr, CHAR *new_path_name)
77 {
78
79 UINT status;
80 FX_DIR_ENTRY dir_entry;
81 CHAR *path_string_ptr;
82 UINT path_string_capacity;
83 FX_PATH *path_ptr;
84 UINT i;
85
86
87
88 #ifndef FX_MEDIA_STATISTICS_DISABLE
89
90 /* Increment the number of times this service has been called. */
91 2461 media_ptr -> fx_media_directory_default_sets++;
92 #endif
93
94 /* Setup pointer to media name buffer. */
95 2461 dir_entry.fx_dir_entry_name = media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
96
97 /* Clear the short name string. */
98 2461 dir_entry.fx_dir_entry_short_name[0] = 0;
99
100 /* Clear the long name string. */
101 2461 dir_entry.fx_dir_entry_name[0] = (CHAR)0;
102
103 /* Check the media to make sure it is open. */
104
2/2
✓ Branch 2 → 3 taken 9 times.
✓ Branch 2 → 4 taken 2452 times.
2461 if (media_ptr -> fx_media_id != FX_MEDIA_ID)
105 {
106
107 /* Return the media not opened error. */
108 9 return(FX_MEDIA_NOT_OPEN);
109 }
110
111 /* If trace is enabled, insert this event into the trace buffer. */
112 FX_TRACE_IN_LINE_INSERT(FX_TRACE_DIRECTORY_DEFAULT_SET, media_ptr, new_path_name, 0, 0, FX_TRACE_DIRECTORY_EVENTS, 0, 0)
113
114 /* Protect against other threads accessing the media. */
115 1050 FX_PROTECT
116
117 /* Setup the path string pointer to the start of the current path. */
118 2452 path_string_ptr = &(media_ptr -> fx_media_default_path.fx_path_string[0]);
119
120
121 /* Look for a root directory selection. */
122
13/13
✓ Branch 4 → 5 taken 1398 times.
✓ Branch 4 → 8 taken 4 times.
✓ Branch 5 → 6 taken 2345 times.
✓ Branch 5 → 7 taken 98 times.
✓ Branch 5 → 9 taken 5 times.
✓ Branch 6 → 7 taken 1492 times.
✓ Branch 6 → 8 taken 25 times.
✓ Branch 6 → 9 taken 828 times.
✓ Branch 7 → 8 taken 265 times.
✓ Branch 7 → 9 taken 450 times.
✓ Branch 7 → 10 taken 875 times.
✓ Branch 8 → 9 taken 50 times.
✓ Branch 8 → 10 taken 120 times.
2452 if ((!new_path_name) || (((new_path_name[0] == '\\') || (new_path_name[0] == '/')) && (new_path_name[1] == (CHAR)0)))
123 {
124
125 /* Set the media current working directory to the root. */
126 179 media_ptr -> fx_media_default_path.fx_path_directory.fx_dir_entry_name[0] = (CHAR) 0;
127 179 media_ptr -> fx_media_default_path.fx_path_string[0] = (CHAR) 0;
128 179 media_ptr -> fx_media_default_path.fx_path_string[FX_MAXIMUM_PATH - 2] = (CHAR) 0;
129 }
130 else
131 {
132
133 /* Search the system for the supplied path and directory name. */
134 2273 status = _fx_directory_search(media_ptr, new_path_name, &dir_entry, FX_NULL, FX_NULL);
135
136 /* Determine if the search failed or if the entry found is not a
137 directory. */
138
6/6
✓ Branch 10 → 11 taken 1274 times.
✓ Branch 10 → 12 taken 4 times.
✓ Branch 11 → 12 taken 994 times.
✓ Branch 11 → 13 taken 1275 times.
✓ Branch 12 → 13 taken 5 times.
✓ Branch 12 → 15 taken 985 times.
2273 if ((status != FX_SUCCESS) || (!(dir_entry.fx_dir_entry_attributes & FX_DIRECTORY)))
139 {
140
141 /* Release media protection. */
142 10 FX_UNPROTECT
143
144 /* Invalid Path - Return the error code. */
145 18 return(FX_INVALID_PATH);
146 }
147
148 /* Now update the current path string. */
149
150 /* Setup the path string's capacity. */
151 2255 path_string_capacity = FX_MAXIMUM_PATH - 1;
152
153 /* Determine if the new path is relative from the current path. */
154
8/8
✓ Branch 13 → 14 taken 1262 times.
✓ Branch 13 → 29 taken 8 times.
✓ Branch 14 → 15 taken 820 times.
✓ Branch 14 → 29 taken 442 times.
✓ Branch 15 → 16 taken 975 times.
✓ Branch 15 → 35 taken 10 times.
✓ Branch 16 → 17 taken 865 times.
✓ Branch 16 → 35 taken 110 times.
2255 if ((new_path_name[0] != '\\') && (new_path_name[0] != '/'))
155 {
156
157 /* Yes, a relative path was found. */
158
159 /* First check for a local path pointer stored in the thread control block.
160 This is only available in ThreadX Version 4 and above. */
161 #ifndef FX_NO_LOCAL_PATH
162
2/2
✓ Branch 17 → 18 taken 5 times.
✓ Branch 17 → 19 taken 860 times.
865 if (_tx_thread_current_ptr -> tx_thread_filex_ptr)
163 {
164
165 CHAR *saved_name_ptr;
166
167 /* First, save the name pointer of the default path. */
168 5 saved_name_ptr = media_ptr -> fx_media_default_path.fx_path_directory.fx_dir_entry_name;
169
170 /* Setup the default path pointer to the local path. */
171 5 path_ptr = (FX_PATH *)_tx_thread_current_ptr -> tx_thread_filex_ptr;
172
173 /* Copy the local path to the default path. */
174 5 media_ptr -> fx_media_default_path = *path_ptr;
175
176 /* Restore the name pointer of the default path. */
177 5 media_ptr -> fx_media_default_path.fx_path_directory.fx_dir_entry_name = saved_name_ptr;
178
179 /* Set the path pointer to the default pointer. */
180 5 path_ptr = &media_ptr -> fx_media_default_path;
181 }
182 else
183 {
184
185 /* Setup the default path to the global media path. */
186 860 path_ptr = &media_ptr -> fx_media_default_path;
187 }
188 #else
189
190 /* Setup the default path to the global media path. */
191 820 path_ptr = &media_ptr -> fx_media_default_path;
192 #endif
193
194 /* First, check the current path for string overflow. If this is set,
195 don't attempt to update the current path with relative information.
196 The path won't be valid again until a complete path is given. */
197
4/4
✓ Branch 15 → 16 taken 212 times.
✓ Branch 15 → 22 taken 608 times.
✓ Branch 20 → 21 taken 285 times.
✓ Branch 20 → 28 taken 580 times.
1685 if (path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] == '*')
198 {
199
200 /* Yes, don't update the string, just finish the path set processing. */
201
202 /* Determine if we are at the root directory. */
203
4/4
✓ Branch 16 → 17 taken 16 times.
✓ Branch 16 → 18 taken 196 times.
✓ Branch 21 → 22 taken 20 times.
✓ Branch 21 → 23 taken 265 times.
497 if (!dir_entry.fx_dir_entry_cluster)
204 {
205 /* Set the current directory back to the root directory. */
206 36 path_ptr -> fx_path_directory.fx_dir_entry_name[0] = (CHAR) 0;
207
208 /* Set name to NULL. */
209 36 dir_entry.fx_dir_entry_name[0] = (CHAR) 0;
210
211 /* Clear the current path string. */
212 36 path_ptr -> fx_path_string[0] = (CHAR)0;
213
214 /* Clear the overflow flag in the current path string... just in
215 case! */
216 36 path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] = (CHAR)0;
217 }
218
219 /* Copy the new directory entry into the media control block. */
220 497 path_ptr -> fx_path_directory = dir_entry;
221
222 /* Copy the name into the path name buffer. */
223
4/4
✓ Branch 20 → 19 taken 2540 times.
✓ Branch 20 → 21 taken 212 times.
✓ Branch 25 → 24 taken 3635 times.
✓ Branch 25 → 26 taken 285 times.
6672 for (i = 0; dir_entry.fx_dir_entry_name[i]; i++)
224 {
225 6175 path_ptr -> fx_path_name_buffer[i] = dir_entry.fx_dir_entry_name[i];
226 }
227
228 /* Reassign the pointer. */
229 497 path_ptr -> fx_path_directory.fx_dir_entry_name = path_ptr -> fx_path_name_buffer;
230
231 /* Release media protection. */
232 285 FX_UNPROTECT
233
234 /* Default directory set is complete, return status. */
235 497 return(FX_SUCCESS);
236 }
237
238 /* Move the current path starting pointer to the end of the current
239 path string. */
240
8/8
✓ Branch 24 → 25 taken 41786 times.
✓ Branch 24 → 26 taken 4 times.
✓ Branch 25 → 23 taken 41182 times.
✓ Branch 25 → 26 taken 604 times.
✓ Branch 30 → 31 taken 58195 times.
✓ Branch 30 → 32 taken 5 times.
✓ Branch 31 → 29 taken 57620 times.
✓ Branch 31 → 32 taken 575 times.
99990 while ((path_string_capacity) && (*path_string_ptr != FX_NULL))
241 {
242 98802 path_string_ptr++;
243 98802 path_string_capacity--;
244 }
245
246 /* If room, place the \ character in the path string. */
247
4/4
✓ Branch 26 → 27 taken 604 times.
✓ Branch 26 → 28 taken 4 times.
✓ Branch 32 → 33 taken 575 times.
✓ Branch 32 → 34 taken 5 times.
1188 if (path_string_capacity)
248 {
249
250 /* There is room, place the directory marker in the string. */
251 1179 *path_string_ptr++ = '\\';
252 1179 path_string_capacity--;
253 }
254 }
255 else
256 {
257
258 /* Setup the default path pointer. */
259
260 /* First check for a local path pointer stored in the thread control block.
261 This is only available in ThreadX Version 4 and above. */
262 #ifndef FX_NO_LOCAL_PATH
263
2/2
✓ Branch 35 → 36 taken 5 times.
✓ Branch 35 → 37 taken 115 times.
120 if (_tx_thread_current_ptr -> tx_thread_filex_ptr)
264 {
265
266 CHAR *saved_name_ptr;
267
268 /* First, save the name pointer of the default path. */
269 5 saved_name_ptr = media_ptr -> fx_media_default_path.fx_path_directory.fx_dir_entry_name;
270
271 /* Setup the default path pointer to the local path. */
272 5 path_ptr = (FX_PATH *)_tx_thread_current_ptr -> tx_thread_filex_ptr;
273
274 /* Copy the local path to the default path. */
275 5 media_ptr -> fx_media_default_path = *path_ptr;
276
277 /* Restore the name pointer of the default path. */
278 5 media_ptr -> fx_media_default_path.fx_path_directory.fx_dir_entry_name = saved_name_ptr;
279
280 /* Set the path pointer to the default pointer. */
281 5 path_ptr = &media_ptr -> fx_media_default_path;
282 }
283 else
284 {
285
286 /* Setup the default path to the global media path. */
287 115 path_ptr = &media_ptr -> fx_media_default_path;
288 }
289 #else
290
291 /* Setup the default path to the global media path. */
292 450 path_ptr = &media_ptr -> fx_media_default_path;
293 #endif
294
295 /* Complete path name given. Check to see if we need to clear an
296 overflow character from a previous current path string update. */
297
4/4
✓ Branch 29 → 30 taken 8 times.
✓ Branch 29 → 31 taken 442 times.
✓ Branch 38 → 39 taken 10 times.
✓ Branch 38 → 40 taken 110 times.
570 if (path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] == '*')
298 {
299 18 path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] = (CHAR)0;
300 }
301 }
302
303 /* Copy what we can into the current path. */
304
4/4
✓ Branch 44 → 32 taken 14228 times.
✓ Branch 44 → 45 taken 1026 times.
✓ Branch 53 → 41 taken 15060 times.
✓ Branch 53 → 54 taken 655 times.
30969 while (*new_path_name)
305 {
306
307 /* Determine if there is a ".." character sequence that specifies the
308 previous path. */
309
8/8
✓ Branch 32 → 33 taken 20 times.
✓ Branch 32 → 40 taken 14208 times.
✓ Branch 33 → 34 taken 16 times.
✓ Branch 33 → 40 taken 4 times.
✓ Branch 41 → 42 taken 25 times.
✓ Branch 41 → 49 taken 15035 times.
✓ Branch 42 → 43 taken 20 times.
✓ Branch 42 → 49 taken 5 times.
29288 if ((*new_path_name == '.') && (*(new_path_name + 1) == '.'))
310 {
311
312 /* Yes, a backward path is found. The current path pointer
313 must be moved back to just after the previous \ character. */
314
315 /* Skip the current \0 that is at the end of the current path. */
316 36 path_string_capacity = path_string_capacity + 2;
317 36 path_string_ptr = path_string_ptr - 2;
318
319
4/4
✓ Branch 38 → 35 taken 292 times.
✓ Branch 38 → 39 taken 8 times.
✓ Branch 47 → 44 taken 365 times.
✓ Branch 47 → 48 taken 10 times.
675 while (path_string_capacity <= (FX_MAXIMUM_PATH - 1))
320 {
321
322 /* Move the current path pointer backwards until
323 a \ character is found. */
324
325
8/8
✓ Branch 35 → 36 taken 288 times.
✓ Branch 35 → 39 taken 4 times.
✓ Branch 36 → 37 taken 284 times.
✓ Branch 36 → 39 taken 4 times.
✓ Branch 44 → 45 taken 360 times.
✓ Branch 44 → 48 taken 5 times.
✓ Branch 45 → 46 taken 355 times.
✓ Branch 45 → 48 taken 5 times.
657 if ((*path_string_ptr == '\\') || (*path_string_ptr == '/'))
326 {
327
328 /* Yes, we have successfully backed up one directory. */
329 break;
330 }
331
332 /* Backup another character. */
333 639 path_string_capacity++;
334 639 path_string_ptr--;
335 }
336
337 /* Adjust the new directory pointer past the .. characters */
338 36 new_path_name = new_path_name + 2;
339 }
340 else
341 {
342
343 /* Normal characters that need to be copied into the current path. */
344
345
4/4
✓ Branch 40 → 41 taken 14180 times.
✓ Branch 40 → 42 taken 32 times.
✓ Branch 49 → 50 taken 14995 times.
✓ Branch 49 → 51 taken 45 times.
29252 if (path_string_capacity)
346 {
347
348 /* Copy character from the new path into the current path string. */
349 29175 *path_string_ptr++ = *new_path_name++;
350
351 29175 path_string_capacity--;
352 }
353 else
354 {
355
356 /* No more room in the current path string! */
357 77 break;
358 }
359 }
360 }
361
362 /* Determine if there is still room in the current path string. */
363
4/4
✓ Branch 45 → 46 taken 1014 times.
✓ Branch 45 → 47 taken 44 times.
✓ Branch 54 → 55 taken 645 times.
✓ Branch 54 → 56 taken 55 times.
1758 if (path_string_capacity)
364 {
365
366 /* Yes, there is still room, place a NULL character at the
367 end of the path. */
368 1659 *path_string_ptr = (CHAR)FX_NULL;
369 }
370 else
371 {
372
373 /* No more room. Determine if the entire path was successfully
374 copied into the current path. */
375
4/4
✓ Branch 47 → 48 taken 32 times.
✓ Branch 47 → 49 taken 12 times.
✓ Branch 56 → 57 taken 45 times.
✓ Branch 56 → 58 taken 10 times.
99 if (*new_path_name)
376 {
377
378 /* No, we couldn't fit the entire path. Place a "*" character
379 at the end to indicate that we had overflow. Note that
380 the path is kept just the the directory default get call, so
381 the new default path is valid. */
382 77 path_ptr -> fx_path_string[FX_MAXIMUM_PATH - 2] = '*';
383 }
384 }
385
386 /* Determine if we are at the root directory. */
387
4/4
✓ Branch 49 → 50 taken 8 times.
✓ Branch 49 → 51 taken 1050 times.
✓ Branch 58 → 59 taken 10 times.
✓ Branch 58 → 60 taken 690 times.
1758 if (!dir_entry.fx_dir_entry_cluster)
388 {
389
390 /* Set the current directory back to the root directory. */
391 18 dir_entry.fx_dir_entry_name[0] = (CHAR)0;
392 18 path_ptr -> fx_path_name_buffer[0] = (CHAR)0;
393 }
394
395 /* Copy the new directory entry into the media control block. */
396 1758 path_ptr -> fx_path_directory = dir_entry;
397
398 /* Copy the name. */
399
4/4
✓ Branch 53 → 52 taken 12374 times.
✓ Branch 53 → 54 taken 1058 times.
✓ Branch 62 → 61 taken 13915 times.
✓ Branch 62 → 63 taken 700 times.
28047 for (i = 0; dir_entry.fx_dir_entry_name[i]; i++)
400 {
401 26289 path_ptr -> fx_path_name_buffer[i] = dir_entry.fx_dir_entry_name[i];
402 }
403
404 /* Reassign the pointer. */
405 1758 path_ptr -> fx_path_directory.fx_dir_entry_name = path_ptr -> fx_path_name_buffer;
406 }
407
408 /* Release media protection. */
409 755 FX_UNPROTECT
410
411 /* Default directory set is complete, return status. */
412 1937 return(FX_SUCCESS);
413 }
414
415