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