GCC Code Coverage Report


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

fx_file_create.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 /** File */
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_directory.h"
31 #include "fx_file.h"
32 #include "fx_utility.h"
33 #ifdef FX_ENABLE_FAULT_TOLERANT
34 #include "fx_fault_tolerant.h"
35 #endif /* FX_ENABLE_FAULT_TOLERANT */
36
37
38 /**************************************************************************/
39 /* */
40 /* FUNCTION RELEASE */
41 /* */
42 /* _fx_file_create PORTABLE C */
43 /* 6.1 */
44 /* AUTHOR */
45 /* */
46 /* William E. Lamie, Microsoft Corporation */
47 /* */
48 /* DESCRIPTION */
49 /* */
50 /* This function first attempts to find the specified file. If found, */
51 /* the create request is invalid and an error is returned to the */
52 /* caller. After the file name verification is made, a search for a */
53 /* free directory entry will be made. If nothing is available, an */
54 /* error will be returned to the caller. Otherwise, if all is okay, a */
55 /* file of 0 bytes will be created. */
56 /* */
57 /* INPUT */
58 /* */
59 /* media_ptr Media control block pointer */
60 /* file_name File name */
61 /* */
62 /* OUTPUT */
63 /* */
64 /* return status */
65 /* */
66 /* CALLS */
67 /* */
68 /* _fx_directory_entry_write Write the new directory entry */
69 /* _fx_directory_name_extract Extract directory name */
70 /* _fx_directory_search Search for the file name in */
71 /* the directory structure */
72 /* _fx_directory_free_search Search for a free directory */
73 /* entry */
74 /* _fx_fault_tolerant_transaction_start Start fault tolerant */
75 /* transaction */
76 /* _fx_fault_tolerant_transaction_end End fault tolerant transaction*/
77 /* _fx_fault_tolerant_recover Recover FAT chain */
78 /* _fx_fault_tolerant_reset_log_file Reset the log file */
79 /* */
80 /* CALLED BY */
81 /* */
82 /* Application Code */
83 /* */
84 /**************************************************************************/
85 501010 UINT _fx_file_create(FX_MEDIA *media_ptr, CHAR *file_name)
86 {
87
88 FX_INT_SAVE_AREA
89
90 UINT status;
91 CHAR *name_ptr;
92 UINT i;
93 CHAR *work_ptr;
94 FX_DIR_ENTRY dir_entry;
95 FX_DIR_ENTRY search_directory;
96
97
98 #ifndef FX_MEDIA_STATISTICS_DISABLE
99
100 /* Increment the number of times this service has been called. */
101 501010 media_ptr -> fx_media_file_creates++;
102 #endif
103
104 /* Determine if the supplied name is less than the maximum supported name size. The
105 maximum name (FX_MAX_LONG_NAME_LEN) is defined in fx_api.h. */
106 501010 i = 0;
107 501010 work_ptr = (CHAR *)file_name;
108
2/2
✓ Branch 10 → 3 taken 6162208 times.
✓ Branch 10 → 11 taken 501010 times.
6663218 while (*work_ptr)
109 {
110
111 /* Determine if the character designates a new path. */
112
4/4
✓ Branch 3 → 4 taken 5909236 times.
✓ Branch 3 → 5 taken 252972 times.
✓ Branch 4 → 5 taken 2550 times.
✓ Branch 4 → 6 taken 5906686 times.
6162208 if ((*work_ptr == '\\') || (*work_ptr == '/'))
113 {
114 /* Yes, reset the name size. */
115 255522 i = 0;
116 }
117 /* Check for leading spaces. */
118
4/4
✓ Branch 6 → 7 taken 423 times.
✓ Branch 6 → 8 taken 5906263 times.
✓ Branch 7 → 8 taken 207 times.
✓ Branch 7 → 9 taken 216 times.
5906686 else if ((*work_ptr != ' ') || (i != 0))
119 {
120
121 /* No leading spaces, increment the name size. */
122 5906470 i++;
123 }
124
125 /* Move to the next character. */
126 6162208 work_ptr++;
127 }
128
129 /* Determine if the supplied name is valid. */
130
4/4
✓ Branch 11 → 12 taken 501001 times.
✓ Branch 11 → 13 taken 9 times.
✓ Branch 12 → 13 taken 9 times.
✓ Branch 12 → 14 taken 500992 times.
501010 if ((i == 0) || (i >= FX_MAX_LONG_NAME_LEN))
131 {
132
133 /* Return an invalid name value. */
134 18 return(FX_INVALID_NAME);
135 }
136
137 /* Setup pointer to media name buffer. */
138 500992 dir_entry.fx_dir_entry_name = media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN;
139
140 /* Setup another pointer to another media name buffer. */
141 500992 search_directory.fx_dir_entry_name = media_ptr -> fx_media_name_buffer + FX_MAX_LONG_NAME_LEN * 2;
142
143 /* Clear the short name strings. */
144 500992 dir_entry.fx_dir_entry_short_name[0] = 0;
145 500992 search_directory.fx_dir_entry_short_name[0] = 0;
146
147 /* Check the media to make sure it is open. */
148
2/2
✓ Branch 14 → 15 taken 9 times.
✓ Branch 14 → 16 taken 500983 times.
500992 if (media_ptr -> fx_media_id != FX_MEDIA_ID)
149 {
150
151 /* Return the media not opened error. */
152 9 return(FX_MEDIA_NOT_OPEN);
153 }
154
155 /* If trace is enabled, insert this event into the trace buffer. */
156 FX_TRACE_IN_LINE_INSERT(FX_TRACE_FILE_CREATE, media_ptr, file_name, 0, 0, FX_TRACE_FILE_EVENTS, 0, 0)
157
158 /* Protect against other threads accessing the media. */
159 278290 FX_PROTECT
160
161 #ifdef FX_ENABLE_FAULT_TOLERANT
162 /* Start transaction. */
163 224296 _fx_fault_tolerant_transaction_start(media_ptr);
164 #endif /* FX_ENABLE_FAULT_TOLERANT */
165
166 /* Check for write protect at the media level (set by driver). */
167
6/6
✓ Branch 16 → 17 taken 4 times.
✓ Branch 16 → 18 taken 110609 times.
✓ Branch 17 → 18 taken 10 times.
✓ Branch 17 → 20 taken 278144 times.
✓ Branch 18 → 19 taken 4 times.
✓ Branch 18 → 22 taken 112212 times.
500983 if (media_ptr -> fx_media_driver_write_protect)
168 {
169
170 #ifdef FX_ENABLE_FAULT_TOLERANT
171 8 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
172 #endif /* FX_ENABLE_FAULT_TOLERANT */
173
174 /* Release media protection. */
175 10 FX_UNPROTECT
176
177 /* Return write protect error. */
178 18 return(FX_WRITE_PROTECT);
179 }
180
181 /* Search the system for the supplied file name. */
182 500965 status = _fx_directory_search(media_ptr, file_name, &dir_entry, &search_directory, &name_ptr);
183
184 /* Determine if the search was successful. */
185
6/6
✓ Branch 19 → 20 taken 877 times.
✓ Branch 19 → 21 taken 109732 times.
✓ Branch 21 → 22 taken 2298 times.
✓ Branch 21 → 24 taken 275846 times.
✓ Branch 23 → 24 taken 984 times.
✓ Branch 23 → 27 taken 111228 times.
500965 if (status == FX_SUCCESS)
186 {
187
188 #ifdef FX_ENABLE_FAULT_TOLERANT
189 1968 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
190 #endif /* FX_ENABLE_FAULT_TOLERANT */
191
192 /* Release media protection. */
193 2298 FX_UNPROTECT
194
195 /* File found - Return the error code. */
196 4159 return(FX_ALREADY_CREATED);
197 }
198
199 /* Determine if there is anything left after the name. */
200
6/6
✓ Branch 22 → 23 taken 4 times.
✓ Branch 22 → 24 taken 109728 times.
✓ Branch 25 → 26 taken 10 times.
✓ Branch 25 → 28 taken 275836 times.
✓ Branch 28 → 29 taken 4 times.
✓ Branch 28 → 32 taken 111224 times.
496806 if (_fx_directory_name_extract(name_ptr, &dir_entry.fx_dir_entry_name[0]))
201 {
202
203 #ifdef FX_ENABLE_FAULT_TOLERANT
204 8 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
205 #endif /* FX_ENABLE_FAULT_TOLERANT */
206
207 /* Release media protection. */
208 10 FX_UNPROTECT
209
210 /* Extra information after the file name, return an invalid path
211 error. */
212 18 return(FX_INVALID_PATH);
213 }
214
215
216 /* Find a free slot for the new file. */
217 496788 status = _fx_directory_free_search(media_ptr, &search_directory, &dir_entry);
218
219 /* Determine if the search was successful. */
220
6/6
✓ Branch 25 → 26 taken 41 times.
✓ Branch 25 → 27 taken 109687 times.
✓ Branch 29 → 30 taken 101 times.
✓ Branch 29 → 32 taken 275735 times.
✓ Branch 33 → 34 taken 39 times.
✓ Branch 33 → 37 taken 111185 times.
496788 if (status != FX_SUCCESS)
221 {
222
223 #ifdef FX_ENABLE_FAULT_TOLERANT
224 78 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
225 #endif /* FX_ENABLE_FAULT_TOLERANT */
226
227 /* Release media protection. */
228 101 FX_UNPROTECT
229
230 /* Return the error code. */
231 181 return(status);
232 }
233
234 /* Populate the directory entry. */
235
236 /* Isolate the file name. */
237 496607 _fx_directory_name_extract(name_ptr, &dir_entry.fx_dir_entry_name[0]);
238
239 /* Disable interrupts for time/date access. */
240 275871 FX_DISABLE_INTS
241
242 /* Set time and date stamps. */
243 496607 dir_entry.fx_dir_entry_time = _fx_system_time;
244 496607 dir_entry.fx_dir_entry_date = _fx_system_date;
245
246 /* Restore interrupts. */
247 275871 FX_RESTORE_INTS
248
249 /* Set the attributes for the file. */
250 496607 dir_entry.fx_dir_entry_attributes = FX_ARCHIVE;
251
252 /* Set file size to 0. */
253 496607 dir_entry.fx_dir_entry_file_size = 0;
254
255
256 /* Set the cluster to NULL. */
257 496607 dir_entry.fx_dir_entry_cluster = FX_NULL;
258
259 /* Is there a leading dot? */
260
8/8
✓ Branch 28 → 29 taken 4 times.
✓ Branch 28 → 30 taken 109683 times.
✓ Branch 33 → 34 taken 4 times.
✓ Branch 33 → 35 taken 111045 times.
✓ Branch 35 → 36 taken 6 times.
✓ Branch 35 → 37 taken 164680 times.
✓ Branch 40 → 41 taken 4 times.
✓ Branch 40 → 42 taken 111181 times.
496607 if (dir_entry.fx_dir_entry_name[0] == '.')
261 {
262
263 /* Yes, toggle the hidden attribute bit. */
264 18 dir_entry.fx_dir_entry_attributes |= FX_HIDDEN;
265 }
266
267
268 /* Now write out the directory entry. */
269 496607 status = _fx_directory_entry_write(media_ptr, &dir_entry);
270
271 #ifdef FX_ENABLE_FAULT_TOLERANT
272 /* Check for a bad status. */
273
4/4
✓ Branch 36 → 37 taken 12 times.
✓ Branch 36 → 39 taken 111037 times.
✓ Branch 43 → 44 taken 12 times.
✓ Branch 43 → 47 taken 111173 times.
222234 if (status != FX_SUCCESS)
274 {
275
276 24 FX_FAULT_TOLERANT_TRANSACTION_FAIL(media_ptr);
277
278 /* Release media protection. */
279 12 FX_UNPROTECT
280
281 /* Return the bad status. */
282 24 return(status);
283 }
284
285 /* End transaction. */
286 222210 status = _fx_fault_tolerant_transaction_end(media_ptr);
287 #endif /* FX_ENABLE_FAULT_TOLERANT */
288
289 /* Release media protection. */
290 275835 FX_UNPROTECT
291
292 /* File create is complete, return status. */
293 496535 return(status);
294 }
295
296