Some C99 flexible array changes
authorWayne Davison <wayne@opencoder.net>
Mon, 6 Jul 2020 00:04:37 +0000 (17:04 -0700)
committerWayne Davison <wayne@opencoder.net>
Mon, 6 Jul 2020 00:25:53 +0000 (17:25 -0700)
- Use C99 flexible arrays when possible, and fall back on the existing
  fname[1] kluges on older compilers.
- Avoid static initialization of a flexible array, which is not really
  in the C standard.

flist.c
rsync.h

diff --git a/flist.c b/flist.c
index f248e29b7339370ea26ae32ecf3e34a881959928..5970ce548f4eeb88988f2a301f2db3da89e11d8f 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -1892,7 +1892,7 @@ static void send_implied_dirs(int f, struct file_list *flist, char *fname,
                memcpy(F_DIR_RELNAMES_P(lastpath_struct), &relname_list, sizeof relname_list);
        }
        rnpp = EXPAND_ITEM_LIST(relname_list, relnamecache *, 32);
-       *rnpp = (relnamecache*)new_array(char, sizeof (relnamecache) + len);
+       *rnpp = (relnamecache*)new_array(char, RELNAMECACHE_LEN + len + 1);
        (*rnpp)->name_type = name_type;
        strlcpy((*rnpp)->fname, limit+1, len + 1);
 
@@ -2051,8 +2051,7 @@ void send_extra_file_list(int f, int at_least)
 
                if (need_unsorted_flist) {
                        flist->sorted = new_array(struct file_struct *, flist->used);
-                       memcpy(flist->sorted, flist->files,
-                              flist->used * sizeof (struct file_struct*));
+                       memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
                } else
                        flist->sorted = flist->files;
 
@@ -2405,8 +2404,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
         * send them together in a single file-list. */
        if (need_unsorted_flist) {
                flist->sorted = new_array(struct file_struct *, flist->used);
-               memcpy(flist->sorted, flist->files,
-                      flist->used * sizeof (struct file_struct*));
+               memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
        } else
                flist->sorted = flist->files;
        flist_sort_and_clean(flist, 0);
@@ -2587,8 +2585,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
                 * list unsorted for our exchange of index numbers with the
                 * other side (since their names may not sort the same). */
                flist->sorted = new_array(struct file_struct *, flist->used);
-               memcpy(flist->sorted, flist->files,
-                      flist->used * sizeof (struct file_struct*));
+               memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
                if (inc_recurse && dir_flist->used > dstart) {
                        static int dir_flist_malloced = 0;
                        if (dir_flist_malloced < dir_flist->malloced) {
@@ -2598,7 +2595,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
                                dir_flist_malloced = dir_flist->malloced;
                        }
                        memcpy(dir_flist->sorted + dstart, dir_flist->files + dstart,
-                              (dir_flist->used - dstart) * sizeof (struct file_struct*));
+                              (dir_flist->used - dstart) * PTR_SIZE);
                        fsort(dir_flist->sorted + dstart, dir_flist->used - dstart);
                }
        } else {
diff --git a/rsync.h b/rsync.h
index 41c4052b99fede4fe97a7f4c739fa76282943ca4..1d6b81792f092c7a3c842d654d6d3ef789dc4c53 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -732,6 +732,10 @@ struct ht_int64_node {
 # error Character pointers are not 4 or 8 bytes.
 #endif
 
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#define USE_FLEXIBLE_ARRAY 1
+#endif
+
 union file_extras {
        int32 num;
        uint32 unum;
@@ -753,7 +757,11 @@ struct file_struct {
        uint32 len32;           /* Lowest 32 bits of the file's length */
        uint16 mode;            /* The item's type and permissions */
        uint16 flags;           /* The FLAG_* bits for this item */
-       const char basename[1]; /* The basename (AKA filename) follows */
+#ifdef USE_FLEXIBLE_ARRAY
+       const char basename[];  /* The basename (AKA filename) follows */
+#else
+       const char basename[1]; /* A kluge that should work like a flexible array */
+#endif
 };
 
 extern int file_extra_cnt;
@@ -766,7 +774,11 @@ extern int gid_ndx;
 extern int acls_ndx;
 extern int xattrs_ndx;
 
+#ifdef USE_FLEXIBLE_ARRAY
+#define FILE_STRUCT_LEN (sizeof (struct file_struct))
+#else
 #define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
+#endif
 #define EXTRA_LEN (sizeof (union file_extras))
 #define DEV_EXTRA_CNT 2
 #define DIRNODE_EXTRA_CNT 3
@@ -1035,9 +1047,19 @@ typedef struct {
 
 typedef struct {
        char name_type;
-       char fname[1]; /* has variable size */
+#ifdef USE_FLEXIBLE_ARRAY
+       char fname[]; /* has variable size */
+#else
+       char fname[1]; /* A kluge that should work like a flexible array */
+#endif
 } relnamecache;
 
+#ifdef USE_FLEXIBLE_ARRAY
+#define RELNAMECACHE_LEN (sizeof (relnamecache))
+#else
+#define RELNAMECACHE_LEN (offsetof(relnamecache, fname))
+#endif
+
 #include "byteorder.h"
 #include "lib/mdigest.h"
 #include "lib/wildmatch.h"
@@ -1094,7 +1116,7 @@ struct name_num_obj {
        uchar *saw;
        int saw_len;
        int negotiated_num;
-       struct name_num_item list[];
+       struct name_num_item list[8]; /* A big-enough len (we'll get a compile error if it is ever too small) */
 };
 
 #ifndef __cplusplus