hash: Trivial whitespace cleanups.
[mLib] / fwatch.c
1 /* -*-c-*-
2 *
3 * $Id: fwatch.c,v 1.2 2004/04/08 01:36:11 mdw Exp $
4 *
5 * Watch a file for changes
6 *
7 * (c) 2001 Straylight/Edgeware
8 */
9
10 /*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of the mLib utilities library.
13 *
14 * mLib is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * mLib is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with mLib; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30 /*----- Header files ------------------------------------------------------*/
31
32 #include <errno.h>
33 #include <string.h>
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37
38 #include "fwatch.h"
39
40 /*----- Main code ---------------------------------------------------------*/
41
42 /* --- @doupdate@ --- *
43 *
44 * Arguments: @fwatch *f@ = pointer to an @fwatch@ structure
45 * @struct stat *st@ = pointer to file state
46 * @int err@ = whether there was an error
47 *
48 * Returns: Nonzero if the file has changed.
49 *
50 * Use: Updates the information in an @fwatch@ block.
51 */
52
53 static void copy(fwatch *f, struct stat *st)
54 {
55 f->dev = st->st_dev; f->ino = st->st_ino;
56 f->mtime = st->st_mtime; f->size = st->st_size;
57 f->mode = st->st_mode;
58 f->uid = st->st_uid; f->gid = st->st_gid;
59 }
60
61 static int doupdate(fwatch *f, struct stat *st, int err)
62 {
63 /* --- Fiddle with the error state --- *
64 *
65 * Only the presence or absence of error is interesting to someone wanting
66 * to read the file.
67 */
68
69 if (err)
70 err = errno;
71 if (err || f->err) {
72 if (!err != !f->err) {
73 f->err = err;
74 if (!err)
75 copy(f, st);
76 return (1);
77 }
78 return (0);
79 }
80
81 /* --- Check everything else --- */
82
83 if (st->st_dev != f->dev || st->st_ino != f->ino ||
84 st->st_mtime != f->mtime || st->st_size != f->size ||
85 st->st_mode != f->mode ||
86 st->st_uid != f->uid || st->st_gid != f->gid) {
87 copy(f, st);
88 return (1);
89 }
90 return (0);
91 }
92
93 /* --- @fwatch_init@, @fwatch_update@, etc --- *
94 *
95 * Arguments: @fwatch *f@ = pointer to an @fwatch@ structure
96 * @const char *name@ = name of the file to watch
97 * @int fd@ = a file descriptor to watch
98 *
99 * Returns: The @update@ functions return nonzero if the file has
100 * changed.
101 *
102 * Use: Stores information about a file which can be used to watch
103 * for changes. The structures may be freed without telling
104 * anyone.
105 */
106
107 void fwatch_init(fwatch *f, const char *name)
108 {
109 struct stat st;
110 memset(f, 0, sizeof(*f));
111 doupdate(f, &st, stat(name, &st));
112 }
113
114 void fwatch_initfd(fwatch *f, int fd)
115 {
116 struct stat st;
117 memset(f, 0, sizeof(*f));
118 doupdate(f, &st, fstat(fd, &st));
119 }
120
121 int fwatch_update(fwatch *f, const char *name)
122 {
123 struct stat st;
124 return (doupdate(f, &st, stat(name, &st)));
125 }
126
127 int fwatch_updatefd(fwatch *f, int fd)
128 {
129 struct stat st;
130 return (doupdate(f, &st, fstat(fd, &st)));
131 }
132
133 /*----- That's all, folks -------------------------------------------------*/