chiark / gitweb /
url: Allow `;' to separate key/value pairs in URL-encoded strings.
[mLib] / fwatch.c
CommitLineData
32e1147e 1/* -*-c-*-
2 *
8656dc50 3 * $Id: fwatch.c,v 1.2 2004/04/08 01:36:11 mdw Exp $
32e1147e 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
32e1147e 30/*----- Header files ------------------------------------------------------*/
31
32#include <errno.h>
b68d83ad 33#include <string.h>
32e1147e 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
53static 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
61static 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
107void 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
114void 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
121int fwatch_update(fwatch *f, const char *name)
122{
123 struct stat st;
124 return (doupdate(f, &st, stat(name, &st)));
125}
126
127int 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 -------------------------------------------------*/