#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*---*/
#include <signal.h>
#include <unistd.h>
struct node {
char *data;
struct node *next;
struct node *prev;
};
char *pop(struct node **);
static struct node *rootS = 0;
/*---------------------------------------------------------------*/
void signal_handler(int sig) {
char *p;
char mes[] = "jumped into the signal handler, aborting.\n";
write(2, mes, sizeof(mes));
while ((p = pop(&rootS)) != 0)
free(p);
exit(1);
}
#define SIGTABLESIZE 16
enum sigentry { INIT = 0, DISABLE, ENABLE };
void signal_handling_entry(enum sigentry entry) {
sigset_t set;
static sigset_t defmaskS, restoreS;
struct sigaction act;
switch (entry) {
case INIT:
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGQUIT);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGTSTP);
act.sa_handler = signal_handler;
act.sa_flags = SA_RESTART;
act.sa_mask = set;
sigaction(SIGINT, &act, 0);
sigaction(SIGQUIT, &act, 0);
sigaction(SIGTERM, &act, 0);
sigaction(SIGTSTP, &act, 0);
defmaskS = set;
return;
case DISABLE:
sigprocmask(SIG_BLOCK, &defmaskS, &restoreS);
return;
case ENABLE:
sigprocmask(SIG_SETMASK, &restoreS, 0);
return;
default:
return;
}
}
/*---------------------------------------------------------------*/
void push_head(struct node **root, char *data) {
struct node *p;
if ((p = malloc(sizeof(struct node))) != 0) {
p->data = data;
p->next = *root;
if (*root == 0) {
p->prev = p;
} else {
p->prev = (*root)->prev;
p->prev->next = p;
p->next->prev = p;
}
*root = p;
}
}
void push_tail(struct node **root, char *data) {
struct node *p;
if ((p = malloc(sizeof(struct node))) != 0) {
p->data = data;
p->next = *root;
if (*root == 0) {
p->prev = p;
*root = p;
} else {
p->prev = (*root)->prev;
p->prev->next = p;
p->next->prev = p;
}
}
}
char *pop(struct node **root) {
char *r;
struct node *p;
if (*root == 0)
return 0;
p = *root;
r = p->data;
if (p->next == p) {
*root = 0;
free(p);
} else {
p->next->prev = p->prev;
p->prev->next = p->next;
*root = p->next;
free(p);
}
return r;
}
#define BUFFSIZE 1024
int main(int argc, char *argv[]) {
static char buff[BUFFSIZE];
char *p;
int flag_reverse;
if (argc != 2) {
usage:
fprintf(stderr, "usage: %s -r/f.\n option -r:reverse, -f:forward\n", argv[0]);
exit(1);
}
if (*argv[1] == '-') {
if (*(argv[1] + 1) == 'f')
flag_reverse = 0;
else if (*(argv[1] + 1) == 'r')
flag_reverse = 1;
else
goto usage;
} else {
goto usage;
}
signal_handling_entry(INIT);
for (;fgets(buff, BUFFSIZE, stdin);) {
signal_handling_entry(DISABLE);
if ((p = malloc(strlen(buff) + 1)) != 0) {
strcpy(p, buff);
if (flag_reverse)
push_head(&rootS, p);
else
push_tail(&rootS, p);
}
signal_handling_entry(ENABLE);
}
putchar('\n');
for (;;) {
signal_handling_entry(DISABLE);
if((p = pop(&rootS)) == 0)
break;
printf("%s", p);
free(p);
signal_handling_entry(ENABLE);
}
return 0;
}
/* end */