1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** FileX Component */
16 /** */
17 /** File */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define FX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "fx_api.h"
28 #include "fx_system.h"
29 #include "fx_file.h"
30 #include "fx_utility.h"
31 #include "fx_directory.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _fx_file_close PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* William E. Lamie, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function closes the specified file. If the file was written */
47 /* to this function will also write the directory entry (with the new */
48 /* size and time/date stamp) out to disk. */
49 /* */
50 /* INPUT */
51 /* */
52 /* file_ptr File control block pointer */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* return status */
57 /* */
58 /* CALLS */
59 /* */
60 /* _fx_directory_entry_write Write the directory entry */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* Application Code */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
71 /* 09-30-2020 William E. Lamie Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* */
74 /**************************************************************************/
_fx_file_close(FX_FILE * file_ptr)75 UINT _fx_file_close(FX_FILE *file_ptr)
76 {
77
78 UINT status;
79 FX_MEDIA *media_ptr;
80 FX_INT_SAVE_AREA
81
82
83 /* First, determine if the file is still open. */
84 if (file_ptr -> fx_file_id != FX_FILE_ID)
85 {
86
87 /* Return the file not open error status. */
88 return(FX_NOT_OPEN);
89 }
90
91 /* Setup a pointer to the associated media. */
92 media_ptr = file_ptr -> fx_file_media_ptr;
93
94 #ifndef FX_MEDIA_STATISTICS_DISABLE
95
96 /* Increment the number of times this service has been called. */
97 media_ptr -> fx_media_file_closes++;
98 #endif
99
100 /* If trace is enabled, insert this event into the trace buffer. */
101 FX_TRACE_IN_LINE_INSERT(FX_TRACE_FILE_CLOSE, file_ptr, file_ptr -> fx_file_current_file_size, 0, 0, FX_TRACE_FILE_EVENTS, 0, 0)
102
103 /* Protect against other threads accessing the media. */
104 FX_PROTECT
105 /* If trace is enabled, unregister this object. */
106 FX_TRACE_OBJECT_UNREGISTER(file_ptr)
107
108 /* Remove this file from the opened list for the media. */
109
110 /* See if the file is the only one on the open list for this media. */
111 if (file_ptr == file_ptr -> fx_file_opened_next)
112 {
113
114 /* Only opened file, just set the opened list to NULL. */
115 media_ptr -> fx_media_opened_file_list = FX_NULL;
116 }
117 else
118 {
119
120 /* Otherwise, not the only opened file, link-up the neighbors. */
121 (file_ptr -> fx_file_opened_next) -> fx_file_opened_previous =
122 file_ptr -> fx_file_opened_previous;
123 (file_ptr -> fx_file_opened_previous) -> fx_file_opened_next =
124 file_ptr -> fx_file_opened_next;
125
126 /* See if we have to update the opened list head pointer. */
127 if (media_ptr -> fx_media_opened_file_list == file_ptr)
128 {
129
130 /* Yes, move the head pointer to the next opened file. */
131 media_ptr -> fx_media_opened_file_list = file_ptr -> fx_file_opened_next;
132 }
133 }
134
135 /* Decrement the opened file counter. */
136 media_ptr -> fx_media_opened_file_count--;
137
138 /* Finally, Indicate that this file is closed. */
139 file_ptr -> fx_file_id = FX_FILE_CLOSED_ID;
140
141 /* Check to see if this file needs to have its directory entry written
142 back to the media. */
143 if ((file_ptr -> fx_file_open_mode == FX_OPEN_FOR_WRITE) &&
144 (file_ptr -> fx_file_modified))
145 {
146
147 /* Lockout interrupts for time/date access. */
148 FX_DISABLE_INTS
149
150 /* Set the new time and date. */
151 file_ptr -> fx_file_dir_entry.fx_dir_entry_time = _fx_system_time;
152 file_ptr -> fx_file_dir_entry.fx_dir_entry_date = _fx_system_date;
153
154 /* Set the last access date. */
155 file_ptr -> fx_file_dir_entry.fx_dir_entry_last_accessed_date = _fx_system_date;
156
157 /* Restore interrupts. */
158 FX_RESTORE_INTS
159
160 /* Copy the new file size into the directory entry. */
161 file_ptr -> fx_file_dir_entry.fx_dir_entry_file_size =
162 file_ptr -> fx_file_current_file_size;
163
164 /* Write the directory entry to the media. */
165 status = _fx_directory_entry_write(media_ptr, &(file_ptr -> fx_file_dir_entry));
166
167 /* Check for a good status. */
168 if (status != FX_SUCCESS)
169 {
170
171 /* Release media protection. */
172 FX_UNPROTECT
173
174 /* Error writing the directory. */
175 return(status);
176 }
177 }
178
179 /* Release media protection. */
180 FX_UNPROTECT
181
182 /* Return status to the caller. */
183 return(FX_SUCCESS);
184 }
185
186