[ create a new paste ] login | about

Link: http://codepad.org/mLtuxDOF    [ raw code | output | fork ]

C, pasted on Nov 17:
#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 */


Output:
1
2
usage: /t -r/f.
 option -r:reverse, -f:forward


Create a new paste based on this one


Comments: