1 /* Make sure that you can modify then ctf_gzwrite() a dict 2 and it changes after modification. */ 3 4 #include <ctf-api.h> 5 #include <errno.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 10 #include <zlib.h> 11 12 char *read_gz(const char *path, size_t *len) 13 { 14 char *in = NULL; 15 char buf[4096]; 16 gzFile foo; 17 size_t ret; 18 19 if ((foo = gzopen (path, "rb")) == NULL) 20 return NULL; 21 22 *len = 0; 23 while ((ret = gzread (foo, buf, 4096)) > 0) 24 { 25 if ((in = realloc (in, *len + ret)) == NULL) 26 { 27 fprintf (stderr, "Out of memory\n"); 28 exit (1); 29 } 30 31 memcpy (&in[*len], buf, ret); 32 *len += ret; 33 } 34 if (ret < 0) 35 { 36 int errnum; 37 const char *err; 38 err = gzerror (foo, &errnum); 39 if (errnum != Z_ERRNO) 40 fprintf (stderr, "error reading %s: %s\n", path, err); 41 else 42 fprintf (stderr, "error reading %s: %s\n", path, strerror(errno)); 43 exit (1); 44 } 45 gzclose (foo); 46 return in; 47 } 48 49 int 50 main (int argc, char *argv[]) 51 { 52 ctf_dict_t *fp, *fp_b; 53 ctf_archive_t *ctf; 54 gzFile foo; 55 char *a, *b; 56 size_t a_len, b_len; 57 ctf_id_t type, ptrtype; 58 int err; 59 60 if (argc != 2) 61 { 62 fprintf (stderr, "Syntax: %s PROGRAM\n", argv[0]); 63 exit(1); 64 } 65 66 if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL) 67 goto open_err; 68 if ((fp = ctf_dict_open (ctf, NULL, &err)) == NULL) 69 goto open_err; 70 71 if ((foo = gzopen ("tmpdir/one.gz", "wb")) == NULL) 72 goto write_gzerr; 73 if (ctf_gzwrite (fp, foo) < 0) 74 goto write_err; 75 gzclose (foo); 76 77 if ((foo = gzopen ("tmpdir/two.gz", "wb")) == NULL) 78 goto write_gzerr; 79 if (ctf_gzwrite (fp, foo) < 0) 80 goto write_err; 81 gzclose (foo); 82 83 if ((a = read_gz ("tmpdir/one.gz", &a_len)) == NULL) 84 goto read_err; 85 86 if ((b = read_gz ("tmpdir/two.gz", &b_len)) == NULL) 87 goto read_err; 88 89 if (a_len != b_len || memcmp (a, b, a_len) != 0) 90 { 91 fprintf (stderr, "consecutive gzwrites are different: lengths %zu and %zu\n", a_len, b_len); 92 return 1; 93 } 94 95 free (b); 96 97 /* Add some new types to the dict and write it out, then read it back in and 98 make sure they're still there, and that at least some of the 99 originally-present data objects are still there too. */ 100 101 if ((type = ctf_lookup_by_name (fp, "struct a_struct")) == CTF_ERR) 102 fprintf (stderr, "Lookup of struct a_struct failed: %s\n", ctf_errmsg (ctf_errno (fp))); 103 104 if ((ptrtype = ctf_add_pointer (fp, CTF_ADD_ROOT, type)) == CTF_ERR) 105 fprintf (stderr, "Cannot add pointer to ctf_opened dict: %s\n", ctf_errmsg (ctf_errno (fp))); 106 107 unlink ("tmpdir/two.gz"); 108 if ((foo = gzopen ("tmpdir/two.gz", "wb")) == NULL) 109 goto write_gzerr; 110 if (ctf_gzwrite (fp, foo) < 0) 111 goto write_err; 112 gzclose (foo); 113 114 if ((b = read_gz ("tmpdir/two.gz", &b_len)) == NULL) 115 goto read_err; 116 117 if (a_len == b_len && memcmp (a, b, b_len) == 0) 118 { 119 fprintf (stderr, "gzwrites after adding types does not change the dict\n"); 120 return 1; 121 } 122 123 free (a); 124 if ((fp_b = ctf_simple_open (b, b_len, NULL, 0, 0, NULL, 0, &err)) == NULL) 125 goto open_err; 126 127 if (ctf_type_reference (fp_b, ptrtype) == CTF_ERR) 128 fprintf (stderr, "Lookup of pointer preserved across writeout failed: %s\n", ctf_errmsg (ctf_errno (fp_b))); 129 130 if (ctf_type_reference (fp_b, ptrtype) != type) 131 fprintf (stderr, "Look up of newly-added type in serialized dict yields ID %lx, expected %lx\n", ctf_type_reference (fp_b, ptrtype), type); 132 133 if (ctf_lookup_by_symbol_name (fp_b, "an_int") == CTF_ERR) 134 fprintf (stderr, "Lookup of symbol an_int failed: %s\n", ctf_errmsg (ctf_errno (fp_b))); 135 136 free (b); 137 ctf_dict_close (fp); 138 ctf_dict_close (fp_b); 139 ctf_close (ctf); 140 141 printf ("All done.\n"); 142 return 0; 143 144 open_err: 145 fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err)); 146 return 1; 147 write_err: 148 fprintf (stderr, "%s: cannot write: %s\n", argv[0], ctf_errmsg (ctf_errno (fp))); 149 return 1; 150 write_gzerr: 151 { 152 int errnum; 153 const char *err; 154 155 err = gzerror (foo, &errnum); 156 if (errnum != Z_ERRNO) 157 fprintf (stderr, "error gzwriting: %s\n", err); 158 else 159 fprintf (stderr, "error gzwriting: %s\n", strerror(errno)); 160 return 1; 161 } 162 read_err: 163 fprintf (stderr, "%s: cannot read\n", argv[0]); 164 return 1; 165 } 166