@@ -120,80 +120,20 @@ MVMnum64 MVM_file_time(MVMThreadContext *tc, MVMString *filename, MVMint64 statu
120
120
121
121
/* copy a file from one to another */
122
122
void MVM_file_copy (MVMThreadContext * tc , MVMString * src , MVMString * dest ) {
123
- /* TODO: on Windows we can use the CopyFile API, which is probaly
124
- more efficient, not to mention easier to use. */
123
+ char * const a = MVM_string_utf8_c8_encode_C_string ( tc , src );
124
+ char * const b = MVM_string_utf8_c8_encode_C_string ( tc , dest );
125
125
uv_fs_t req ;
126
- char * a , * b ;
127
- uv_file in_fd = -1 , out_fd = -1 ;
128
- MVMuint64 size , offset ;
129
-
130
- a = MVM_string_utf8_c8_encode_C_string (tc , src );
131
- b = MVM_string_utf8_c8_encode_C_string (tc , dest );
132
-
133
- /* If the file cannot be stat(), there is little point in going any further. */
134
- if (uv_fs_stat (tc -> loop , & req , a , NULL ) < 0 )
135
- goto failure ;
136
- size = req .statbuf .st_size ;
137
-
138
- in_fd = uv_fs_open (tc -> loop , & req , (const char * )a , O_RDONLY , 0 , NULL );
139
- if (in_fd < 0 ) {
140
- goto failure ;
141
- }
142
-
143
- out_fd = uv_fs_open (tc -> loop , & req , (const char * )b , O_WRONLY | O_CREAT | O_TRUNC , DEFAULT_MODE , NULL );
144
- if (out_fd < 0 ) {
145
- goto failure ;
146
- }
147
-
148
- offset = 0 ;
149
- do {
150
- /* sendfile() traditionally takes offset as a pointer argument
151
- * used a both input and output. libuv deviates by making
152
- * offset an integer and returning the number of bytes
153
- * sent. So it is necessary to add these explicitly. */
154
- MVMint64 sent = uv_fs_sendfile (tc -> loop , & req , out_fd , in_fd , offset , size - offset , NULL );
155
- if (sent < 0 ) {
156
- goto failure ;
157
- }
158
- offset += sent ;
159
- } while (offset < size );
160
126
161
- /* Cleanup */
162
- if (uv_fs_close (tc -> loop , & req , in_fd , NULL ) < 0 ) {
163
- goto failure ;
164
- }
165
- in_fd = -1 ;
166
-
167
- if (uv_fs_close (tc -> loop , & req , out_fd , NULL ) < 0 ) {
168
- goto failure ;
127
+ if (uv_fs_copyfile (tc -> loop , & req , a , b , 0 , NULL ) < 0 ) {
128
+ MVM_free (a );
129
+ MVM_free (b );
130
+ MVM_exception_throw_adhoc (tc , "Failed to copy file: %s" , uv_strerror (req .result ));
169
131
}
170
132
171
- MVM_free (b );
172
133
MVM_free (a );
173
- return ;
174
-
175
- failure : {
176
- /* First get the error, since it may be overwritten further on. */
177
- const char * error = uv_strerror (req .result );
178
- /* Basic premise: dealing with all failure cases is hard.
179
- * So to simplify, a and b are allocated in all conditions.
180
- * Also to simplify, in_fd are nonnegative if open, negative
181
- * otherwise. */
182
- MVM_free (b );
183
- MVM_free (a );
184
- /* If any of these fail there is nothing
185
- * further to do, since we're already failing */
186
- if (in_fd >= 0 )
187
- uv_fs_close (tc -> loop , & req , in_fd , NULL );
188
- if (out_fd >= 0 )
189
- uv_fs_close (tc -> loop , & req , out_fd , NULL );
190
- /* This function only throws adhoc errors, so the message is for
191
- * progammer eyes only */
192
- MVM_exception_throw_adhoc (tc , "Failed to copy file: %s" , error );
193
- }
134
+ MVM_free (b );
194
135
}
195
136
196
-
197
137
/* rename one file to another. */
198
138
void MVM_file_rename (MVMThreadContext * tc , MVMString * src , MVMString * dest ) {
199
139
char * const a = MVM_string_utf8_c8_encode_C_string (tc , src );
0 commit comments