fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. /*-------------------*/
  5. #include <signal.h>
  6. #include <unistd.h>
  7. #include <errno.h>
  8.  
  9. static volatile sig_atomic_t flagSignalS = 0;
  10.  
  11. void signal_handler(int sig) {
  12. int errsrv = errno;
  13. char mes[] = "\njumped into the signal handler, ignored.\n";
  14. write(2, mes, sizeof(mes) - 1);
  15. errno = errsrv;
  16. flagSignalS = 1;
  17. }
  18.  
  19. enum sigentry { INIT = 0, DISABLE, ENABLE };
  20. void signal_handling_entry(enum sigentry entry) {
  21. sigset_t set;
  22. static sigset_t defmaskS, restoreS;
  23. struct sigaction act;
  24. switch (entry) {
  25. case INIT:
  26. sigemptyset(&set);
  27. sigaddset(&set, SIGINT);
  28. sigaddset(&set, SIGQUIT);
  29. sigaddset(&set, SIGTERM);
  30. sigaddset(&set, SIGTSTP);
  31. act.sa_handler = signal_handler;
  32. act.sa_mask = set;
  33. sigemptyset(&act.sa_mask);
  34. sigaction(SIGINT, &act, 0);
  35. sigaction(SIGQUIT, &act, 0);
  36. sigaction(SIGTERM, &act, 0);
  37. sigaction(SIGTSTP, &act, 0);
  38. defmaskS = set;
  39. return;
  40.  
  41. case DISABLE:
  42. sigprocmask(SIG_BLOCK, &defmaskS, &restoreS);
  43. return;
  44.  
  45. case ENABLE:
  46. sigprocmask(SIG_SETMASK, &restoreS, 0);
  47. return;
  48.  
  49. default:
  50. return;
  51. }
  52. }
  53.  
  54. int getSignalS(void) {
  55. int flag_sig;
  56. signal_handling_entry(DISABLE);
  57. flag_sig = flagSignalS;
  58. signal_handling_entry(ENABLE);
  59. return flag_sig;
  60. }
  61.  
  62. void clearSignalS(void) {
  63. signal_handling_entry(DISABLE);
  64. flagSignalS = 0;
  65. signal_handling_entry(ENABLE);
  66. }
  67.  
  68. /*-------------------*/
  69.  
  70. struct node {
  71. char *data;
  72. struct node *next;
  73. struct node *prev;
  74. };
  75.  
  76. int push_head(struct node **root, char *data) {
  77. struct node *p;
  78. if ((p = malloc(sizeof(struct node))) != 0) {
  79. p->data = data;
  80. if (*root == 0) {
  81. p->next = p;
  82. p->prev = p;
  83. } else {
  84. p->next = *root;
  85. p->prev = (*root)->prev;
  86. p->prev->next = p;
  87. p->next->prev = p;
  88. }
  89. *root = p;
  90. return 1;
  91. }
  92. return 0;
  93. }
  94.  
  95. int push_tail(struct node **root, char *data) {
  96. struct node *p;
  97. if ((p = malloc(sizeof(struct node))) != 0) {
  98. p->data = data;
  99. if (*root == 0) {
  100. p->next = p;
  101. p->prev = p;
  102. *root = p;
  103. } else {
  104. p->next = *root;
  105. p->prev = (*root)->prev;
  106. p->prev->next = p;
  107. p->next->prev = p;
  108. }
  109. return 1;
  110. }
  111. return 0;
  112. }
  113.  
  114. char *pop(struct node **root) {
  115. char *r;
  116. struct node *p;
  117. if (*root == 0)
  118. return 0;
  119. p = *root;
  120. r = p->data;
  121. if (p->next == p) {
  122. *root = 0;
  123. free(p);
  124. } else {
  125. p->next->prev = p->prev;
  126. p->prev->next = p->next;
  127. *root = p->next;
  128. free(p);
  129. }
  130. return r;
  131. }
  132.  
  133.  
  134. #define BUFFSIZE 1024
  135. int main(int argc, char *argv[]) {
  136. struct node *rootS = 0;
  137. static char buff[BUFFSIZE];
  138. char *p;
  139. int flag_reverse;
  140. if (argc != 2) {
  141. usage:
  142. fprintf(stderr, "usage: %s -r/f.\n option -r:reverse, -f:forward\n", argv[0]);
  143. exit(1);
  144. }
  145. if (*argv[1] == '-') {
  146. if (*(argv[1] + 1) == 'f')
  147. flag_reverse = 0;
  148. else if (*(argv[1] + 1) == 'r')
  149. flag_reverse = 1;
  150. else
  151. goto usage;
  152. } else {
  153. goto usage;
  154. }
  155.  
  156. signal_handling_entry(INIT);
  157. rootS = 0;
  158. for (;;) {
  159. printf(">> ");
  160. if (fgets(buff, BUFFSIZE, stdin) == 0) {
  161. if (ferror(stdin)) {
  162. if (getSignalS()) { clearSignalS(); clearerr(stdin); continue; } else {
  163. fprintf(stderr, "error occured in fgets(), aborting.\n");
  164. break;
  165. }
  166. } else
  167. break;
  168. }
  169. while (!(p = malloc(strlen(buff) + 1)))
  170. if (getSignalS()) { clearSignalS(); continue; }
  171. if (p != 0) {
  172. strcpy(p, buff);
  173. if (flag_reverse) {
  174. while (!push_head(&rootS, p))
  175. if (getSignalS()) { clearSignalS(); continue; } else {
  176. free(p); goto label_exit;
  177. }
  178. } else {
  179. while (!push_tail(&rootS, p))
  180. if (getSignalS()) { clearSignalS(); continue; } else {
  181. free(p); goto label_exit;
  182. }
  183. }
  184. }
  185. } /* for(;;) */
  186. putchar('\n');
  187. while ((p = pop(&rootS)) != 0) {
  188. while (printf("%s", p) < 0)
  189. if (getSignalS()) { clearSignalS(); continue; } else
  190. break;
  191. free(p);
  192. }
  193. label_exit:
  194. while ((p = pop(&rootS)) != 0)
  195. free(p);
  196. return 0;
  197. }
  198. /* end */
  199.  
Runtime error #stdin #stdout 0.01s 1672KB
stdin
Standard input is empty
stdout
Standard output is empty