xref: /openbsd-src/usr.bin/rcs/worklist.c (revision 8ac837e598fb9f435489728e1643b141b140cf77)
1*8ac837e5Snicm /*	$OpenBSD: worklist.c,v 1.4 2015/06/13 20:15:21 nicm Exp $	*/
22dc36bedSjoris /*
32dc36bedSjoris  * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
42dc36bedSjoris  * All rights reserved.
52dc36bedSjoris  *
62dc36bedSjoris  * Redistribution and use in source and binary forms, with or without
72dc36bedSjoris  * modification, are permitted provided that the following conditions
82dc36bedSjoris  * are met:
92dc36bedSjoris  *
102dc36bedSjoris  * 1. Redistributions of source code must retain the above copyright
112dc36bedSjoris  *    notice, this list of conditions and the following disclaimer.
122dc36bedSjoris  * 2. The name of the author may not be used to endorse or promote products
132dc36bedSjoris  *    derived from this software without specific prior written permission.
142dc36bedSjoris  *
152dc36bedSjoris  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
162dc36bedSjoris  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
172dc36bedSjoris  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
182dc36bedSjoris  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
192dc36bedSjoris  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
202dc36bedSjoris  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
212dc36bedSjoris  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
222dc36bedSjoris  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
232dc36bedSjoris  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
242dc36bedSjoris  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
252dc36bedSjoris  */
262dc36bedSjoris 
274781e2faSxsa #include <sys/queue.h>
284781e2faSxsa 
294781e2faSxsa #include <err.h>
304781e2faSxsa #include <signal.h>
31*8ac837e5Snicm #include <stdlib.h>
324781e2faSxsa #include <string.h>
334781e2faSxsa #include <unistd.h>
342dc36bedSjoris 
352dc36bedSjoris #include "worklist.h"
362dc36bedSjoris #include "xmalloc.h"
372dc36bedSjoris 
382dc36bedSjoris /*
392dc36bedSjoris  * adds a path to a worklist.
402dc36bedSjoris  */
412dc36bedSjoris void
worklist_add(const char * path,struct wklhead * worklist)427a9e6d11Sray worklist_add(const char *path, struct wklhead *worklist)
432dc36bedSjoris {
442dc36bedSjoris 	size_t len;
457a9e6d11Sray 	struct worklist *wkl;
462dc36bedSjoris 	sigset_t old, new;
472dc36bedSjoris 
482dc36bedSjoris 	wkl = xcalloc(1, sizeof(*wkl));
492dc36bedSjoris 
502dc36bedSjoris 	len = strlcpy(wkl->wkl_path, path, sizeof(wkl->wkl_path));
512dc36bedSjoris 	if (len >= sizeof(wkl->wkl_path))
527a9e6d11Sray 		errx(1, "path truncation in worklist_add");
532dc36bedSjoris 
542dc36bedSjoris 	sigfillset(&new);
552dc36bedSjoris 	sigprocmask(SIG_BLOCK, &new, &old);
562dc36bedSjoris 	SLIST_INSERT_HEAD(worklist, wkl, wkl_list);
572dc36bedSjoris 	sigprocmask(SIG_SETMASK, &old, NULL);
582dc36bedSjoris }
592dc36bedSjoris 
602dc36bedSjoris /*
612dc36bedSjoris  * run over the given worklist, calling cb for each element.
627a9e6d11Sray  * this is just like worklist_clean(), except we block signals first.
632dc36bedSjoris  */
642dc36bedSjoris void
worklist_run(struct wklhead * list,void (* cb)(struct worklist *))657a9e6d11Sray worklist_run(struct wklhead *list, void (*cb)(struct worklist *))
662dc36bedSjoris {
672dc36bedSjoris 	sigset_t old, new;
687a9e6d11Sray 	struct worklist *wkl;
692dc36bedSjoris 
702dc36bedSjoris 	sigfillset(&new);
712dc36bedSjoris 	sigprocmask(SIG_BLOCK, &new, &old);
722dc36bedSjoris 
737a9e6d11Sray 	worklist_clean(list, cb);
742dc36bedSjoris 
752dc36bedSjoris 	while ((wkl = SLIST_FIRST(list)) != NULL) {
762dc36bedSjoris 		SLIST_REMOVE_HEAD(list, wkl_list);
77*8ac837e5Snicm 		free(wkl);
782dc36bedSjoris 	}
792dc36bedSjoris 
802dc36bedSjoris 	sigprocmask(SIG_SETMASK, &old, NULL);
812dc36bedSjoris }
822dc36bedSjoris 
832dc36bedSjoris /*
842dc36bedSjoris  * pass elements to the specified callback, which has to be signal safe.
852dc36bedSjoris  */
862dc36bedSjoris void
worklist_clean(struct wklhead * list,void (* cb)(struct worklist *))877a9e6d11Sray worklist_clean(struct wklhead *list, void (*cb)(struct worklist *))
882dc36bedSjoris {
897a9e6d11Sray 	struct worklist *wkl;
902dc36bedSjoris 
912dc36bedSjoris 	SLIST_FOREACH(wkl, list, wkl_list)
922dc36bedSjoris 	    cb(wkl);
932dc36bedSjoris }
942dc36bedSjoris 
952dc36bedSjoris void
worklist_unlink(struct worklist * wkl)967a9e6d11Sray worklist_unlink(struct worklist *wkl)
972dc36bedSjoris {
982dc36bedSjoris 	(void)unlink(wkl->wkl_path);
992dc36bedSjoris }
100