chiark / gitweb /
New feature: watch a file for changes.
authormdw <mdw>
Sat, 3 Feb 2001 18:43:59 +0000 (18:43 +0000)
committermdw <mdw>
Sat, 3 Feb 2001 18:43:59 +0000 (18:43 +0000)
Makefile.am
fwatch.c [new file with mode: 0644]
fwatch.h [new file with mode: 0644]
man/.cvsignore
man/fwatch.3 [new file with mode: 0644]
man/mLib.3

index e5f3753..ded3be5 100644 (file)
@@ -1,6 +1,6 @@
 ## -*-Makefile-*-
 ##
-## $Id: Makefile.am,v 1.30 2001/01/25 21:11:41 mdw Exp $
+## $Id: Makefile.am,v 1.31 2001/02/03 18:43:56 mdw Exp $
 ##
 ## Building the distribution
 ##
@@ -29,6 +29,9 @@
 ##----- Revision history ----------------------------------------------------
 ##
 ## $Log: Makefile.am,v $
+## Revision 1.31  2001/02/03 18:43:56  mdw
+## New feature: watch a file for changes.
+##
 ## Revision 1.30  2001/01/25 21:11:41  mdw
 ## Use `$(MAKE)' in the `install-man' rule, so that the jobserver doesn't
 ## whinge.
@@ -118,7 +121,7 @@ pkginclude_HEADERS = \
        alloc.h arena.h bits.h exc.h quis.h report.h sub.h trace.h track.h \
        pool.h \
        atom.h assoc.h darray.h dstr.h dspool.h hash.h sym.h crc32.h \
-       env.h fdflags.h lock.h \
+       env.h fdflags.h fwatch.h lock.h \
        bres.h conn.h lbuf.h ident.h pkbuf.h sel.h selbuf.h selpk.h sig.h \
        tv.h \
        base64.h mdwopt.h str.h testrig.h url.h
@@ -135,7 +138,7 @@ libmLib_la_SOURCES = \
        pool.c pool-file.c pool-sub.c \
        atom.c assoc.c darray.c dstr.c dputf.c dspool.c hash.c sym.c \
        crc32.c crc32-tab.c \
-       env.c fdflags.c lock.c \
+       env.c fdflags.c fwatch.c lock.c \
        bres.c conn.c lbuf.c ident.c pkbuf.c sel.c selbuf.c selpk.c sig.c \
        tv.c \
        base64.c mdwopt.c str.c testrig.c url.c
diff --git a/fwatch.c b/fwatch.c
new file mode 100644 (file)
index 0000000..ecf945a
--- /dev/null
+++ b/fwatch.c
@@ -0,0 +1,140 @@
+/* -*-c-*-
+ *
+ * $Id: fwatch.c,v 1.1 2001/02/03 18:43:56 mdw Exp $
+ *
+ * Watch a file for changes
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of the mLib utilities library.
+ *
+ * mLib is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ * 
+ * mLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with mLib; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: fwatch.c,v $
+ * Revision 1.1  2001/02/03 18:43:56  mdw
+ * New feature: watch a file for changes.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "fwatch.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @doupdate@ --- *
+ *
+ * Arguments:  @fwatch *f@ = pointer to an @fwatch@ structure
+ *             @struct stat *st@ = pointer to file state
+ *             @int err@ = whether there was an error
+ *
+ * Returns:    Nonzero if the file has changed.
+ *
+ * Use:                Updates the information in an @fwatch@ block.
+ */
+
+static void copy(fwatch *f, struct stat *st)
+{
+  f->dev = st->st_dev; f->ino = st->st_ino;
+  f->mtime = st->st_mtime; f->size = st->st_size;
+  f->mode = st->st_mode;
+  f->uid = st->st_uid; f->gid = st->st_gid;
+}
+
+static int doupdate(fwatch *f, struct stat *st, int err)
+{
+  /* --- Fiddle with the error state --- *
+   *
+   * Only the presence or absence of error is interesting to someone wanting
+   * to read the file.
+   */
+
+  if (err)
+    err = errno;
+  if (err || f->err) {
+    if (!err != !f->err) {
+      f->err = err;
+      if (!err)
+       copy(f, st);
+      return (1);
+    }
+    return (0);
+  }
+
+  /* --- Check everything else --- */
+
+  if (st->st_dev != f->dev || st->st_ino != f->ino ||
+      st->st_mtime != f->mtime || st->st_size != f->size ||
+      st->st_mode != f->mode ||
+      st->st_uid != f->uid || st->st_gid != f->gid) {
+    copy(f, st);
+    return (1);
+  }
+  return (0);
+}
+
+/* --- @fwatch_init@, @fwatch_update@, etc --- *
+ *
+ * Arguments:  @fwatch *f@ = pointer to an @fwatch@ structure
+ *             @const char *name@ = name of the file to watch
+ *             @int fd@ = a file descriptor to watch
+ *
+ * Returns:    The @update@ functions return nonzero if the file has
+ *             changed.
+ *
+ * Use:                Stores information about a file which can be used to watch
+ *             for changes.  The structures may be freed without telling
+ *             anyone.
+ */
+
+void fwatch_init(fwatch *f, const char *name)
+{
+  struct stat st;
+  memset(f, 0, sizeof(*f));
+  doupdate(f, &st, stat(name, &st));
+}
+
+void fwatch_initfd(fwatch *f, int fd)
+{
+  struct stat st;
+  memset(f, 0, sizeof(*f));
+  doupdate(f, &st, fstat(fd, &st));
+}
+
+int fwatch_update(fwatch *f, const char *name)
+{
+  struct stat st;
+  return (doupdate(f, &st, stat(name, &st)));
+}
+
+int fwatch_updatefd(fwatch *f, int fd)
+{
+  struct stat st;
+  return (doupdate(f, &st, fstat(fd, &st)));
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/fwatch.h b/fwatch.h
new file mode 100644 (file)
index 0000000..1a0898a
--- /dev/null
+++ b/fwatch.h
@@ -0,0 +1,90 @@
+/* -*-c-*-
+ *
+ * $Id: fwatch.h,v 1.1 2001/02/03 18:43:56 mdw Exp $
+ *
+ * Watch a file for changes
+ *
+ * (c) 2001 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of the mLib utilities library.
+ *
+ * mLib is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ * 
+ * mLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with mLib; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: fwatch.h,v $
+ * Revision 1.1  2001/02/03 18:43:56  mdw
+ * New feature: watch a file for changes.
+ *
+ */
+
+#ifndef MLIB_FWATCH_H
+#define MLIB_FWATCH_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/*----- Data structures ---------------------------------------------------*/
+
+typedef struct fwatch {
+  int err;
+  dev_t dev;
+  ino_t ino;
+  time_t mtime;
+  off_t size;
+  mode_t mode;
+  uid_t uid;
+  gid_t gid;
+} fwatch;
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @fwatch_init@, @fwatch_update@, etc --- *
+ *
+ * Arguments:  @fwatch *f@ = pointer to an @fwatch@ structure
+ *             @const char *name@ = name of the file to watch
+ *             @int fd@ = a file descriptor to watch
+ *
+ * Returns:    The @update@ functions return nonzero if the file has
+ *             changed.
+ *
+ * Use:                Stores information about a file which can be used to watch
+ *             for changes.  The structures may be freed without telling
+ *             anyone.
+ */
+
+extern void fwatch_init(fwatch */*f*/, const char */*name*/);
+extern void fwatch_initfd(fwatch */*f*/, int /*fd*/);
+extern int fwatch_update(fwatch */*f*/, const char */*name*/);
+extern int fwatch_updatefd(fwatch */*f*/, int /*fd*/);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
index 6b9f144..f80f4ab 100644 (file)
@@ -169,6 +169,10 @@ env_get.3
 env_import.3
 env_put.3
 exc_uncaught.3
+fwatch_init.3
+fwatch_initfd.3
+fwatch_update.3
+fwatch_updatefd.3
 hash_bin.3
 hash_create.3
 hash_destroy.3
diff --git a/man/fwatch.3 b/man/fwatch.3
new file mode 100644 (file)
index 0000000..a22e031
--- /dev/null
@@ -0,0 +1,41 @@
+.\" -*-nroff-*-
+.TH fwatch 3 "3 February 2001" mLib
+.SH NAME
+fwatch \- watch a file for changes
+.\" @fwatch_init
+.\" @fwatch_initfd
+.\" @fwatch_update
+.\" @fwatch_updatefd
+.SH SYNOPSIS
+.nf
+.B "#include <mLib/fwatch.h>"
+
+.BI "void fwatch_init(fwatch *" f ", const char *" name );
+.BI "void fwatch_initfd(fwatch *" f ", int " fd );
+.BI "int fwatch_update(fwatch *" f ", const char *" name );
+.BI "int fwatch_updatefd(fwatch *" f ", int " fd );
+.fi
+.SH DESCRIPTION
+These functions watch a file for changes.  Use
+.B fwatch_init
+or
+.B fwatch_initfd
+to initialize a
+.B fwatch
+block with information about a file; then later, the functions
+.B fwatch_update
+and
+.B fwatch_updatefd
+will update the information in the structure and inform you whether the
+file changed.
+.PP
+The
+.B fwatch
+functions can't return errors: they remember errors as part of the file
+state instead.  The
+.B update
+functions return zero if the file has not changed or nonzero if it has.
+.SH SEE ALSO
+.BR mLib (3).
+.SH AUTHOR
+Mark Wooding, <mdw@nsict.org>
index f109d19..0796883 100644 (file)
@@ -167,6 +167,11 @@ The
 module manipulates file descriptor flags in a fairly painless way.
 .PP
 The
+.BR fwatch (3)
+module allows you to easily find out whether a file has changed since
+the last time you looked at it.
+.PP
+The
 .BR lbuf (3)
 module implements a `line buffer', which is an object that emits
 completed lines of text from an incoming asynchronous data stream.  It's
@@ -261,6 +266,7 @@ module does background hostname and address resolution.
 .BR env (3),
 .BR exc (3),
 .BR fdflags (3),
+.BR fwatch (3),
 .BR hash (3),
 .BR ident (3),
 .BR lbuf (3),