summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-09-09 12:24:37 +0100
committerColin Watson <cjwatson@debian.org>2014-09-11 12:53:28 +0100
commit8cabdfbf42bdb94bdc500ae4463d0e498349946f (patch)
tree1a5153560a87ceecfde9048d862c185a63efe267
parentd9ebedad152816ea2ee8725a0ee1b0f80f7aeb46 (diff)
Use high-precision timestamps for manual pages
* lib/util.c (is_changed): Compare high-precision timestamps. * libdb/db_storage.h (FIELDS): Increment to 10. (struct mandata): Change "time_t _st_mtime" to "struct timespec mtime". * libdb/db_lookup.c (dbprintf): Update mtime display. (split_content): Store two fields for the mtime (seconds and nanoseconds). (make_content): Expect two fields for the mtime. * libdb/db_store.c (replace_if_necessary): Compare high-precision timestamps. * src/check_mandirs.c (test_manfile): Likewise. * src/man.c (maybe_update_file): Likewise. * src/straycats.c (check_for_stray): Update initialisation of struct mandata. * src/tests/testlib.sh (accessdb_filter): Adjust for new format. * manual/db.me (Contents of an index database): Describe new format. (Example database): Update example output. * NEWS: Document this.
-rw-r--r--NEWS3
-rw-r--r--lib/util.c5
-rw-r--r--libdb/db_lookup.c12
-rw-r--r--libdb/db_storage.h6
-rw-r--r--libdb/db_store.c5
-rw-r--r--manual/db.me33
-rw-r--r--src/check_mandirs.c6
-rw-r--r--src/man.c10
-rw-r--r--src/straycats.c3
-rw-r--r--src/tests/testlib.sh2
10 files changed, 53 insertions, 32 deletions
diff --git a/NEWS b/NEWS
index 71f52191..53e9880f 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,9 @@ Major changes since man-db 2.6.7.1:
high-precision timestamps to determine whether it needs to update
databases.
+ o Timestamps of manual pages are also now stored in the database
+ with high precision and compared accordingly.
+
man-db 2.6.7.1 (10 April 2014)
==============================
diff --git a/lib/util.c b/lib/util.c
index 978a16e4..faa5d643 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -44,6 +44,8 @@
#include <unistd.h>
#include <locale.h>
+#include "stat-time.h"
+#include "timespec.h"
#include "xvasprintf.h"
#include "gettext.h"
@@ -97,7 +99,8 @@ int is_changed (const char *fa, const char *fb)
if (fb_sb.st_size == 0)
status |= 4;
- status |= (fa_sb.st_mtime != fb_sb.st_mtime);
+ status |= (timespec_cmp (get_stat_mtime (&fa_sb),
+ get_stat_mtime (&fb_sb)) != 0);
debug (" (%d)\n", status);
return status;
diff --git a/libdb/db_lookup.c b/libdb/db_lookup.c
index 6a4c675b..cca1b887 100644
--- a/libdb/db_lookup.c
+++ b/libdb/db_lookup.c
@@ -110,13 +110,13 @@ void dbprintf (const struct mandata *info)
"section: %s\n"
"comp. ext: %s\n"
"id: %c\n"
- "st_mtime %ld\n"
+ "mtime: %ld.%09ld\n"
"pointer: %s\n"
"filter: %s\n"
"whatis: %s\n\n",
dash_if_unset (info->name),
info->ext, info->sec, info->comp,
- info->id, (long) info->_st_mtime,
+ info->id, (long) info->mtime.tv_sec, info->mtime.tv_nsec,
info->pointer, info->filter, info->whatis);
}
@@ -210,7 +210,8 @@ void split_content (char *cont_ptr, struct mandata *pinfo)
pinfo->name = copy_if_set (*(data++));
pinfo->ext = *(data++);
pinfo->sec = *(data++);
- pinfo->_st_mtime = (time_t) atol (*(data++)); /* time_t format */
+ pinfo->mtime.tv_sec = (time_t) atol (*(data++));
+ pinfo->mtime.tv_nsec = atol (*(data++));
pinfo->id = **(data++); /* single char id */
pinfo->pointer = *(data++);
pinfo->filter = *(data++);
@@ -239,11 +240,12 @@ datum make_content (struct mandata *in)
in->whatis = dash + 1;
MYDBM_SET (cont, xasprintf (
- "%s\t%s\t%s\t%ld\t%c\t%s\t%s\t%s\t%s",
+ "%s\t%s\t%s\t%ld\t%ld\t%c\t%s\t%s\t%s\t%s",
dash_if_unset (in->name),
in->ext,
in->sec,
- (long) in->_st_mtime,
+ (long) in->mtime.tv_sec,
+ in->mtime.tv_nsec,
in->id,
in->pointer,
in->filter,
diff --git a/libdb/db_storage.h b/libdb/db_storage.h
index a8ef5c16..7495768f 100644
--- a/libdb/db_storage.h
+++ b/libdb/db_storage.h
@@ -43,9 +43,9 @@
#define STRAY_CAT 'D'
#define WHATIS_CAT 'E'
-#define FIELDS 9 /* No of fields in each database page `content' */
+#define FIELDS 10 /* No of fields in each database page `content' */
-#include "sys/time.h" /* for time_t */
+#include "timespec.h"
#include "xalloc.h"
@@ -68,7 +68,7 @@ struct mandata {
const char *comp; /* Compression extension */
const char *filter; /* filters needed for the page */
const char *whatis; /* whatis description for page */
- time_t _st_mtime; /* mod time for file */
+ struct timespec mtime; /* mod time for file */
};
/* used by the world */
diff --git a/libdb/db_store.c b/libdb/db_store.c
index 7c7a13f0..ac996f6f 100644
--- a/libdb/db_store.c
+++ b/libdb/db_store.c
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <unistd.h>
+#include "timespec.h"
#include "xvasprintf.h"
#include "gettext.h"
@@ -89,7 +90,7 @@ static int replace_if_necessary (struct mandata *newdata,
* exists should always take precedence.
*/
if (compare_ids (newdata->id, olddata->id, 1) <= 0 &&
- newdata->_st_mtime > olddata->_st_mtime) {
+ timespec_cmp (newdata->mtime, olddata->mtime) > 0) {
debug ("replace_if_necessary(): newer mtime; replacing\n");
if (MYDBM_REPLACE (dbf, newkey, newcont))
gripe_replace_key (MYDBM_DPTR (newkey));
@@ -138,7 +139,7 @@ static int replace_if_necessary (struct mandata *newdata,
If we have two ULT_MAN pages competing for the same key, we must have
more than one of foo.sec, foo.sec.comp1, foo.sec.comp2. OR we have a
- replacement page. If the st_mtimes differ, throw out the old struct and
+ replacement page. If the mtimes differ, throw out the old struct and
replace it with the new, if the comp exts differ, oops, this is bad,
keep one and return appropriate error code.
diff --git a/manual/db.me b/manual/db.me
index 5430bd97..35d99e3c 100644
--- a/manual/db.me
+++ b/manual/db.me
@@ -101,7 +101,7 @@ In the following entries, the character
will be used to separate the fields. In reality a tab is used.
Direct and indirect entries takes the form:
.ip
-.i "<name> \(-> <realname>|<ext>|<sec>|<mtime>|<ID>|<ref>|<filter>|<comp>|<whatis>"
+.i "<name> \(-> <realname>|<ext>|<sec>|<mtime.sec>|<mtime.nsec>|<ID>|<ref>|<filter>|<comp>|<whatis>"
.lp
Common name index entries take the form:
.ip
@@ -109,7 +109,7 @@ Common name index entries take the form:
.lp
and common name direct or indirect entries take the form:
.ip
-.i "<name>|<ext> \(-> <realname>|<ext>|<sec>|<mtime>|<ID>|<ref>|<filter>|<comp>|<whatis>"
+.i "<name>|<ext> \(-> <realname>|<ext>|<sec>|<mtime.sec>|<mtime.nsec>|<ID>|<ref>|<filter>|<comp>|<whatis>"
.lp
where in each case the filename being represented is formed as
.ip
@@ -126,8 +126,12 @@ If any of the fields would be empty, a single
is stored in its place.
.i <comp>
represents the compression extension,
-.i <mtime>
-is an integer representing the last modification time of the manual page,
+.i <mtime.sec>
+is an integer representing the seconds part of the last modification
+time of the manual page,
+.i <mtime.nsec>
+is an integer representing the nanoseconds part of the last modification
+time of the manual page,
.i <ref>
points to the entry containing the location of the real page,
.i <ID>
@@ -211,15 +215,18 @@ from the top level build directory is included below.
.lp
.nf
$version$ -> "2.5.0"
-apropos -> "1 1 795981542 A - - search the manual page names and descriptions"
-catman -> "8 8 795981544 A - - create or update the pre-formatted manual pages"
-man -> "1 1 795981542 A - - an interface to the on-line reference manuals"
-mandb -> "8 8 795981544 A - - create or update the manual page index caches"
-manpath -> " 1 5"
-manpath~1 -> "1 1 795981542 A - - determine search path for manual pages"
-manpath~5 -> "5 5 795981543 A - - format of the /etc/man_db.config file"
-whatis -> "1 1 795981543 A - - search the manual page names"
-zsoelim -> "1 1 795981543 A - - satisfy .so requests in roff input"
+accessdb -> "- 8 8 1410381979 324541691 A - - - dumps the content of a man-db database in a human readable format"
+apropos -> "- 1 1 1410381979 268541692 A - - - search the manual page names and descriptions"
+catman -> "- 8 8 1410381979 328541691 A - - - create or update the pre-formatted manual pages"
+lexgrog -> "- 1 1 1410381979 268541692 A - - - parse header information in man pages"
+man -> "- 1 1 1410381979 280541692 A - t - an interface to the on-line reference manuals"
+manconv -> "- 1 1 1410381979 272541692 A - - - convert manual page from one encoding to another"
+mandb -> "- 8 8 1410381979 324541691 A - t - create or update the manual page index caches"
+manpath -> " manpath 5 manpath 1"
+manpath~1 -> "- 1 1 1410381979 300541691 A - - - determine search path for manual pages"
+manpath~5 -> "- 5 5 1410381979 304541691 A - - - format of the /etc/manpath.config file"
+whatis -> "- 1 1 1410381979 300541691 A - - - display one-line manual page descriptions"
+zsoelim -> "- 1 1 1410381979 304541691 A - - - satisfy .so requests in roff input"
.fi
.BS 2 "Database types"
.lp
diff --git a/src/check_mandirs.c b/src/check_mandirs.c
index 8941c3a0..42259946 100644
--- a/src/check_mandirs.c
+++ b/src/check_mandirs.c
@@ -158,7 +158,7 @@ void test_manfile (const char *file, const char *path)
/* to get mtime info */
(void) lstat (file, &buf);
- info._st_mtime = buf.st_mtime;
+ info.mtime = get_stat_mtime (&buf);
/* check that our file actually contains some data */
if (buf.st_size == 0) {
@@ -179,8 +179,8 @@ void test_manfile (const char *file, const char *path)
*/
if (exists) {
if (strcmp (exists->comp, info.comp ? info.comp : "-") == 0) {
- if (exists->_st_mtime == info._st_mtime
- && exists->id < WHATIS_MAN) {
+ if (timespec_cmp (exists->mtime, info.mtime) == 0 &&
+ exists->id < WHATIS_MAN) {
free_mandata_struct (exists);
free (manpage);
return;
diff --git a/src/man.c b/src/man.c
index 03fd9bc8..eb81ab0b 100644
--- a/src/man.c
+++ b/src/man.c
@@ -3528,6 +3528,7 @@ static int maybe_update_file (const char *manpath, const char *name,
const char *real_name;
char *file;
struct stat buf;
+ struct timespec file_mtime;
int status;
if (!update)
@@ -3548,11 +3549,14 @@ static int maybe_update_file (const char *manpath, const char *name,
return 0;
if (lstat (file, &buf) != 0)
return 0;
- if (buf.st_mtime == info->_st_mtime)
+ file_mtime = get_stat_mtime (&buf);
+ if (timespec_cmp (file_mtime, info->mtime) == 0)
return 0;
- debug ("%s needs to be recached: %ld %ld\n",
- file, (long) info->_st_mtime, (long) buf.st_mtime);
+ debug ("%s needs to be recached: %ld.%09ld %ld.%09ld\n",
+ file,
+ (long) info->mtime.tv_sec, info->mtime.tv_nsec,
+ (long) file_mtime.tv_sec, file_mtime.tv_nsec);
status = run_mandb (0, manpath, file);
if (status)
error (0, 0, _("mandb command failed with exit status %d"),
diff --git a/src/straycats.c b/src/straycats.c
index 349d57b3..a7a74448 100644
--- a/src/straycats.c
+++ b/src/straycats.c
@@ -207,7 +207,8 @@ static int check_for_stray (void)
info.id = STRAY_CAT;
info.pointer = NULL;
info.filter = "-";
- info._st_mtime = 0L;
+ info.mtime.tv_sec = 0;
+ info.mtime.tv_nsec = 0;
drop_effective_privs ();
decomp = decompress_open (catdir);
diff --git a/src/tests/testlib.sh b/src/tests/testlib.sh
index fc4498fe..7ca11e00 100644
--- a/src/tests/testlib.sh
+++ b/src/tests/testlib.sh
@@ -61,7 +61,7 @@ EOF
accessdb_filter () {
# e.g. 'test -> "- 1 1 1250702063 A - - gz simple mandb test"'
run $ACCESSDB "$1" | grep -v '^\$' | \
- sed 's/\(-> "[^ ][^ ]* [^ ][^ ]* [^ ][^ ]* \)[^ ][^ ]* /\1MTIME /'
+ sed 's/\(-> "[^ ][^ ]* [^ ][^ ]* [^ ][^ ]* \)[^ ][^ ]* [^ ][^ ]* /\1MTIME /'
}
next_second () {