1010
1111#include " src/__support/CPP/span.h"
1212
13- #include < errno.h>
13+ #include < errno.h> // For error macros
1414#include < stdio.h>
1515#include < stdlib.h>
1616
1717namespace __llvm_libc {
1818
19- size_t File::write_unlocked (const void *data, size_t len) {
19+ FileIOResult File::write_unlocked (const void *data, size_t len) {
2020 if (!write_allowed ()) {
21- errno = EBADF;
2221 err = true ;
23- return 0 ;
22+ return { 0 , EBADF} ;
2423 }
2524
2625 prev_op = FileOp::WRITE;
@@ -37,26 +36,27 @@ size_t File::write_unlocked(const void *data, size_t len) {
3736 }
3837}
3938
40- size_t File::write_unlocked_nbf (const uint8_t *data, size_t len) {
39+ FileIOResult File::write_unlocked_nbf (const uint8_t *data, size_t len) {
4140 if (pos > 0 ) { // If the buffer is not empty
4241 // Flush the buffer
4342 const size_t write_size = pos;
44- size_t bytes_written = platform_write (this , buf, write_size);
43+ auto write_result = platform_write (this , buf, write_size);
4544 pos = 0 ; // Buffer is now empty so reset pos to the beginning.
4645 // If less bytes were written than expected, then an error occurred.
47- if (bytes_written < write_size) {
46+ if (write_result < write_size) {
4847 err = true ;
49- return 0 ; // No bytes from data were written, so return 0.
48+ // No bytes from data were written, so return 0.
49+ return {0 , write_result.error };
5050 }
5151 }
5252
53- size_t written = platform_write (this , data, len);
54- if (written < len)
53+ auto write_result = platform_write (this , data, len);
54+ if (write_result < len)
5555 err = true ;
56- return written ;
56+ return write_result ;
5757}
5858
59- size_t File::write_unlocked_fbf (const uint8_t *data, size_t len) {
59+ FileIOResult File::write_unlocked_fbf (const uint8_t *data, size_t len) {
6060 const size_t init_pos = pos;
6161 const size_t bufspace = bufsize - pos;
6262
@@ -96,13 +96,17 @@ size_t File::write_unlocked_fbf(const uint8_t *data, size_t len) {
9696 // We need to flush the buffer now, since there is still data and the buffer
9797 // is full.
9898 const size_t write_size = pos;
99- size_t bytes_written = platform_write (this , buf, write_size);
99+
100+ auto buf_result = platform_write (this , buf, write_size);
101+ size_t bytes_written = buf_result.value ;
102+
100103 pos = 0 ; // Buffer is now empty so reset pos to the beginning.
101104 // If less bytes were written than expected, then an error occurred. Return
102105 // the number of bytes that have been written from |data|.
103- if (bytes_written < write_size) {
106+ if (buf_result. has_error () || bytes_written < write_size) {
104107 err = true ;
105- return bytes_written <= init_pos ? 0 : bytes_written - init_pos;
108+ return {bytes_written <= init_pos ? 0 : bytes_written - init_pos,
109+ buf_result.error };
106110 }
107111
108112 // The second piece is handled basically the same as the first, although we
@@ -114,21 +118,22 @@ size_t File::write_unlocked_fbf(const uint8_t *data, size_t len) {
114118 bufref[i] = remainder[i];
115119 pos = remainder.size ();
116120 } else {
117- size_t bytes_written =
118- platform_write (this , remainder.data (), remainder.size ());
121+
122+ auto result = platform_write (this , remainder.data (), remainder.size ());
123+ size_t bytes_written = buf_result.value ;
119124
120125 // If less bytes were written than expected, then an error occurred. Return
121126 // the number of bytes that have been written from |data|.
122- if (bytes_written < remainder.size ()) {
127+ if (result. has_error () || bytes_written < remainder.size ()) {
123128 err = true ;
124- return primary.size () + bytes_written;
129+ return { primary.size () + bytes_written, result. error } ;
125130 }
126131 }
127132
128133 return len;
129134}
130135
131- size_t File::write_unlocked_lbf (const uint8_t *data, size_t len) {
136+ FileIOResult File::write_unlocked_lbf (const uint8_t *data, size_t len) {
132137 constexpr uint8_t NEWLINE_CHAR = ' \n ' ;
133138 size_t last_newline = len;
134139 for (size_t i = len; i >= 1 ; --i) {
@@ -175,11 +180,10 @@ size_t File::write_unlocked_lbf(const uint8_t *data, size_t len) {
175180 return len;
176181}
177182
178- size_t File::read_unlocked (void *data, size_t len) {
183+ FileIOResult File::read_unlocked (void *data, size_t len) {
179184 if (!read_allowed ()) {
180- errno = EBADF;
181185 err = true ;
182- return 0 ;
186+ return { 0 , EBADF} ;
183187 }
184188
185189 prev_op = FileOp::READ;
@@ -210,31 +214,33 @@ size_t File::read_unlocked(void *data, size_t len) {
210214
211215 size_t to_fetch = len - available_data;
212216 if (to_fetch > bufsize) {
213- size_t fetched_size = platform_read (this , dataref.data (), to_fetch);
214- if (fetched_size < to_fetch) {
215- if (errno == 0 )
217+ auto result = platform_read (this , dataref.data (), to_fetch);
218+ size_t fetched_size = result.value ;
219+ if (result.has_error () || fetched_size < to_fetch) {
220+ if (!result.has_error ())
216221 eof = true ;
217222 else
218223 err = true ;
219- return available_data + fetched_size;
224+ return { available_data + fetched_size, result. has_error ()} ;
220225 }
221226 return len;
222227 }
223228
224229 // Fetch and buffer another buffer worth of data.
225- size_t fetched_size = platform_read (this , buf, bufsize);
230+ auto result = platform_read (this , buf, bufsize);
231+ size_t fetched_size = result.value ;
226232 read_limit += fetched_size;
227233 size_t transfer_size = fetched_size >= to_fetch ? to_fetch : fetched_size;
228234 for (size_t i = 0 ; i < transfer_size; ++i)
229235 dataref[i] = bufref[i];
230236 pos += transfer_size;
231- if (fetched_size < to_fetch) {
232- if (errno == 0 )
237+ if (result. has_error () || fetched_size < to_fetch) {
238+ if (!result. has_error () )
233239 eof = true ;
234240 else
235241 err = true ;
236242 }
237- return transfer_size + available_data;
243+ return { transfer_size + available_data, result. error } ;
238244}
239245
240246int File::ungetc_unlocked (int c) {
@@ -275,13 +281,14 @@ int File::ungetc_unlocked(int c) {
275281 return c;
276282}
277283
278- int File::seek (long offset, int whence) {
284+ ErrorOr< int > File::seek (long offset, int whence) {
279285 FileLock lock (this );
280286 if (prev_op == FileOp::WRITE && pos > 0 ) {
281- size_t transferred_size = platform_write (this , buf, pos);
282- if (transferred_size < pos) {
287+
288+ auto buf_result = platform_write (this , buf, pos);
289+ if (buf_result.has_error () || buf_result.value < pos) {
283290 err = true ;
284- return - 1 ;
291+ return Error (buf_result. error ) ;
285292 }
286293 } else if (prev_op == FileOp::READ && whence == SEEK_CUR) {
287294 // More data could have been read out from the platform file than was
@@ -294,22 +301,20 @@ int File::seek(long offset, int whence) {
294301 // Reset the eof flag as a seek might move the file positon to some place
295302 // readable.
296303 eof = false ;
297- long platform_pos = platform_seek (this , offset, whence);
298- if (platform_pos >= 0 )
299- return 0 ;
304+ auto result = platform_seek (this , offset, whence);
305+ if (!result. has_value () )
306+ return Error (result. error ()) ;
300307 else
301- return - 1 ;
308+ return 0 ;
302309}
303310
304- long File::tell () {
311+ ErrorOr< long > File::tell () {
305312 FileLock lock (this );
306- long platform_offset;
307- if (eof)
308- platform_offset = platform_seek (this , 0 , SEEK_END);
309- else
310- platform_offset = platform_seek (this , 0 , SEEK_CUR);
311- if (platform_offset < 0 )
312- return -1 ;
313+ auto seek_target = eof ? SEEK_END : SEEK_CUR;
314+ auto result = platform_seek (this , 0 , seek_target);
315+ if (!result.has_value () || result.value () < 0 )
316+ return Error (result.error ());
317+ long platform_offset = result.value ();
313318 if (prev_op == FileOp::READ)
314319 return platform_offset - (read_limit - pos);
315320 else if (prev_op == FileOp::WRITE)
@@ -320,10 +325,10 @@ long File::tell() {
320325
321326int File::flush_unlocked () {
322327 if (prev_op == FileOp::WRITE && pos > 0 ) {
323- size_t transferred_size = platform_write (this , buf, pos);
324- if (transferred_size < pos) {
328+ auto buf_result = platform_write (this , buf, pos);
329+ if (buf_result. has_error () || buf_result. value < pos) {
325330 err = true ;
326- return - 1 ;
331+ return buf_result. error ;
327332 }
328333 pos = 0 ;
329334 return platform_flush (this );
@@ -336,14 +341,15 @@ int File::close() {
336341 {
337342 FileLock lock (this );
338343 if (prev_op == FileOp::WRITE && pos > 0 ) {
339- size_t transferred_size = platform_write (this , buf, pos);
340- if (transferred_size < pos) {
344+ auto buf_result = platform_write (this , buf, pos);
345+ if (buf_result. has_error () || buf_result. value < pos) {
341346 err = true ;
342- return - 1 ;
347+ return buf_result. error ;
343348 }
344349 }
345- if (platform_close (this ) != 0 )
346- return -1 ;
350+ int result = platform_close (this );
351+ if (result != 0 )
352+ return result;
347353 if (own_buf)
348354 free (buf);
349355 }
0 commit comments