Advertisement
Guest User

Untitled

a guest
Nov 19th, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.39 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(alarm_handler,SIGALRM);
  64.    
  65.     alarm(1);
  66.     while(!sig_alarm)
  67.         while(sig_count>0)
  68.         {
  69.             if((s=bulk_write(out,buf,s))<0) ERR("write");
  70.             sig_count--;
  71.         }
  72.    
  73.     if(TEMP_FAILURE_RETRY(close(out))) ERR("close");
  74.     free(buf);
  75. }
  76.  
  77. void parent_work() {
  78.     struct timespec t = {0, 10*1000000};
  79.     sethandler(SIG_IGN,SIGUSR1);
  80.     sethandler(alarm_handler,SIGALRM);
  81.    
  82.     alarm(1);
  83.     while(!sig_alarm){
  84.         nanosleep(&t,NULL);
  85.         if(kill(0,SIGUSR1))ERR("kill");
  86.     }
  87. }
  88.  
  89. void usage(char *name){
  90.     fprintf(stderr,"USAGE: %s n1 n2 n3 ... \n",name);
  91.     fprintf(stderr,"n1, n2, n3, ... - number [0-9]\n");
  92.     exit(EXIT_FAILURE);
  93. }
  94.  
  95. int main(int argc, char** argv) {
  96.     int n;
  97.     pid_t pid;
  98.     for(int i=1; i<argc; i++)
  99.     {
  100.         n = atoi(argv[i]);
  101.         if(n<0 || n>9) usage(argv[0]);
  102.         if((pid=fork())<0) ERR("fork");
  103.         if(0==pid)
  104.         {
  105.             child_work(n);
  106.             return EXIT_SUCCESS;
  107.         }
  108.     }
  109.     parent_work();
  110.     while(wait(NULL)>0);
  111.     return EXIT_SUCCESS;
  112. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement