xref: /netbsd-src/external/gpl3/gdb/dist/libctf/testsuite/libctf-regression/gzrewrite.c (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
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