1*397ddb8aSnicm /* $OpenBSD: worklist.c,v 1.8 2015/11/05 09:48:21 nicm Exp $ */
2d2852796Sjoris /*
3d2852796Sjoris * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
4d2852796Sjoris * All rights reserved.
5d2852796Sjoris *
6d2852796Sjoris * Redistribution and use in source and binary forms, with or without
7d2852796Sjoris * modification, are permitted provided that the following conditions
8d2852796Sjoris * are met:
9d2852796Sjoris *
10d2852796Sjoris * 1. Redistributions of source code must retain the above copyright
11d2852796Sjoris * notice, this list of conditions and the following disclaimer.
12d2852796Sjoris * 2. The name of the author may not be used to endorse or promote products
13d2852796Sjoris * derived from this software without specific prior written permission.
14d2852796Sjoris *
15d2852796Sjoris * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16d2852796Sjoris * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17d2852796Sjoris * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18d2852796Sjoris * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19d2852796Sjoris * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20d2852796Sjoris * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21d2852796Sjoris * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22d2852796Sjoris * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23d2852796Sjoris * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24d2852796Sjoris * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25d2852796Sjoris */
26d2852796Sjoris
27*397ddb8aSnicm #include <stdlib.h>
281f8531bdSotto #include <string.h>
291f8531bdSotto #include <unistd.h>
30d2852796Sjoris
311f8531bdSotto #include "cvs.h"
32d2852796Sjoris
33d2852796Sjoris /*
34f846f452Sniallo * adds a path to a worklist.
35d2852796Sjoris */
36d2852796Sjoris void
worklist_add(const char * path,struct wklhead * worklist)377a9e6d11Sray worklist_add(const char *path, struct wklhead *worklist)
38d2852796Sjoris {
39d2852796Sjoris size_t len;
407a9e6d11Sray struct worklist *wkl;
41d2852796Sjoris sigset_t old, new;
42d2852796Sjoris
433b4c5c25Sray wkl = xcalloc(1, sizeof(*wkl));
44d2852796Sjoris
45d2852796Sjoris len = strlcpy(wkl->wkl_path, path, sizeof(wkl->wkl_path));
46d2852796Sjoris if (len >= sizeof(wkl->wkl_path))
477a9e6d11Sray fatal("path truncation in worklist_add");
48d2852796Sjoris
49d2852796Sjoris sigfillset(&new);
50d2852796Sjoris sigprocmask(SIG_BLOCK, &new, &old);
51d2852796Sjoris SLIST_INSERT_HEAD(worklist, wkl, wkl_list);
52d2852796Sjoris sigprocmask(SIG_SETMASK, &old, NULL);
53d2852796Sjoris }
54d2852796Sjoris
55d2852796Sjoris /*
56d2852796Sjoris * run over the given worklist, calling cb for each element.
577a9e6d11Sray * this is just like worklist_clean(), except we block signals first.
58d2852796Sjoris */
59d2852796Sjoris void
worklist_run(struct wklhead * list,void (* cb)(struct worklist *))607a9e6d11Sray worklist_run(struct wklhead *list, void (*cb)(struct worklist *))
61d2852796Sjoris {
62d2852796Sjoris sigset_t old, new;
637a9e6d11Sray struct worklist *wkl;
64d2852796Sjoris
65d2852796Sjoris sigfillset(&new);
66d2852796Sjoris sigprocmask(SIG_BLOCK, &new, &old);
67d2852796Sjoris
687a9e6d11Sray worklist_clean(list, cb);
69d2852796Sjoris
706ecffe12Sjoris while ((wkl = SLIST_FIRST(list)) != NULL) {
716ecffe12Sjoris SLIST_REMOVE_HEAD(list, wkl_list);
72*397ddb8aSnicm free(wkl);
736ecffe12Sjoris }
746ecffe12Sjoris
75d2852796Sjoris sigprocmask(SIG_SETMASK, &old, NULL);
76d2852796Sjoris }
77d2852796Sjoris
78d2852796Sjoris /*
796ecffe12Sjoris * pass elements to the specified callback, which has to be signal safe.
80d2852796Sjoris */
81d2852796Sjoris void
worklist_clean(struct wklhead * list,void (* cb)(struct worklist *))827a9e6d11Sray worklist_clean(struct wklhead *list, void (*cb)(struct worklist *))
83d2852796Sjoris {
847a9e6d11Sray struct worklist *wkl;
85d2852796Sjoris
86aac69026Sniallo SLIST_FOREACH(wkl, list, wkl_list)
87d2852796Sjoris cb(wkl);
88d2852796Sjoris }
89d2852796Sjoris
90d2852796Sjoris void
worklist_unlink(struct worklist * wkl)917a9e6d11Sray worklist_unlink(struct worklist *wkl)
92d2852796Sjoris {
93d2852796Sjoris (void)unlink(wkl->wkl_path);
94d2852796Sjoris }
95