h_segv.c revision 1.1
11.1Schristos/*	$NetBSD: h_segv.c,v 1.1 2017/12/07 19:46:40 christos Exp $	*/
21.1Schristos
31.1Schristos/*-
41.1Schristos * Copyright (c) 2017 The NetBSD Foundation, Inc.
51.1Schristos * All rights reserved.
61.1Schristos *
71.1Schristos * This code is derived from software contributed to The NetBSD Foundation
81.1Schristos * by Christos Zoulas.
91.1Schristos *
101.1Schristos * Redistribution and use in source and binary forms, with or without
111.1Schristos * modification, are permitted provided that the following conditions
121.1Schristos * are met:
131.1Schristos * 1. Redistributions of source code must retain the above copyright
141.1Schristos *    notice, this list of conditions and the following disclaimer.
151.1Schristos * 2. Redistributions in binary form must reproduce the above copyright
161.1Schristos *    notice, this list of conditions and the following disclaimer in the
171.1Schristos *    documentation and/or other materials provided with the distribution.
181.1Schristos *
191.1Schristos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
201.1Schristos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
211.1Schristos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
221.1Schristos * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
231.1Schristos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
241.1Schristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
251.1Schristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
261.1Schristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
271.1Schristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281.1Schristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
291.1Schristos * POSSIBILITY OF SUCH DAMAGE.
301.1Schristos */
311.1Schristos#include <sys/cdefs.h>
321.1Schristos__RCSID("$NetBSD: h_segv.c,v 1.1 2017/12/07 19:46:40 christos Exp $");
331.1Schristos
341.1Schristos#include <stdio.h>
351.1Schristos#include <string.h>
361.1Schristos#include <stdlib.h>
371.1Schristos#include <unistd.h>
381.1Schristos#include <signal.h>
391.1Schristos#include <err.h>
401.1Schristos
411.1Schristos// A faulting address
421.1Schristosstatic int *p = (int *) 0xfefefef0;
431.1Schristos
441.1Schristosstatic int flags;
451.1Schristos#define F_RECURSE 	1
461.1Schristos#define F_HANDLE	2
471.1Schristos#define F_MASK		4
481.1Schristos
491.1Schristosstatic struct {
501.1Schristos	const char *n;
511.1Schristos	int v;
521.1Schristos} nv[] = {
531.1Schristos	{ "recurse",	F_RECURSE },
541.1Schristos	{ "handle",	F_HANDLE },
551.1Schristos	{ "mask",	F_MASK },
561.1Schristos};
571.1Schristos
581.1Schristosstatic void
591.1Schristosfoo(int s)
601.1Schristos{
611.1Schristos        char buf[64];
621.1Schristos        int i = snprintf(buf, sizeof(buf), "got %d\n", s);
631.1Schristos        write(2, buf, i);
641.1Schristos	if (flags & F_RECURSE)
651.1Schristos		*p = 0;
661.1Schristos        exit(EXIT_SUCCESS);
671.1Schristos}
681.1Schristos
691.1Schristosstatic __dead void
701.1Schristosusage(void)
711.1Schristos{
721.1Schristos	fprintf(stderr, "Usage: %s recurse|mask|unhandle ...\n", getprogname());
731.1Schristos	exit(EXIT_FAILURE);
741.1Schristos}
751.1Schristos
761.1Schristosint
771.1Schristosmain(int argc, char *argv[])
781.1Schristos{
791.1Schristos	if (argc == 1)
801.1Schristos	    usage();
811.1Schristos
821.1Schristos	for (int i = 1; i < argc; i++) {
831.1Schristos		size_t j;
841.1Schristos		for (j = 0; j < __arraycount(nv); j++)
851.1Schristos			if (strcmp(nv[j].n, argv[i]) == 0) {
861.1Schristos				flags |= nv[j].v;
871.1Schristos				break;
881.1Schristos			}
891.1Schristos		if (j == __arraycount(nv))
901.1Schristos			usage();
911.1Schristos	}
921.1Schristos
931.1Schristos	if (flags == 0)
941.1Schristos		usage();
951.1Schristos
961.1Schristos	if (flags & F_HANDLE) {
971.1Schristos		struct sigaction sa;
981.1Schristos
991.1Schristos		sa.sa_flags = SA_RESTART;
1001.1Schristos		sa.sa_handler = foo;
1011.1Schristos		sigemptyset(&sa.sa_mask);
1021.1Schristos		if (sigaction(SIGSEGV, &sa, NULL) == -1)
1031.1Schristos			err(EXIT_FAILURE, "sigaction");
1041.1Schristos	}
1051.1Schristos
1061.1Schristos	if (flags & F_MASK) {
1071.1Schristos		sigset_t set;
1081.1Schristos
1091.1Schristos		sigemptyset(&set);
1101.1Schristos		sigaddset(&set, SIGSEGV);
1111.1Schristos		if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
1121.1Schristos			err(EXIT_FAILURE, "sigprocmask");
1131.1Schristos	}
1141.1Schristos
1151.1Schristos        *p = 1;
1161.1Schristos	return EXIT_SUCCESS;
1171.1Schristos}
118