Make a simple sleep clone
This commit is contained in:
19
exercises/coreutils/sleep/Makefile
Normal file
19
exercises/coreutils/sleep/Makefile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
CC := gcc
|
||||||
|
CFLAGS := -Wall -Wextra -pedantic -std=c11 -pthread -g
|
||||||
|
TARGET := sleep
|
||||||
|
SRC := main.c
|
||||||
|
OBJS := $(SRC:.c=.o)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CC) $(CFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(TARGET) $(OBJS)
|
||||||
|
|
||||||
58
exercises/coreutils/sleep/main.c
Normal file
58
exercises/coreutils/sleep/main.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static void alarm_handler(int, siginfo_t *, void *);
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct sigaction act, old_act;
|
||||||
|
sigset_t newmask, oldmask, suspmask;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "Usage: %s SECONDS", argv[0]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int timeout = (unsigned int)strtol(argv[1], (char **)NULL, 10);
|
||||||
|
|
||||||
|
sigemptyset(&act.sa_mask);
|
||||||
|
act.sa_flags = 0;
|
||||||
|
act.sa_sigaction = alarm_handler;
|
||||||
|
|
||||||
|
if (sigaction(SIGALRM, &act, &old_act) < 0) {
|
||||||
|
perror("sigaction");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigemptyset(&newmask);
|
||||||
|
sigaddset(&newmask, SIGALRM);
|
||||||
|
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
|
||||||
|
perror("sigprocmask");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
alarm(timeout);
|
||||||
|
|
||||||
|
suspmask = oldmask;
|
||||||
|
sigdelset(&suspmask, SIGALRM);
|
||||||
|
sigsuspend(&suspmask);
|
||||||
|
|
||||||
|
alarm(0);
|
||||||
|
|
||||||
|
if (sigaction(SIGALRM, &old_act, NULL) == -1) {
|
||||||
|
perror("sigaction restore");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
|
||||||
|
perror("sigprocmask restore");
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void alarm_handler(int signo, siginfo_t *info, void *context)
|
||||||
|
{
|
||||||
|
//printf("Catch signal %d from %u\n", signo, info->si_pid);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user