Make ef_open() extend files with fixed size automatically
authorMarkus Armbruster <armbru@pond.sub.org>
Wed, 4 May 2011 05:45:05 +0000 (07:45 +0200)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 25 Jun 2011 14:50:06 +0000 (16:50 +0200)
Turns the fixed size into an invariant.  Before, the files utility
created them empty, then extended them.

src/lib/common/file.c
src/util/files.c

index d7fd63557edc0ce5bde0a7c8f9abe2123745c88f..e586d96e022c1d44ce7ba2ec7f7c2a2a367cc246 100644 (file)
@@ -58,6 +58,7 @@ static int do_write(struct empfile *, void *, int, int);
 static unsigned get_seqno(struct empfile *, int);
 static void new_seqno(struct empfile *, void *);
 static void must_be_fresh(struct empfile *, void *);
+static int do_extend(struct empfile *, int);
 static void do_blank(struct empfile *, void *, int, int);
 static int ef_check(int);
 
@@ -74,7 +75,7 @@ int
 ef_open(int type, int how)
 {
     struct empfile *ep;
-    int oflags, fd, fsiz, fids, nslots;
+    int oflags, fd, fsiz, fids, nslots, fail;
 
     if (ef_check(type) < 0)
        return 0;
@@ -97,19 +98,23 @@ ef_open(int type, int how)
     }
 
     /* get file size */
-    fsiz = fsize(fd);
-    if (fsiz % ep->size) {
-       logerror("Can't open %s (file size not a multiple of record size %d)",
-                ep->file, ep->size);
-       close(fd);
-       return 0;
-    }
-    fids = fsiz / ep->size;
-    if (ep->nent >= 0 && ep->nent != fids && !(how & EFF_CREATE)) {
-       logerror("Can't open %s (got %d records instead of %d)",
-                ep->file, fids, ep->nent);
-       close(fd);
-       return 0;
+    if (how & EFF_CREATE) {
+       fids = ep->nent >= 0 ? ep->nent : 0;
+    } else {
+       fsiz = fsize(fd);
+       if (fsiz % ep->size) {
+           logerror("Can't open %s (file size not a multiple of record size %d)",
+                    ep->file, ep->size);
+           close(fd);
+           return 0;
+       }
+       fids = fsiz / ep->size;
+       if (ep->nent >= 0 && ep->nent != fids) {
+           logerror("Can't open %s (got %d records instead of %d)",
+                    ep->file, fids, ep->nent);
+           close(fd);
+           return 0;
+       }
     }
 
     /* allocate cache */
@@ -139,17 +144,24 @@ ef_open(int type, int how)
     }
     ep->baseid = 0;
     ep->cids = 0;
-    ep->fids = fids;
     ep->flags = (ep->flags & EFF_IMMUTABLE) | (how & ~EFF_CREATE);
     ep->fd = fd;
 
-    /* map file into cache */
-    if ((how & EFF_MEM) && fids) {
-       if (fillcache(ep, 0) != fids) {
-           ep->cids = 0;       /* prevent cache flush */
-           ef_close(type);
-           return 0;
-       }
+    if (how & EFF_CREATE) {
+       /* populate new file */
+       ep->fids = 0;
+       fail = !do_extend(ep, fids);
+    } else {
+       ep->fids = fids;
+       if ((how & EFF_MEM) && fids)
+           fail = fillcache(ep, 0) != fids;
+       else
+           fail = 0;
+    }
+    if (fail) {
+       ep->cids = 0;   /* prevent cache flush */
+       ef_close(type);
+       return 0;
     }
 
     if (ep->onresize)
@@ -678,13 +690,24 @@ int
 ef_extend(int type, int count)
 {
     struct empfile *ep;
-    char *p;
-    int need_sentinel, i, id;
 
-    if (ef_check(type) < 0 || CANT_HAPPEN(EF_IS_VIEW(type)))
+    if (ef_check(type) < 0)
        return 0;
     ep = &empfile[type];
-    if (CANT_HAPPEN(count < 0))
+    if (!do_extend(ep, count))
+       return 0;
+    if (ep->onresize)
+       ep->onresize(type);
+    return 1;
+}
+
+static int
+do_extend(struct empfile *ep, int count)
+{
+    char *p;
+    int need_sentinel, i, id;
+
+    if (CANT_HAPPEN(EF_IS_VIEW(ep->uid)) || count < 0)
        return 0;
 
     id = ep->fids;
@@ -723,8 +746,6 @@ ef_extend(int type, int count)
        }
     }
     ep->fids = id + count;
-    if (ep->onresize)
-       ep->onresize(type);
     return 1;
 }
 
index 85fa7d630dd16d2e64792e3e4a261ee3e97fe18e..10bf5d2fb3bbd9c09ef7b568650d6582d442297d 100644 (file)
@@ -136,8 +136,6 @@ main(int argc, char *argv[])
        }
     }
 
-    ef_extend(EF_GAME, 1);
-    ef_extend(EF_NATION, MAXNOC);
     ef_read(EF_NATION, 0, &nat);
     strcpy(nat.nat_cnam, "POGO");
     strcpy(nat.nat_pnam, "peter");
@@ -147,7 +145,6 @@ main(int argc, char *argv[])
     nat.nat_flags |= NF_FLASH;
     ef_write(EF_NATION, 0, &nat);
     printf("All praise to %s!\n", nat.nat_cnam);
-    ef_extend(EF_REALM, MAXNOC * MAXNOR);
     if (mkdir(teldir, S_IRWXU | S_IRWXG) < 0 && errno != EEXIST) {
        perror(teldir);
        printf("Can't make telegram directory\n");
@@ -159,10 +156,6 @@ main(int argc, char *argv[])
     }
     close(creat(annfil, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
 
-    ef_extend(EF_SECTOR, WORLD_SZ());
-    ef_extend(EF_MAP, MAXNOC);
-    ef_extend(EF_BMAP, MAXNOC);
-
     for (i = 0; i < EF_MAX; i++) {
        if (!EF_IS_GAME_STATE(i))
            continue;