xref: /openbsd-src/usr.bin/cvs/worklist.c (revision 397ddb8a3f80a7c0fc96b9834bf9a6841845ed3c)
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