commit 06aef97ceacf6506da8fc66e51735ad09cc88556
parent d533827b53eeeb8b54de589694f41c13d88f0bdd
Author: sin <sin@2f30.org>
Date: Sun, 3 Mar 2013 15:55:25 +0000
mdiff: Fix bugs and add mdiff_read_diff()
Diffstat:
3 files changed, 64 insertions(+), 15 deletions(-)
diff --git a/docs/mdiff-fmt b/docs/mdiff-fmt
@@ -3,9 +3,11 @@ File format of the mdiff files
struct mdiff_hdr {
/* MDIFF\0 */
- char magic[6];
+ char magic[8];
/* Number of memory diff regions */
uint32_t nregions;
+ /* Block size */
+ uint32_t blksize;
};
struct mdiff_region {
diff --git a/mdiff.c b/mdiff.c
@@ -18,7 +18,7 @@ create_mdiff(const char *path)
{
int fd;
- fd = open(path, O_RDWR);
+ fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
if (fd < 0)
errx(1, "%s: %s", path, strerror(errno));
return fd;
@@ -38,23 +38,24 @@ close_mdiff(int fd)
return 0;
}
-int
+struct mdiff_hdr *
parse_mdiff_hdr(int fd)
{
- struct mdiff_hdr hdr;
+ struct mdiff_hdr *hdr;
ssize_t ret;
if (fd < 0)
- return -EINVAL;
+ return NULL;
- ret = read(fd, &hdr, sizeof(hdr));
- if (ret != sizeof(hdr))
+ hdr = xmalloc(sizeof(*hdr));
+ ret = read(fd, hdr, sizeof(*hdr));
+ if (ret != sizeof(*hdr))
err(1, "read");
- if (memcmp(hdr.magic, "MDIFF", sizeof(hdr.magic)))
- return -EINVAL;
- if (!hdr.nregions)
- return -EINVAL;
- return 0;
+ if (strncmp(hdr->magic, "MDIFF", 5))
+ return NULL;
+ if (!hdr->nregions)
+ return NULL;
+ return hdr;
}
int
@@ -88,6 +89,48 @@ mdiff_start_diff(int fd)
return 0;
}
+struct mdiff_region *
+mdiff_read_diff(int fd, struct mdiff_hdr *hdr, uint32_t region)
+{
+ int ret;
+ off_t offset;
+ struct mdiff_region *mdiff;
+ uint32_t i;
+ uint32_t len;
+
+ if (fd < 0 || !hdr)
+ return NULL;
+
+ offset = sizeof(*hdr);
+ ret = lseek(fd, offset, SEEK_SET);
+ if (ret < 0)
+ err(1, "lseek");
+ mdiff = xmalloc(sizeof(*mdiff));
+ for (i = 0; i < region; i++) {
+ ret = read(fd, mdiff, sizeof(*mdiff));
+ if (ret != sizeof(*mdiff))
+ err(1, "read");
+ offset += sizeof(*mdiff);
+ offset += mdiff->len;
+ ret = lseek(fd, offset, SEEK_SET);
+ if (ret < 0)
+ err(1, "lseek");
+ }
+
+ ret = read(fd, mdiff, sizeof(*mdiff));
+ if (ret != sizeof(*mdiff))
+ err(1, "mdiff");
+ ret = lseek(fd, offset, SEEK_SET);
+ if (ret < 0)
+ err(1, "lseek");
+ len = mdiff->len;
+ mdiff = xrealloc(mdiff, sizeof(*mdiff) + len);
+ ret = read(fd, mdiff, sizeof(*mdiff) + len);
+ if ((size_t)ret != sizeof(*mdiff) + len)
+ err(1, "read");
+ return mdiff;
+}
+
int
mdiff_append_rdiff(int fd, struct mem_region_diff *rdiff)
{
diff --git a/proto.h b/proto.h
@@ -101,10 +101,12 @@ struct mem_tree_entry {
RB_HEAD(mem_tree, mem_tree_entry);
struct mdiff_hdr {
- /* MDIFF\0 */
- char magic[6];
+ /* MDIFF */
+ char magic[8];
/* Number of memory diff regions */
uint32_t nregions;
+ /* Block size */
+ uint32_t blksize;
};
struct mdiff_region {
@@ -159,9 +161,11 @@ void readmem(pid_t pid, void *buf, void *offset, size_t size);
int open_mdiff(const char *path);
int create_mdiff(const char *path);
int close_mdiff(int fd);
-int parse_mdiff_hdr(int fd);
+struct mdiff_hdr *parse_mdiff_hdr(int fd);
int mdiff_insert_hdr(int fd, struct mdiff_hdr *hdr);
int mdiff_start_diff(int fd);
+struct mdiff_region *mdiff_read_diff(int fd, struct mdiff_hdr *hdr,
+ uint32_t region);
int mdiff_append_rdiff(int fd, struct mem_region_diff *rdiff);
#endif