-
Notifications
You must be signed in to change notification settings - Fork 48
Implement sigtimedwait for use by suckless init #1320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 25 commits
a219223
7286e68
e07f7c1
6f5ad93
3d15ce3
1e3744d
1ce829f
000d730
2d7ca28
b386909
fb3eaa3
e41929e
7abe9f9
35a1ecc
c486015
bc5288f
7b0199c
239ca0e
da05dd4
54b38ef
1994eb2
b301a1c
ac3908b
51bbe9f
cbf8c25
29c302b
e597ef4
eff8b00
76ca8f1
c576c73
db00050
4088dd6
cdfc493
f7977d5
97d0591
f9014c9
a5fb873
0c30ce6
86c4f14
3c7670d
4b8edb8
65da74e
b4caf4b
d1df936
59d3c58
c3c4abd
cfab58a
78e955b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,13 @@ | ||
| #include <assert.h> | ||
| #include <signal.h> | ||
| #include <stdio.h> | ||
| #include <errno.h> | ||
| #include <unistd.h> | ||
| #include <sched.h> | ||
| #include <sys/wait.h> | ||
|
|
||
| #include "sys/errno.h" | ||
| #include "sys/signal.h" | ||
| #include "utest.h" | ||
| #include "util.h" | ||
|
|
||
|
|
@@ -287,6 +290,88 @@ int test_signal_sigsuspend(void) { | |
| return 0; | ||
| } | ||
|
|
||
| /* ======= signal_sigtimedwait ======= */ | ||
| int test_signal_sigtimedwait(void) { | ||
| pid_t ppid = getpid(); | ||
| signal(SIGCONT, sigcont_handler); | ||
| sigset_t set, current, waitset; | ||
| __sigemptyset(&set); | ||
| __sigaddset(&set, SIGUSR1); | ||
| __sigaddset(&set, SIGCONT); | ||
| assert(sigprocmask(SIG_SETMASK, &set, NULL) == 0); | ||
cahirwpz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| pid_t cpid = fork(); | ||
| if (cpid == 0) { | ||
| // for (int i = 0; i < 10; i++) { | ||
cahirwpz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // kill(ppid, SIGCONT); | ||
| // } | ||
| // sched_yield(); | ||
| kill(ppid, SIGUSR1); | ||
| return 0; | ||
| } | ||
|
|
||
| printf("Calling sigtimedwait()...\n"); | ||
| siginfo_t info; | ||
| __sigemptyset(&waitset); | ||
| __sigaddset(&waitset, SIGUSR1); | ||
| assert(sigtimedwait(&waitset, &info, NULL) == SIGUSR1); | ||
cahirwpz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| assert(info.si_signo == SIGUSR1); | ||
| sigprocmask(SIG_BLOCK, NULL, ¤t); | ||
| assert(__sigsetequal(&set, ¤t)); | ||
|
|
||
| printf("Waiting for child...\n"); | ||
| int status; | ||
| wait(&status); | ||
| assert(WIFEXITED(status)); | ||
| assert(WEXITSTATUS(status) == 0); | ||
| return 0; | ||
| } | ||
|
|
||
| /* ======= signal_sigtimedwait_timeout ======= */ | ||
| static int sigusr2_handled = 0; | ||
|
|
||
| void sigtimedwait_timeout_sigusr2_handler(int signo) { | ||
|
||
| sigusr2_handled = 1; | ||
| } | ||
|
|
||
| int test_signal_sigtimedwait_timeout(void) { | ||
| pid_t ppid = getpid(); | ||
| signal(SIGCONT, sigcont_handler); | ||
| signal(SIGUSR2, sigtimedwait_timeout_sigusr2_handler); | ||
| sigset_t set, waitset; | ||
| __sigemptyset(&set); | ||
| __sigaddset(&set, SIGUSR1); | ||
| assert(sigprocmask(SIG_SETMASK, &set, NULL) == 0); | ||
| pid_t cpid = fork(); | ||
| if (cpid == 0) { | ||
| while (!sigusr2_handled) { | ||
| kill(ppid, SIGCONT); | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| printf("Calling sigtimedwait()...\n"); | ||
| siginfo_t info; | ||
| __sigemptyset(&waitset); | ||
| __sigaddset(&waitset, SIGUSR1); | ||
| timespec_t timeout = { | ||
| .tv_nsec = 10000000, | ||
| .tv_sec = 0, | ||
| }; | ||
| assert(sigtimedwait(&waitset, &info, &timeout) == -1); | ||
| assert(errno == EINTR); | ||
| kill(cpid, SIGUSR2); | ||
| nanosleep(&timeout, NULL); | ||
| assert(sigtimedwait(&waitset, &info, &timeout) == -1); | ||
| assert(errno == EAGAIN); | ||
|
|
||
| printf("Waiting for child...\n"); | ||
| int status; | ||
| wait(&status); | ||
| assert(WIFEXITED(status)); | ||
| assert(WEXITSTATUS(status) == 0); | ||
| return 0; | ||
| } | ||
|
|
||
| /* ======= signal_sigsuspend_stop ======= */ | ||
| int test_signal_sigsuspend_stop(void) { | ||
| pid_t ppid = getpid(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| #!/bin/ksh | ||
|
|
||
| umask 022 | ||
|
|
||
| echo " __ __ _ _ _ ____ _____ " | ||
| echo " | \/ (_) (_) | / __ \ / ____| " | ||
| echo " | \ / |_ _ __ ___ _| | _____ _ __| | | | (___ " | ||
| echo " | |\/| | | '_ \` _ \| | |/ / _ \ '__| | | |\___ \ " | ||
| echo " | | | | | | | | | | | < __/ | | |__| |____) | " | ||
| echo " |_| |_|_|_| |_| |_|_|_|\_\___|_| \____/|_____/ " | ||
| echo | ||
|
|
||
| exec /bin/ksh |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| #!/bin/ksh | ||
|
|
||
| echo "Shutdown not supported yet!" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| /* $NetBSD: sigwait.c,v 1.5 2012/03/20 16:26:12 matt Exp $ */ | ||
|
|
||
| /*- | ||
| * Copyright (c) 2003 The NetBSD Foundation, Inc. | ||
| * All rights reserved. | ||
| * | ||
| * This code is derived from software contributed to The NetBSD Foundation | ||
| * by Jaromir Dolecek. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | ||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
| * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | ||
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGE. | ||
| */ | ||
|
|
||
| #include <sys/cdefs.h> | ||
| #include <sys/types.h> | ||
| #include <sys/syscall.h> | ||
| #include <unistd.h> | ||
| #include <signal.h> | ||
| #include <errno.h> | ||
|
|
||
| /* | ||
| * This is wrapper around sigtimedwait(2), providing sigwait() | ||
| * implementation for userland. | ||
| */ | ||
| int | ||
| sigwait(const sigset_t * __restrict set, int * __restrict signum) | ||
| { | ||
| int saved_errno, new_errno, sig; | ||
|
|
||
| saved_errno = errno; | ||
| sig = sigtimedwait(set, NULL, NULL); | ||
| new_errno = errno; | ||
| errno = saved_errno; | ||
| if (sig < 0) | ||
| return (new_errno); | ||
| *signum = sig; | ||
| return (0); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # vim: tabstop=8 shiftwidth=8 noexpandtab: | ||
|
|
||
| TOPDIR = $(realpath ..) | ||
|
|
||
| SUBDIR = init | ||
|
|
||
| all: build | ||
|
|
||
| include $(TOPDIR)/build/common.mk |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| MIT/X Consortium License | ||
|
|
||
| © 2014-2015 Dimitris Papastamos <sin@2f30.org> | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a | ||
| copy of this software and associated documentation files (the "Software"), | ||
| to deal in the Software without restriction, including without limitation | ||
| the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| and/or sell copies of the Software, and to permit persons to whom the | ||
| Software is furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in | ||
| all copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| DEALINGS IN THE SOFTWARE. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| TOPDIR = $(realpath ../..) | ||
|
|
||
| PROGRAM = init | ||
| FORMAT-EXCLUDE = $(SOURCES) | ||
|
|
||
| include $(TOPDIR)/build/build.prog.mk |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| sinit - suckless init | ||
| ===================== | ||
|
|
||
| sinit is a simple init. It was initially based on | ||
| Rich Felker's minimal init[1]. | ||
|
|
||
| Why? | ||
| ---- | ||
|
|
||
| I wanted to get rid of Busybox init on my toy distro[2]. | ||
|
|
||
| How? | ||
| ---- | ||
|
|
||
| There are 3 signals that sinit will act on. | ||
|
|
||
| SIGUSR1: powers off the machine. | ||
| SIGINT: reboots the machine (or alternatively via ctrl-alt-del). | ||
| SIGCHLD: reap children | ||
|
|
||
| To see how sinit integrates with the init scripts, then have | ||
| a look at [3]. | ||
|
|
||
| [1] https://gist.github.com/rofl0r/6168719 | ||
| [2] http://git.2f30.org/morpheus/ | ||
| [3] http://git.2f30.org/ports/tree/fs/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| /* See LICENSE file for copyright and license details. */ | ||
|
|
||
| static char *const rcinitcmd[] = { "/etc/rc.init", NULL }; | ||
| static char *const rcrebootcmd[] = { "/etc/rc.shutdown", "reboot", NULL }; | ||
| static char *const rcpoweroffcmd[] = { "/etc/rc.shutdown", "poweroff", NULL }; |
Uh oh!
There was an error while loading. Please reload this page.