Просмотр исходного кода

libdpkg: Refactor parse_open() and parse_close() from parsedb()

This will allow code using parse_stanza() to avoid having to reimplement
the opening and closing logic.
Guillem Jover лет назад: 15
Родитель
Сommit
6ee5e8af9d
2 измененных файлов с 72 добавлено и 43 удалено
  1. 67 43
      lib/dpkg/parse.c
  2. 5 0
      lib/dpkg/parsedump.h

+ 67 - 43
lib/dpkg/parse.c

@@ -302,6 +302,53 @@ pkg_parse_copy(struct parsedb_state *ps,
   }
 }
 
+/**
+ * Open a file for RFC-822 parsing.
+ */
+void
+parse_open(struct parsedb_state *ps, const char *filename,
+           enum parsedbflags flags)
+{
+  static int fd;
+  struct stat st;
+
+  ps->filename = filename;
+  ps->flags = flags;
+  ps->lno = 0;
+
+  fd = open(filename, O_RDONLY);
+  if (fd == -1)
+    ohshite(_("failed to open package info file `%.255s' for reading"),
+            filename);
+
+  push_cleanup(cu_closefd, ~ehflag_normaltidy, NULL, 0, 1, &fd);
+
+  if (fstat(fd, &st) == -1)
+    ohshite(_("can't stat package info file `%.255s'"), filename);
+
+  if (st.st_size > 0) {
+#ifdef USE_MMAP
+    ps->dataptr = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+    if (ps->dataptr == MAP_FAILED)
+      ohshite(_("can't mmap package info file `%.255s'"), filename);
+#else
+    ps->dataptr = m_malloc(st.st_size);
+
+    if (fd_read(fd, ps->dataptr, st.st_size) < 0)
+      ohshite(_("reading package info file '%.255s'"), filename);
+#endif
+    ps->data = ps->dataptr;
+    ps->endptr = ps->dataptr + st.st_size;
+  } else {
+    ps->data = ps->dataptr = ps->endptr = NULL;
+  }
+
+  pop_cleanup(ehflag_normaltidy);
+
+  if (close(fd))
+    ohshite(_("failed to close after read: `%.255s'"), filename);
+}
+
 /**
  * Parse an RFC-822 style stanza.
  */
@@ -421,6 +468,21 @@ parse_stanza(struct parsedb_state *ps, struct field_state *fs,
   return true;
 }
 
+/**
+ * Close an RFC-822 parser context.
+ */
+void
+parse_close(struct parsedb_state *ps)
+{
+  if (ps->data != NULL) {
+#ifdef USE_MMAP
+    munmap(ps->data, ps->endptr - ps->data);
+#else
+    free(ps->data);
+#endif
+  }
+}
+
 /**
  * Parse an RFC-822 style file.
  *
@@ -430,24 +492,19 @@ parse_stanza(struct parsedb_state *ps, struct field_state *fs,
 int parsedb(const char *filename, enum parsedbflags flags,
             struct pkginfo **donep)
 {
-  static int fd;
   struct pkginfo tmp_pkg;
   struct pkginfo *new_pkg, *db_pkg;
   struct pkgbin *new_pkgbin, *db_pkgbin;
   int fieldencountered[array_count(fieldinfos)];
   int pdone;
-  char *data;
-  struct stat st;
   struct parsedb_state ps;
   struct field_state fs;
 
-  ps.filename = filename;
-  ps.flags = flags;
-  ps.lno = 0;
-
   memset(&fs, 0, sizeof(fs));
   fs.fieldencountered = fieldencountered;
 
+  parse_open(&ps, filename, flags);
+
   new_pkg = &tmp_pkg;
   if (flags & pdb_recordavailable)
     new_pkgbin = &new_pkg->available;
@@ -457,35 +514,6 @@ int parsedb(const char *filename, enum parsedbflags flags,
   ps.pkg = new_pkg;
   ps.pkgbin = new_pkgbin;
 
-  fd= open(filename, O_RDONLY);
-  if (fd == -1) ohshite(_("failed to open package info file `%.255s' for reading"),filename);
-
-  push_cleanup(cu_closefd, ~ehflag_normaltidy, NULL, 0, 1, &fd);
-
-  if (fstat(fd, &st) == -1)
-    ohshite(_("can't stat package info file `%.255s'"),filename);
-
-  if (st.st_size > 0) {
-#ifdef USE_MMAP
-    ps.dataptr = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
-    if (ps.dataptr == MAP_FAILED)
-      ohshite(_("can't mmap package info file `%.255s'"),filename);
-#else
-    ps.dataptr = m_malloc(st.st_size);
-
-    if (fd_read(fd, ps.dataptr, st.st_size) < 0)
-      ohshite(_("reading package info file '%.255s'"), filename);
-#endif
-    data = ps.dataptr;
-    ps.endptr = ps.dataptr + st.st_size;
-  } else {
-    data = ps.dataptr = ps.endptr = NULL;
-  }
-
-  pop_cleanup(ehflag_normaltidy);
-  if (close(fd))
-    ohshite(_("failed to close after read: `%.255s'"), filename);
-
   pdone= 0;
 
   /* Loop per package. */
@@ -520,13 +548,9 @@ int parsedb(const char *filename, enum parsedbflags flags,
     if (parse_EOF(&ps))
       break;
   }
-  if (data != NULL) {
-#ifdef USE_MMAP
-    munmap(data, st.st_size);
-#else
-    free(data);
-#endif
-  }
+
+  parse_close(&ps);
+
   varbuf_destroy(&fs.value);
   if (donep && !pdone) ohshit(_("no package information in `%.255s'"),filename);
 

+ 5 - 0
lib/dpkg/parsedump.h

@@ -28,6 +28,7 @@ struct parsedb_state {
 	enum parsedbflags flags;
 	struct pkginfo *pkg;
 	struct pkgbin *pkgbin;
+	char *data;
 	char *dataptr;
 	char *endptr;
 	const char *filename;
@@ -47,6 +48,10 @@ struct field_state {
 	int *fieldencountered;
 };
 
+void parse_open(struct parsedb_state *ps, const char *filename,
+                enum parsedbflags flags);
+void parse_close(struct parsedb_state *ps);
+
 typedef void parse_field_func(struct parsedb_state *ps, struct field_state *fs,
                               struct pkginfo *pkg, struct pkgbin *pkgbin);