Home | History | Annotate | Line # | Download | only in libctf-regression
      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