Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _GNU_SOURCE
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/wait.h>
- #include <sys/time.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <string.h>
- #include <time.h>
- #define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
- perror(source),kill(0,SIGKILL),\
- exit(EXIT_FAILURE))
- int sig_count = 0, sig_alarm = 0;
- ssize_t bulk_write(int fd, char *buf, size_t count){
- ssize_t c;
- ssize_t len=0;
- do{
- c=TEMP_FAILURE_RETRY(write(fd,buf,count));
- if(c<0) return c;
- buf+=c;
- len+=c;
- count-=c;
- }while(count>0);
- return len ;
- }
- void sethandler( void (*f)(int), int sigNo) {
- struct sigaction act;
- memset(&act, 0, sizeof(struct sigaction));
- act.sa_handler = f;
- if (-1==sigaction(sigNo, &act, NULL)) ERR("sigaction");
- }
- void sig_handler(int sig) {
- sig_count++;
- }
- void alarm_handler(int sig) {
- sig_alarm = 1;
- }
- void child_work(int n) {
- pid_t pid = getpid();
- srand(pid);
- char name[8];
- sprintf(name, "%d", pid);
- strcat(name, ".txt");
- int out;
- ssize_t s = 1024*(rand()%91+10);
- char *buf = malloc(s);
- if(!buf) ERR("malloc");
- for(int i=0;i<s;i++)
- buf[i]=n+48;
- if((out=TEMP_FAILURE_RETRY(open(name,O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,0777)))<0) ERR("open");
- sethandler(sig_handler, SIGUSR1);
- sethandler(alarm_handler,SIGALRM);
- alarm(1);
- while(!sig_alarm)
- while(sig_count>0)
- {
- if((s=bulk_write(out,buf,s))<0) ERR("write");
- sig_count--;
- }
- if(TEMP_FAILURE_RETRY(close(out))) ERR("close");
- free(buf);
- }
- void parent_work() {
- struct timespec t = {0, 10*1000000};
- sethandler(SIG_IGN,SIGUSR1);
- sethandler(alarm_handler,SIGALRM);
- alarm(1);
- while(!sig_alarm){
- nanosleep(&t,NULL);
- if(kill(0,SIGUSR1))ERR("kill");
- }
- }
- void usage(char *name){
- fprintf(stderr,"USAGE: %s n1 n2 n3 ... \n",name);
- fprintf(stderr,"n1, n2, n3, ... - number [0-9]\n");
- exit(EXIT_FAILURE);
- }
- int main(int argc, char** argv) {
- int n;
- pid_t pid;
- for(int i=1; i<argc; i++)
- {
- n = atoi(argv[i]);
- if(n<0 || n>9) usage(argv[0]);
- if((pid=fork())<0) ERR("fork");
- if(0==pid)
- {
- child_work(n);
- return EXIT_SUCCESS;
- }
- }
- parent_work();
- while(wait(NULL)>0);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement