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