1616#include <aws/io/stream.h>
1717
1818#include <errno.h>
19+ #include <fcntl.h>
20+ #include <unistd.h>
21+
22+ /* O_DIRECT is not available on all platforms */
23+ #ifndef O_DIRECT
24+ # define O_DIRECT 0
25+ #endif
1926
2027#define ONE_SEC_IN_NS_P ((uint64_t)AWS_TIMESTAMP_NANOS)
2128#define MAX_TIMEOUT_NS_P (600 * ONE_SEC_IN_NS_P)
@@ -98,35 +105,35 @@ static void s_s3_parallel_from_file_read_task(struct aws_task *task, void *arg,
98105 struct read_task_impl * read_task = arg ;
99106 struct aws_parallel_input_stream_from_file_impl * impl = read_task -> para_impl ;
100107 struct aws_future_bool * end_future = read_task -> end_future ;
101- FILE * file_stream = NULL ;
108+ int file_fd = -1 ;
102109 int error_code = AWS_ERROR_SUCCESS ;
103110 size_t actually_read = 0 ;
104111
105- file_stream = aws_fopen (aws_string_c_str (impl -> file_path ), "rb" );
106- if (file_stream == NULL ) {
112+ file_fd = open (aws_string_c_str (impl -> file_path ), O_RDONLY | O_DIRECT );
113+ if (file_fd == -1 ) {
107114 AWS_LOGF_ERROR (
108115 AWS_LS_S3_GENERAL ,
109- "id=%p: Failed to open file %s for reading" ,
116+ "id=%p: Failed to open file %s for reading with O_DIRECT " ,
110117 (void * )& impl -> base ,
111118 aws_string_c_str (impl -> file_path ));
112- error_code = aws_last_error ( );
119+ error_code = aws_translate_and_raise_io_error ( errno );
113120 goto cleanup ;
114121 }
115122
116123 /* seek to the right position and then read */
117- if (aws_fseek ( file_stream , (int64_t )read_task -> offset , SEEK_SET )) {
124+ if (lseek ( file_fd , (off_t )read_task -> offset , SEEK_SET ) == -1 ) {
118125 AWS_LOGF_ERROR (
119126 AWS_LS_S3_GENERAL ,
120127 "id=%p: Failed to seek to position %llu in file %s" ,
121128 (void * )& impl -> base ,
122129 (unsigned long long )read_task -> offset ,
123130 aws_string_c_str (impl -> file_path ));
124- error_code = aws_last_error ( );
131+ error_code = aws_translate_and_raise_io_error ( errno );
125132 goto cleanup ;
126133 }
127134
128- actually_read = fread ( read_task -> dest -> buffer + read_task -> dest -> len , 1 , read_task -> length , file_stream );
129- if (actually_read == 0 && ferror ( file_stream ) ) {
135+ ssize_t bytes_read = read ( file_fd , read_task -> dest -> buffer + read_task -> dest -> len , read_task -> length );
136+ if (bytes_read == -1 ) {
130137 AWS_LOGF_ERROR (
131138 AWS_LS_S3_GENERAL ,
132139 "id=%p: Failed to read %zu bytes from file %s" ,
@@ -137,6 +144,7 @@ static void s_s3_parallel_from_file_read_task(struct aws_task *task, void *arg,
137144 goto cleanup ;
138145 }
139146
147+ actually_read = (size_t )bytes_read ;
140148 read_task -> dest -> len += actually_read ;
141149
142150 AWS_LOGF_TRACE (
@@ -148,8 +156,8 @@ static void s_s3_parallel_from_file_read_task(struct aws_task *task, void *arg,
148156 (unsigned long long )read_task -> offset );
149157
150158cleanup :
151- if (file_stream != NULL ) {
152- fclose ( file_stream );
159+ if (file_fd != -1 ) {
160+ close ( file_fd );
153161 }
154162
155163 if (error_code != AWS_ERROR_SUCCESS ) {
0 commit comments