copy.c revision 302408
1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr_arch_file_io.h" 18#include "apr_file_io.h" 19 20static apr_status_t apr_file_transfer_contents(const char *from_path, 21 const char *to_path, 22 apr_int32_t flags, 23 apr_fileperms_t to_perms, 24 apr_pool_t *pool) 25{ 26 apr_file_t *s, *d; 27 apr_status_t status; 28 apr_finfo_t finfo; 29 apr_fileperms_t perms; 30 31 /* Open source file. */ 32 status = apr_file_open(&s, from_path, APR_FOPEN_READ, APR_OS_DEFAULT, pool); 33 if (status) 34 return status; 35 36 /* Maybe get its permissions. */ 37 if (to_perms == APR_FILE_SOURCE_PERMS) { 38 status = apr_file_info_get(&finfo, APR_FINFO_PROT, s); 39 if (status != APR_SUCCESS && status != APR_INCOMPLETE) { 40 apr_file_close(s); /* toss any error */ 41 return status; 42 } 43 perms = finfo.protection; 44 } 45 else 46 perms = to_perms; 47 48 /* Open dest file. */ 49 status = apr_file_open(&d, to_path, flags, perms, pool); 50 if (status) { 51 apr_file_close(s); /* toss any error */ 52 return status; 53 } 54 55#if BUFSIZ > APR_FILE_DEFAULT_BUFSIZE 56#define COPY_BUFSIZ BUFSIZ 57#else 58#define COPY_BUFSIZ APR_FILE_DEFAULT_BUFSIZE 59#endif 60 61 /* Copy bytes till the cows come home. */ 62 while (1) { 63 char buf[COPY_BUFSIZ]; 64 apr_size_t bytes_this_time = sizeof(buf); 65 apr_status_t read_err; 66 apr_status_t write_err; 67 68 /* Read 'em. */ 69 read_err = apr_file_read(s, buf, &bytes_this_time); 70 if (read_err && !APR_STATUS_IS_EOF(read_err)) { 71 apr_file_close(s); /* toss any error */ 72 apr_file_close(d); /* toss any error */ 73 return read_err; 74 } 75 76 /* Write 'em. */ 77 write_err = apr_file_write_full(d, buf, bytes_this_time, NULL); 78 if (write_err) { 79 apr_file_close(s); /* toss any error */ 80 apr_file_close(d); /* toss any error */ 81 return write_err; 82 } 83 84 if (read_err && APR_STATUS_IS_EOF(read_err)) { 85 status = apr_file_close(s); 86 if (status) { 87 apr_file_close(d); /* toss any error */ 88 return status; 89 } 90 91 /* return the results of this close: an error, or success */ 92 return apr_file_close(d); 93 } 94 } 95 /* NOTREACHED */ 96} 97 98APR_DECLARE(apr_status_t) apr_file_copy(const char *from_path, 99 const char *to_path, 100 apr_fileperms_t perms, 101 apr_pool_t *pool) 102{ 103 return apr_file_transfer_contents(from_path, to_path, 104 (APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE), 105 perms, 106 pool); 107} 108 109APR_DECLARE(apr_status_t) apr_file_append(const char *from_path, 110 const char *to_path, 111 apr_fileperms_t perms, 112 apr_pool_t *pool) 113{ 114 return apr_file_transfer_contents(from_path, to_path, 115 (APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_APPEND), 116 perms, 117 pool); 118} 119