copy.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. #include "apr_arch_file_io.h"
  17. #include "apr_file_io.h"
  18. static apr_status_t apr_file_transfer_contents(const char *from_path,
  19. const char *to_path,
  20. apr_int32_t flags,
  21. apr_fileperms_t to_perms,
  22. apr_pool_t *pool)
  23. {
  24. apr_file_t *s, *d;
  25. apr_status_t status;
  26. apr_finfo_t finfo;
  27. apr_fileperms_t perms;
  28. /* Open source file. */
  29. status = apr_file_open(&s, from_path, APR_FOPEN_READ, APR_OS_DEFAULT, pool);
  30. if (status)
  31. return status;
  32. /* Maybe get its permissions. */
  33. if (to_perms == APR_FILE_SOURCE_PERMS) {
  34. status = apr_file_info_get(&finfo, APR_FINFO_PROT, s);
  35. if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
  36. apr_file_close(s); /* toss any error */
  37. return status;
  38. }
  39. perms = finfo.protection;
  40. }
  41. else
  42. perms = to_perms;
  43. /* Open dest file. */
  44. status = apr_file_open(&d, to_path, flags, perms, pool);
  45. if (status) {
  46. apr_file_close(s); /* toss any error */
  47. return status;
  48. }
  49. #if BUFSIZ > APR_FILE_DEFAULT_BUFSIZE
  50. #define COPY_BUFSIZ BUFSIZ
  51. #else
  52. #define COPY_BUFSIZ APR_FILE_DEFAULT_BUFSIZE
  53. #endif
  54. /* Copy bytes till the cows come home. */
  55. while (1) {
  56. char buf[COPY_BUFSIZ];
  57. apr_size_t bytes_this_time = sizeof(buf);
  58. apr_status_t read_err;
  59. apr_status_t write_err;
  60. /* Read 'em. */
  61. read_err = apr_file_read(s, buf, &bytes_this_time);
  62. if (read_err && !APR_STATUS_IS_EOF(read_err)) {
  63. apr_file_close(s); /* toss any error */
  64. apr_file_close(d); /* toss any error */
  65. return read_err;
  66. }
  67. /* Write 'em. */
  68. write_err = apr_file_write_full(d, buf, bytes_this_time, NULL);
  69. if (write_err) {
  70. apr_file_close(s); /* toss any error */
  71. apr_file_close(d); /* toss any error */
  72. return write_err;
  73. }
  74. if (read_err && APR_STATUS_IS_EOF(read_err)) {
  75. status = apr_file_close(s);
  76. if (status) {
  77. apr_file_close(d); /* toss any error */
  78. return status;
  79. }
  80. /* return the results of this close: an error, or success */
  81. return apr_file_close(d);
  82. }
  83. }
  84. /* NOTREACHED */
  85. }
  86. APR_DECLARE(apr_status_t) apr_file_copy(const char *from_path,
  87. const char *to_path,
  88. apr_fileperms_t perms,
  89. apr_pool_t *pool)
  90. {
  91. return apr_file_transfer_contents(from_path, to_path,
  92. (APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE),
  93. perms,
  94. pool);
  95. }
  96. APR_DECLARE(apr_status_t) apr_file_append(const char *from_path,
  97. const char *to_path,
  98. apr_fileperms_t perms,
  99. apr_pool_t *pool)
  100. {
  101. return apr_file_transfer_contents(from_path, to_path,
  102. (APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_APPEND),
  103. perms,
  104. pool);
  105. }