A better version of dwmblock (i think)...
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

164 lignes
2.6KB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <signal.h>
  6. #include <errno.h>
  7. #include <unistd.h>
  8. #include <sys/select.h>
  9. #include <sys/fcntl.h>
  10. #include <sys/wait.h>
  11. typedef struct Process Process;
  12. struct Process {
  13. pid_t pid;
  14. int fd;
  15. char str[64];
  16. Process *next;
  17. };
  18. static Process *list = NULL;
  19. int
  20. max(int a, int b)
  21. {
  22. return (a > b ? a : b);
  23. }
  24. Process *
  25. newproc(const char *command)
  26. {
  27. Process *p;
  28. int pipes[2];
  29. pid_t pid;
  30. if(pipe(pipes) < 0) {
  31. perror("pipe()");
  32. exit(EXIT_FAILURE);
  33. }
  34. switch((pid = fork())) {
  35. case -1:
  36. perror("fork()");
  37. exit(EXIT_FAILURE);
  38. case 0:
  39. close(0);
  40. close(1);
  41. dup2(pipes[1], 1);
  42. close(pipes[0]);
  43. close(pipes[1]);
  44. execl("/bin/sh", "/bin/sh", "-c", command, NULL);
  45. exit(EXIT_SUCCESS);
  46. return NULL;
  47. default:
  48. close(pipes[1]);
  49. p = malloc(sizeof *p);
  50. if(!p) {
  51. perror("malloc()");
  52. exit(EXIT_FAILURE);
  53. }
  54. memset(p, 0, sizeof *p);
  55. p->pid = pid;
  56. p->fd = pipes[0];
  57. return p;
  58. }
  59. }
  60. static void
  61. sigtrap(int sig)
  62. {
  63. if(sig != SIGINT)
  64. return;
  65. for(Process *p = list; p; p = p->next) {
  66. killpg(p->pid, sig);
  67. }
  68. while(wait(NULL) != -1 || errno == EINTR);
  69. /* let the operating take care of the memory leak, fuck it */
  70. exit(EXIT_SUCCESS);
  71. }
  72. int
  73. linerd(int fd, char *line, int linesize)
  74. {
  75. int i;
  76. for(i = 0; i < linesize; i++) {
  77. char c;
  78. if(read(fd, &c, sizeof c) <= 0) {
  79. break;
  80. }
  81. if(c == '\n') {
  82. line[i] = 0;
  83. break;
  84. }
  85. line[i] = c;
  86. }
  87. line[linesize - 1] = 0;
  88. return i;
  89. }
  90. int
  91. main(int argc, char *argv[])
  92. {
  93. int maxfd = 0, i, c;
  94. fd_set rdset;
  95. Process *p;
  96. signal(SIGINT, sigtrap);
  97. signal(SIGTERM, sigtrap);
  98. signal(SIGKILL, sigtrap);
  99. FD_ZERO(&rdset);
  100. while((c = getopt(argc, argv, "c:")) > 0) {
  101. switch(c) {
  102. case 'c':
  103. p = newproc(optarg);
  104. FD_SET(p->fd, &rdset);
  105. maxfd = max(maxfd, p->fd);
  106. p->next = list;
  107. list = p;
  108. break;
  109. default:
  110. fprintf(stderr, "Unknown option: %c\n", c);
  111. exit(EXIT_FAILURE);
  112. }
  113. }
  114. if(!list) {
  115. fprintf(stderr, "usage: %s -c command [-c command2 ]...\n", argv[0]);
  116. exit(EXIT_FAILURE);
  117. }
  118. for(;;) {
  119. int n;
  120. fd_set copy;
  121. FD_ZERO(&copy);
  122. memcpy(&copy, &rdset, sizeof rdset);
  123. n = select(maxfd + 1, &copy, NULL, NULL, NULL);
  124. if(n < 0) {
  125. perror("select()");
  126. continue;
  127. }
  128. for(Process *p = list; p; p = p->next)
  129. if(FD_ISSET(p->fd, &copy)) {
  130. if(linerd(p->fd, p->str, sizeof p->str) <= 0) {
  131. FD_CLR(p->fd, &rdset);
  132. close(p->fd);
  133. }
  134. }
  135. for(Process *p = list; p; p = p->next)
  136. printf("%s%s", p->str, p->next ? " | " : "");
  137. printf("\n");
  138. fflush(stdout);
  139. }
  140. return 0;
  141. }