Advertisement
Guest User

Untitled

a guest
Nov 19th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.43 KB | None | 0 0
  1. #define _GNU_SOURCE
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <sys/wait.h>
  6. #include <sys/time.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <errno.h>
  10. #include <string.h>
  11. #include <time.h>
  12. #define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
  13.                      perror(source),kill(0,SIGKILL),\
  14.                                      exit(EXIT_FAILURE))
  15.  
  16. int sig_count = 0, sig_alarm = 0;
  17.  
  18. ssize_t bulk_write(int fd, char *buf, size_t count){
  19.         ssize_t c;
  20.         ssize_t len=0;
  21.         do{
  22.                 c=TEMP_FAILURE_RETRY(write(fd,buf,count));
  23.                 if(c<0) return c;
  24.                 buf+=c;
  25.                 len+=c;
  26.                 count-=c;
  27.         }while(count>0);
  28.         return len ;
  29. }
  30.  
  31. void sethandler( void (*f)(int), int sigNo) {
  32.     struct sigaction act;
  33.     memset(&act, 0, sizeof(struct sigaction));
  34.     act.sa_handler = f;
  35.     if (-1==sigaction(sigNo, &act, NULL)) ERR("sigaction");
  36. }
  37.  
  38. void sig_handler(int sig) {
  39.     sig_count++;
  40. }
  41.  
  42. void alarm_handler(int sig) {
  43.     sig_alarm = 1;
  44. }
  45.  
  46. void child_work(int n) {
  47.     pid_t pid = getpid();
  48.     srand(pid);
  49.  
  50.     char name[8];
  51.     sprintf(name, "%d", pid);
  52.     strcat(name, ".txt");
  53.    
  54.     int out;
  55.     ssize_t s = 1024*(rand()%91+10);
  56.     char *buf = malloc(s);
  57.     if(!buf) ERR("malloc");
  58.     for(int i=0;i<s;i++)
  59.         buf[i]=n+48;
  60.     if((out=TEMP_FAILURE_RETRY(open(name,O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,0777)))<0) ERR("open");
  61.    
  62.     sethandler(sig_handler, SIGUSR1);
  63.     sethandler(sig_handler, SIGUSR2);
  64.     sethandler(alarm_handler,SIGALRM);
  65.    
  66.     alarm(1);
  67.     while(!sig_alarm)
  68.         while(sig_count>0)
  69.         {
  70.             if((s=bulk_write(out,buf,s))<0) ERR("write");
  71.             sig_count--;
  72.         }
  73.    
  74.     if(TEMP_FAILURE_RETRY(close(out))) ERR("close");
  75.     free(buf);
  76. }
  77.  
  78. void parent_work() {
  79.     struct timespec t = {0, 10*1000000};
  80.     sethandler(SIG_IGN,SIGUSR1);
  81.     sethandler(alarm_handler,SIGALRM);
  82.    
  83.     alarm(1);
  84.     while(!sig_alarm){
  85.         nanosleep(&t,NULL);
  86.         if(kill(0,SIGUSR1))ERR("kill");
  87.     }
  88. }
  89.  
  90. void usage(char *name){
  91.     fprintf(stderr,"USAGE: %s n1 n2 n3 ... \n",name);
  92.     fprintf(stderr,"n1, n2, n3, ... - number [0-9]\n");
  93.     exit(EXIT_FAILURE);
  94. }
  95.  
  96. int main(int argc, char** argv) {
  97.     int n;
  98.     pid_t pid;
  99.     for(int i=1; i<argc; i++)
  100.     {
  101.         n = atoi(argv[i]);
  102.         if(n<0 || n>9) usage(argv[0]);
  103.         if((pid=fork())<0) ERR("fork");
  104.         if(0==pid)
  105.         {
  106.             child_work(n);
  107.             return EXIT_SUCCESS;
  108.         }
  109.     }
  110.     parent_work();
  111.     while(wait(NULL)>0);
  112.     return EXIT_SUCCESS;
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement