xref: /openbsd-src/usr.bin/cvs/worklist.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: worklist.c,v 1.6 2007/02/22 06:42:10 otto Exp $	*/
2 /*
3  * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <string.h>
28 #include <unistd.h>
29 
30 #include "cvs.h"
31 
32 /*
33  * adds a path to a worklist.
34  */
35 void
36 cvs_worklist_add(const char *path, struct cvs_wklhead *worklist)
37 {
38 	size_t len;
39 	struct cvs_worklist *wkl;
40 	sigset_t old, new;
41 
42 	wkl = xcalloc(1, sizeof(*wkl));
43 
44 	len = strlcpy(wkl->wkl_path, path, sizeof(wkl->wkl_path));
45 	if (len >= sizeof(wkl->wkl_path))
46 		fatal("path truncation in cvs_worklist_add");
47 
48 	sigfillset(&new);
49 	sigprocmask(SIG_BLOCK, &new, &old);
50 	SLIST_INSERT_HEAD(worklist, wkl, wkl_list);
51 	sigprocmask(SIG_SETMASK, &old, NULL);
52 }
53 
54 /*
55  * run over the given worklist, calling cb for each element.
56  * this is just like cvs_worklist_clean(), except we block signals first.
57  */
58 void
59 cvs_worklist_run(struct cvs_wklhead *list, void (*cb)(struct cvs_worklist *))
60 {
61 	sigset_t old, new;
62 	struct cvs_worklist *wkl;
63 
64 	sigfillset(&new);
65 	sigprocmask(SIG_BLOCK, &new, &old);
66 
67 	cvs_worklist_clean(list, cb);
68 
69 	while ((wkl = SLIST_FIRST(list)) != NULL) {
70 		SLIST_REMOVE_HEAD(list, wkl_list);
71 		xfree(wkl);
72 	}
73 
74 	sigprocmask(SIG_SETMASK, &old, NULL);
75 }
76 
77 /*
78  * pass elements to the specified callback, which has to be signal safe.
79  */
80 void
81 cvs_worklist_clean(struct cvs_wklhead *list, void (*cb)(struct cvs_worklist *))
82 {
83 	struct cvs_worklist *wkl;
84 
85 	SLIST_FOREACH(wkl, list, wkl_list)
86 	    cb(wkl);
87 }
88 
89 void
90 cvs_worklist_unlink(struct cvs_worklist *wkl)
91 {
92 	(void)unlink(wkl->wkl_path);
93 }
94