extern char *ef_nameof(int);
extern time_t ef_mtime(int);
extern int ef_open(int, int, int);
+extern int ef_open_view(int, int);
extern int ef_close(int);
extern int ef_flush(int);
extern void ef_blank(int, int, void *);
return 1;
}
+/*
+ * Open the table TYPE as view of table BASE.
+ * Return non-zero on success, zero on failure.
+ * Beware: views work only as long as BASE doesn't change size!
+ * You must call ef_close(TYPE) before closing BASE.
+ */
+int
+ef_open_view(int type, int base)
+{
+ struct empfile *ep;
+
+ if (CANT_HAPPEN(!EF_IS_VIEW(type)))
+ return -1;
+ ep = &empfile[type];
+ if (CANT_HAPPEN(!(ef_flags(base) & EFF_MEM)))
+ return -1;
+
+ ep->cache = empfile[base].cache;
+ ep->csize = empfile[base].csize;
+ ep->flags |= EFF_MEM;
+ ep->baseid = empfile[base].baseid;
+ ep->cids = empfile[base].cids;
+ ep->fids = empfile[base].fids;
+ return 0;
+}
+
/*
* Close the file-backed table TYPE (EF_SECTOR, ...).
* Return non-zero on success, zero on failure.
ef_close(int type)
{
struct empfile *ep;
- int retval;
+ int retval = 1;
- retval = ef_flush(type);
+ if (ef_check(type) < 0)
+ return 0;
ep = &empfile[type];
- ep->flags &= EFF_IMMUTABLE;
- if (!(ep->flags & EFF_STATIC)) {
- free(ep->cache);
+
+ if (EF_IS_VIEW(type))
ep->cache = NULL;
+ else {
+ if (!ef_flush(type))
+ retval = 0;
+ ep->flags &= EFF_IMMUTABLE;
+ if (!(ep->flags & EFF_STATIC)) {
+ free(ep->cache);
+ ep->cache = NULL;
+ }
+ if (close(ep->fd) < 0) {
+ logerror("Error closing %s (%s)", ep->file, strerror(errno));
+ retval = 0;
+ }
+ ep->fd = -1;
}
- if (close(ep->fd) < 0) {
- logerror("Error closing %s (%s)", ep->file, strerror(errno));
- retval = 0;
- }
- ep->fd = -1;
return retval;
}
/*
- * Flush table TYPE (EF_SECTOR, ...) to disk.
+ * Flush file-backed table TYPE (EF_SECTOR, ...) to its backing file.
* Do nothing if the table is privately mapped.
* Update timestamps of written elements if table is EFF_TYPED.
* Return non-zero on success, zero on failure.
char *p;
int need_sentinel, i, id;
- if (ef_check(type) < 0)
+ if (ef_check(type) < 0 || CANT_HAPPEN(EF_IS_VIEW(type)))
return 0;
ep = &empfile[type];
if (CANT_HAPPEN(count < 0))
struct empfile *ep;
int need_sentinel;
- if (ef_check(type) < 0)
+ if (ef_check(type) < 0 || CANT_HAPPEN(EF_IS_VIEW(type)))
return 0;
ep = &empfile[type];
if (CANT_HAPPEN(count < 0 || count > ep->fids))
static void ef_open_srv(void);
static void ef_close_srv(void);
-static int ef_init_view(int, int);
-static void ef_fina_view(int);
/*
* Initialize empfile for full server operations.
failed |= !ef_open(EF_LOST, 0, -1);
failed |= !ef_open(EF_REALM, EFF_MEM, MAXNOC * MAXNOR);
if (!failed)
- failed |= ef_init_view(EF_COUNTRY, EF_NATION);
+ failed |= ef_open_view(EF_COUNTRY, EF_NATION);
if (failed) {
logerror("Missing files, giving up");
exit(EXIT_FAILURE);
static void
ef_close_srv(void)
{
- ef_fina_view(EF_COUNTRY);
+ ef_close(EF_COUNTRY);
ef_close(EF_NATION);
ef_close(EF_SECTOR);
ef_close(EF_SHIP);
ef_close(EF_LOST);
ef_close(EF_REALM);
}
-
-static int
-ef_init_view(int type, int base)
-{
- if (CANT_HAPPEN(!(empfile[base].flags & EFF_MEM)))
- return -1;
- empfile[type].cache = empfile[base].cache;
- empfile[type].csize = empfile[base].csize;
- empfile[type].flags |= EFF_MEM;
- empfile[type].baseid = empfile[base].baseid;
- empfile[type].cids = empfile[base].cids;
- empfile[type].fids = empfile[base].fids;
- return 0;
-}
-
-static void
-ef_fina_view(int type)
-{
- empfile[type].cache = NULL;
-}