Explorar el Código

Use the new atomic file API instead of ad-hoc code

[hertzog@debian.org:
 - Switch dselect method option file. ]
Guillem Jover hace 14 años
padre
commit
68189bc967
Se han modificado 7 ficheros con 67 adiciones y 208 borrados
  1. 8 19
      dselect/methparse.cc
  2. 0 2
      lib/dpkg/dpkg.h
  3. 11 32
      lib/dpkg/dump.c
  4. 20 78
      lib/dpkg/triglib.c
  5. 9 24
      src/divertcmd.c
  6. 10 29
      src/filesdb.c
  7. 9 24
      src/statcmd.c

+ 8 - 19
dselect/methparse.cc

@@ -274,25 +274,14 @@ void getcurrentopt() {
 }
 
 void writecurrentopt() {
-  FILE *cmo;
-  int l;
-  static char *newfile=0;
+  struct atomic_file *file;
 
   assert(methoptfile);
-  if (!newfile) {
-    l= strlen(methoptfile);
-    newfile= new char[l + sizeof(NEWDBEXT) + 1];
-    strcpy(newfile,methoptfile);
-    strcpy(newfile+l, NEWDBEXT);
-  }
-  cmo= fopen(newfile,"w");
-  if (!cmo) ohshite(_("unable to open new option file `%.250s'"),newfile);
-  if (fprintf(cmo,"%s %s\n",coption->meth->name,coption->name) == EOF) {
-    fclose(cmo);
-    ohshite(_("unable to write new option to `%.250s'"),newfile);
-  }
-  if (fclose(cmo))
-    ohshite(_("unable to close new option file `%.250s'"),newfile);
-  if (rename(newfile,methoptfile))
-    ohshite(_("unable to install new option as `%.250s'"),methoptfile);
+  file = atomic_file_new(methoptfile, (enum atomic_file_flags)0);
+  atomic_file_open(file);
+  if (fprintf(file->fp, "%s %s\n", coption->meth->name, coption->name) == EOF)
+    ohshite(_("unable to write new option to `%.250s'"), file->name_new);
+  atomic_file_close(file);
+  atomic_file_commit(file);
+  atomic_file_free(file);
 }

+ 0 - 2
lib/dpkg/dpkg.h

@@ -35,8 +35,6 @@ DPKG_BEGIN_DECLS
 #define MAXDIVERTFILENAME   1024
 #define MAXCONTROLFILENAME  100
 #define DEBEXT             ".deb"
-#define OLDDBEXT           "-old"
-#define NEWDBEXT           "-new"
 #define REMOVECONFFEXTS    "~", ".bak", "%", \
                            DPKGTEMPEXT, DPKGNEWEXT, DPKGOLDEXT, DPKGDISTEXT
 

+ 11 - 32
lib/dpkg/dump.c

@@ -450,23 +450,15 @@ writedb(const char *filename, enum writedb_flags flags)
   struct pkgiterator *it;
   struct pkginfo *pigp;
   struct pkgbin *pifp;
-  char *oldfn, *newfn;
   const char *which;
-  FILE *file;
+  struct atomic_file *file;
   struct varbuf vb = VARBUF_INIT;
-  int old_umask;
 
   which = (flags & wdb_dump_available) ? "available" : "status";
-  m_asprintf(&oldfn, "%s%s", filename, OLDDBEXT);
-  m_asprintf(&newfn, "%s%s", filename, NEWDBEXT);
 
-  old_umask = umask(022);
-  file= fopen(newfn,"w");
-  umask(old_umask);
-  if (!file)
-    ohshite(_("failed to open '%s' for writing %s database"), filename, which);
-
-  if (setvbuf(file,writebuf,_IOFBF,sizeof(writebuf)))
+  file = atomic_file_new(filename, aff_backup);
+  atomic_file_open(file);
+  if (setvbuf(file->fp, writebuf, _IOFBF, sizeof(writebuf)))
     ohshite(_("unable to set buffering on %s database file"), which);
 
   it = pkg_db_iter_new();
@@ -478,33 +470,20 @@ writedb(const char *filename, enum writedb_flags flags)
     varbufrecord(&vb,pigp,pifp);
     varbuf_add_char(&vb, '\n');
     varbuf_end_str(&vb);
-    if (fputs(vb.buf,file) < 0)
+    if (fputs(vb.buf, file->fp) < 0)
       ohshite(_("failed to write %s database record about '%.50s' to '%.250s'"),
               which, pigp->set->name, filename);
     varbuf_reset(&vb);
   }
   pkg_db_iter_free(it);
   varbuf_destroy(&vb);
-  if (flags & wdb_must_sync) {
-    if (fflush(file))
-      ohshite(_("failed to flush %s database to '%.250s'"), which, filename);
-    if (fsync(fileno(file)))
-      ohshite(_("failed to fsync %s database to '%.250s'"), which, filename);
-  }
-  if (fclose(file))
-    ohshite(_("failed to close '%.250s' after writing %s database"),
-            filename, which);
-  unlink(oldfn);
-  if (link(filename,oldfn) && errno != ENOENT)
-    ohshite(_("failed to link '%.250s' to '%.250s' for backup of %s database"),
-            filename, oldfn, which);
-  if (rename(newfn,filename))
-    ohshite(_("failed to install '%.250s' as '%.250s' containing %s database"),
-            newfn, filename, which);
+  if (flags & wdb_must_sync)
+    atomic_file_sync(file);
+
+  atomic_file_close(file);
+  atomic_file_commit(file);
+  atomic_file_free(file);
 
   if (flags & wdb_must_sync)
     dir_sync_path_parent(filename);
-
-  free(newfn);
-  free(oldfn);
 }

+ 20 - 78
lib/dpkg/triglib.c

@@ -41,7 +41,7 @@
 
 /*========== Recording triggers. ==========*/
 
-static char *triggersdir, *triggersfilefile, *triggersnewfilefile;
+static char *triggersdir, *triggersfilefile;
 
 static char *
 trig_get_filename(const char *dir, const char *filename)
@@ -311,82 +311,43 @@ trk_explicit_activate_awaiter(struct pkginfo *aw)
 	}
 }
 
-static void
-trk_explicit_interest_flush(const char *newfilename, FILE *nf)
-{
-	if (ferror(nf))
-		ohshite(_("unable to write new trigger interest file `%.250s'"),
-		        newfilename);
-	if (fflush(nf))
-		ohshite(_("unable to flush new trigger interest file '%.250s'"),
-		        newfilename);
-	if (fsync(fileno(nf)))
-		ohshite(_("unable to sync new trigger interest file '%.250s'"),
-		        newfilename);
-}
-
-static void
-trk_explicit_interest_commit(const char *newfilename)
-{
-	if (rename(newfilename, trk_explicit_fn.buf))
-		ohshite(_("unable to install new trigger interest file `%.250s'"),
-		        trk_explicit_fn.buf);
-}
-
-static void
-trk_explicit_interest_remove(const char *newfilename)
-{
-	if (unlink(newfilename))
-		ohshite(_("cannot remove `%.250s'"), newfilename);
-	if (unlink(trk_explicit_fn.buf) && errno != ENOENT)
-		ohshite(_("cannot remove `%.250s'"), trk_explicit_fn.buf);
-}
-
 static void
 trk_explicit_interest_change(const char *trig,  struct pkginfo *pkg, int signum,
                              enum trig_options opts)
 {
-	static struct varbuf newfn;
 	char buf[1024];
-	FILE *nf;
+	struct atomic_file *file;
 	bool empty = true;
 
 	trk_explicit_start(trig);
-	varbuf_reset(&newfn);
-	varbuf_printf(&newfn, "%s/%s.new", triggersdir, trig);
-
-	nf = fopen(newfn.buf, "w");
-	if (!nf)
-		ohshite(_("unable to create new trigger interest file `%.250s'"),
-		        newfn.buf);
-	push_cleanup(cu_closestream, ~ehflag_normaltidy, NULL, 0, 1, nf);
+	file = atomic_file_new(trk_explicit_fn.buf, 0);
+	atomic_file_open(file);
 
 	while (trk_explicit_f && trk_explicit_fgets(buf, sizeof(buf)) >= 0) {
 		int len = strlen(pkg->set->name);
 		if (strncmp(buf, pkg->set->name, len) == 0 &&
 		    (buf[len] == '\0' || buf[len] == '/'))
 			continue;
-		fprintf(nf, "%s\n", buf);
+		fprintf(file->fp, "%s\n", buf);
 		empty = false;
 	}
 	if (signum > 0) {
-		fprintf(nf, "%s%s\n", pkg->set->name,
+		fprintf(file->fp, "%s%s\n", pkg->set->name,
 		        (opts == trig_noawait) ? "/noawait" : "");
 		empty = false;
 	}
 
 	if (!empty)
-		trk_explicit_interest_flush(newfn.buf, nf);
+		atomic_file_sync(file);
 
-	pop_cleanup(ehflag_normaltidy);
-	if (fclose(nf))
-		ohshite(_("unable to close new trigger interest file `%.250s'"),
-		        newfn.buf);
+	atomic_file_close(file);
 
 	if (empty)
-		trk_explicit_interest_remove(newfn.buf);
+		atomic_file_remove(file);
 	else
-		trk_explicit_interest_commit(newfn.buf);
+		atomic_file_commit(file);
+
+	atomic_file_free(file);
 
 	dir_sync_path(triggersdir);
 }
@@ -476,36 +437,20 @@ static void
 trig_file_interests_update(void)
 {
 	struct trigfileint *tfi;
-	FILE *nf;
+	struct atomic_file *file;
 
-	nf = fopen(triggersnewfilefile, "w");
-	if (!nf)
-		ohshite(_("unable to create new file triggers file `%.250s'"),
-		        triggersnewfilefile);
-	push_cleanup(cu_closestream, ~ehflag_normaltidy, NULL, 0, 1, nf);
+	file = atomic_file_new(triggersfilefile, 0);
+	atomic_file_open(file);
 
 	for (tfi = filetriggers.head; tfi; tfi = tfi->inoverall.next)
-		fprintf(nf, "%s %s%s\n", trigh.namenode_name(tfi->fnn),
+		fprintf(file->fp, "%s %s%s\n", trigh.namenode_name(tfi->fnn),
 		        tfi->pkg->set->name,
 		        (tfi->options == trig_noawait) ? "/noawait" : "");
 
-	if (ferror(nf))
-		ohshite(_("unable to write new file triggers file `%.250s'"),
-		        triggersnewfilefile);
-	if (fflush(nf))
-		ohshite(_("unable to flush new file triggers file '%.250s'"),
-		        triggersnewfilefile);
-	if (fsync(fileno(nf)))
-		ohshite(_("unable to sync new file triggers file '%.250s'"),
-		        triggersnewfilefile);
-	pop_cleanup(ehflag_normaltidy);
-	if (fclose(nf))
-		ohshite(_("unable to close new file triggers file `%.250s'"),
-		        triggersnewfilefile);
-
-	if (rename(triggersnewfilefile, triggersfilefile))
-		ohshite(_("unable to install new file triggers file as `%.250s'"),
-		        triggersfilefile);
+	atomic_file_sync(file);
+	atomic_file_close(file);
+	atomic_file_commit(file);
+	atomic_file_free(file);
 }
 
 void
@@ -756,9 +701,6 @@ trig_incorporate(enum modstatdb_rw cstatus)
 	free(triggersfilefile);
 	triggersfilefile = trig_get_filename(triggersdir, "File");
 
-	free(triggersnewfilefile);
-	triggersnewfilefile = trig_get_filename(triggersdir, "File.new");
-
 	trigdef_set_methods(&tdm_incorp);
 	trig_file_interests_ensure();
 

+ 9 - 24
src/divertcmd.c

@@ -343,19 +343,15 @@ diversion_describe(struct diversion *d)
 static void
 divertdb_write(void)
 {
-	char *dbname, *dbname_new, *dbname_old;
-	FILE *dbfile;
+	char *dbname;
+	struct atomic_file *file;
 	struct fileiterator *iter;
 	struct filenamenode *namenode;
 
 	dbname = dpkg_db_get_path(DIVERSIONSFILE);
-	m_asprintf(&dbname_new, "%s%s", dbname, NEWDBEXT);
-	m_asprintf(&dbname_old, "%s%s", dbname, OLDDBEXT);
 
-	dbfile = fopen(dbname_new, "w");
-	if (!dbfile)
-		ohshite(_("cannot create new %s file"), DIVERSIONSFILE);
-	chmod(dbname_new, 0644);
+	file = atomic_file_new(dbname, aff_backup);
+	atomic_file_open(file);
 
 	iter = iterfilestart();
 	while ((namenode = iterfilenext(iter))) {
@@ -364,30 +360,19 @@ divertdb_write(void)
 		if (d == NULL || d->useinstead == NULL)
 			continue;
 
-		fprintf(dbfile, "%s\n%s\n%s\n",
+		fprintf(file->fp, "%s\n%s\n%s\n",
 		        d->useinstead->divert->camefrom->name,
 		        d->useinstead->name,
 		        diversion_pkg_name(d));
 	}
 	iterfileend(iter);
 
-	if (fflush(dbfile))
-		ohshite(_("unable to flush file '%s'"), dbname_new);
-	if (fsync(fileno(dbfile)))
-		ohshite(_("unable to sync file '%s'"), dbname_new);
-	if (fclose(dbfile))
-		ohshite(_("unable to close file '%s'"), dbname_new);
-
-	if (unlink(dbname_old) && errno != ENOENT)
-		ohshite(_("error removing old diversions-old"));
-	if (link(dbname, dbname_old) && errno != ENOENT)
-		ohshite(_("error creating new diversions-old"));
-	if (rename(dbname_new, dbname))
-		ohshite(_("error installing new diversions"));
+	atomic_file_sync(file);
+	atomic_file_close(file);
+	atomic_file_commit(file);
+	atomic_file_free(file);
 
 	free(dbname);
-	free(dbname_new);
-	free(dbname_old);
 }
 
 static int

+ 10 - 29
src/filesdb.c

@@ -510,45 +510,26 @@ void
 write_filelist_except(struct pkginfo *pkg, struct pkgbin *pkgbin,
                       struct fileinlist *list, enum fnnflags mask)
 {
-  static struct varbuf newvb;
+  struct atomic_file *file;
   const char *listfile;
-  FILE *file;
 
   listfile = pkgadminfile(pkg, pkgbin, LISTFILE);
 
-  varbuf_reset(&newvb);
-  varbuf_add_str(&newvb, listfile);
-  varbuf_add_str(&newvb, NEWDBEXT);
-  varbuf_end_str(&newvb);
+  file = atomic_file_new(listfile, 0);
+  atomic_file_open(file);
 
-  file= fopen(newvb.buf,"w+");
-  if (!file)
-    ohshite(_("unable to create updated files list file for package %s"),
-            pkg->set->name);
-  push_cleanup(cu_closestream, ehflag_bombout, NULL, 0, 1, (void *)file);
   while (list) {
     if (!(mask && (list->namenode->flags & mask))) {
-      fputs(list->namenode->name,file);
-      putc('\n',file);
+      fputs(list->namenode->name, file->fp);
+      putc('\n', file->fp);
     }
     list= list->next;
   }
-  if (ferror(file))
-    ohshite(_("failed to write to updated files list file for package %s"),
-            pkg->set->name);
-  if (fflush(file))
-    ohshite(_("failed to flush updated files list file for package %s"),
-            pkg->set->name);
-  if (fsync(fileno(file)))
-    ohshite(_("failed to sync updated files list file for package %s"),
-            pkg->set->name);
-  pop_cleanup(ehflag_normaltidy); /* file = fopen() */
-  if (fclose(file))
-    ohshite(_("failed to close updated files list file for package %s"),
-            pkg->set->name);
-  if (rename(newvb.buf, listfile))
-    ohshite(_("failed to install updated files list file for package %s"),
-            pkg->set->name);
+
+  atomic_file_sync(file);
+  atomic_file_close(file);
+  atomic_file_commit(file);
+  atomic_file_free(file);
 
   dir_sync_path(pkgadmindir());
 

+ 9 - 24
src/statcmd.c

@@ -193,43 +193,28 @@ statdb_node_print(FILE *out, struct filenamenode *file)
 static void
 statdb_write(void)
 {
-	char *dbname, *dbname_new, *dbname_old;
-	FILE *dbfile;
+	char *dbname;
+	struct atomic_file *dbfile;
 	struct fileiterator *i;
 	struct filenamenode *file;
 
 	dbname = dpkg_db_get_path(STATOVERRIDEFILE);
-	m_asprintf(&dbname_new, "%s%s", dbname, NEWDBEXT);
-	m_asprintf(&dbname_old, "%s%s", dbname, OLDDBEXT);
-
-	dbfile = fopen(dbname_new, "w");
-	if (!dbfile)
-		ohshite(_("cannot open new statoverride file"));
+	dbfile = atomic_file_new(dbname, aff_backup);
+	atomic_file_open(dbfile);
 
 	i = iterfilestart();
 	while ((file = iterfilenext(i)))
-		statdb_node_print(dbfile, file);
+		statdb_node_print(dbfile->fp, file);
 	iterfileend(i);
 
-	if (fflush(dbfile))
-		ohshite(_("unable to flush file '%s'"), dbname_new);
-	if (fsync(fileno(dbfile)))
-		ohshite(_("unable to sync file '%s'"), dbname_new);
-	fclose(dbfile);
-
-	chmod(dbname_new, 0644);
-	if (unlink(dbname_old) && errno != ENOENT)
-		ohshite(_("error removing statoverride-old"));
-	if (link(dbname, dbname_old) && errno != ENOENT)
-		ohshite(_("error creating new statoverride-old"));
-	if (rename(dbname_new, dbname))
-		ohshite(_("error installing new statoverride"));
+	atomic_file_sync(dbfile);
+	atomic_file_close(dbfile);
+	atomic_file_commit(dbfile);
+	atomic_file_free(dbfile);
 
 	dir_sync_path(dpkg_db_get_dir());
 
 	free(dbname);
-	free(dbname_new);
-	free(dbname_old);
 }
 
 static int