CI: added FreeBSD build
[rsync.git] / fileio.c
index bd2e36ae3cff51826266d332c6612950c9e9c5e5..69c9a7b494917bbee44fda0e8f1fca9d31ae463b 100644 (file)
--- a/fileio.c
+++ b/fileio.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1998 Andrew Tridgell
  * Copyright (C) 2002 Martin Pool
- * Copyright (C) 2004-2020 Wayne Davison
+ * Copyright (C) 2004-2023 Wayne Davison
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,28 +40,34 @@ OFF_T preallocated_len = 0;
 static OFF_T sparse_seek = 0;
 static OFF_T sparse_past_write = 0;
 
-int sparse_end(int f, OFF_T size)
+int sparse_end(int f, OFF_T size, int updating_basis_or_equiv)
 {
-       int ret;
-
-       if (!sparse_seek)
-               return 0;
+       int ret = 0;
 
+       if (updating_basis_or_equiv) {
+               if (sparse_seek && do_punch_hole(f, sparse_past_write, sparse_seek) < 0)
+                       ret = -1;
+#ifdef HAVE_FTRUNCATE /* A compilation formality -- in-place requires ftruncate() */
+               else /* Just in case the original file was longer */
+                       ret = do_ftruncate(f, size);
+#endif
+       } else if (sparse_seek) {
 #ifdef HAVE_FTRUNCATE
-       ret = do_ftruncate(f, size);
+               ret = do_ftruncate(f, size);
 #else
-       if (do_lseek(f, sparse_seek-1, SEEK_CUR) != size-1)
-               ret = -1;
-       else {
-               do {
-                       ret = write(f, "", 1);
-               } while (ret < 0 && errno == EINTR);
-
-               ret = ret <= 0 ? -1 : 0;
-       }
+               if (do_lseek(f, sparse_seek-1, SEEK_CUR) != size-1)
+                       ret = -1;
+               else {
+                       do {
+                               ret = write(f, "", 1);
+                       } while (ret < 0 && errno == EINTR);
+
+                       ret = ret <= 0 ? -1 : 0;
+               }
 #endif
+       }
 
-       sparse_seek = 0;
+       sparse_past_write = sparse_seek = 0;
 
        return ret;
 }
@@ -155,8 +161,6 @@ int write_file(int f, int use_seek, OFF_T offset, const char *buf, int len)
                                wf_writeBufSize = WRITE_SIZE * 8;
                                wf_writeBufCnt  = 0;
                                wf_writeBuf = new_array(char, wf_writeBufSize);
-                               if (!wf_writeBuf)
-                                       out_of_memory("write_file");
                        }
                        r1 = (int)MIN((size_t)len, wf_writeBufSize - wf_writeBufCnt);
                        if (r1) {
@@ -215,8 +219,7 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
 {
        struct map_struct *map;
 
-       if (!(map = new0(struct map_struct)))
-               out_of_memory("map_file");
+       map = new0(struct map_struct);
 
        if (blk_size && (read_size % blk_size))
                read_size += blk_size - (read_size % blk_size);
@@ -259,8 +262,6 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
        /* make sure we have allocated enough memory for the window */
        if (window_size > map->p_size) {
                map->p = realloc_array(map->p, char, window_size);
-               if (!map->p)
-                       out_of_memory("map_ptr");
                map->p_size = window_size;
        }