OS Online #1

mail@pastecode.io avatar
unknown
c_cpp
7 months ago
4.8 kB
1
Indexable
Never
#include "election.h"

int *shm;
int sharedMemSize;
FILE *GL_secret_file;

/*
INFO: I have assumed that we are required to print in a file hence I have printed the secret received by GL in a 
GL_secret.txt file.
*/

void signal_handler1(int signum, siginfo_t *siginfo, void *ucontext) {
    int valReceived = siginfo->si_int;
    printf("Received SIGUSR1 from EC\n");
    //if not enough supporters
    if(valReceived == -1) exit(0);        
}

void signal_handler2(int signum, siginfo_t *siginfo, void *ucontext) {
    int valReceived = siginfo->si_int;
    printf("Received SIGUSR2 and value %d from EC\n", valReceived);
    printf("Printing received values\n");
    for(int i = 0; i < valReceived; i++) {
        fprintf(GL_secret_file, "%c", (char)shm[i]);
    }
    if(valReceived < sharedMemSize) {
        //in case we are done with the transfer
        exit(0);
    }
    else {
        //send SIGUSR1 to EC such that it sends the next characters
        pid_t pid = EC_pid;
        union sigval sv;
        sv.sival_int = 1;
        sigqueue(pid, SIGUSR1, sv);
    }
}

int GL() {
    if(!fork()) {
        execlp("ls", "ls", "-lh", "MyTeam/", NULL);
    }

    GL_pid = getpid();

    int fd_file = open("testFile.txt", O_RDWR); 
    int std_out = dup(1);
    int fd1 = dup2(fd_file, 1);

    

    
    
    pid_t children[4];
    for(int i = 0; i < 4; i++) {
        pid_t ret = fork();
        if(ret > 0) {
            children[i] = ret;
            waitpid(ret, NULL, WUNTRACED);
        } 
        else {
            kill(getpid(), SIGSTOP);

            int supporterNum = 0;

            if(!fork()) {
                if(i == 0) {
                    execlp("wc", "wc", "-l", "MyTeam/2020.txt", NULL);
                }
                else if(i == 1) {
                    execlp("wc", "wc", "-l", "MyTeam/2021.txt", NULL);
                }
                else if(i == 2) {
                    execlp("wc", "wc", "-l", "MyTeam/2022.txt", NULL);
                }
                else {
                    execlp("wc", "wc", "-l", "MyTeam/2023.txt", NULL);
                }
            }
            exit(supporterNum);
        }
    }



    //restore stdout
    dup2(std_out, 1);

    // int totalSupport = 0;

    printf("Here\n");
    int number = 0;

    FILE* testFile = fopen("testFile.txt", "r+");
    fseek(testFile, 0, SEEK_SET);
    char num;
    fscanf(testFile, "%c", &num);
    printf("\n\n%c\n\n", num);
    number += num;
    fseek(testFile, 18, SEEK_SET);
        fscanf(testFile, "%c", &num);
    printf("\n\n%c %d\n\n", num, num);
    number += num;
    fseek(testFile, 36, SEEK_SET);
        fscanf(testFile, "%c", &num);
    printf("\n\n%c\n\n", num);
    number += num;
    fseek(testFile, 54, SEEK_SET);
        fscanf(testFile, "%c", &num);
    printf("\n\n%c\n\n", num);
    number += num;

    printf("Here2\n");

    int totalSupport = number / 9;

    for(int i = 0; i < 4; i++) {
        kill(children[i], SIGCONT);
        int tmp = 0;
        waitpid(children[i], &tmp, 0);
        totalSupport += tmp;
    }

    //Create shared memory
    sharedMemSize = totalSupport;
    int shmid;
    key_t key = 6969;
    int flag = SHM_R | SHM_W; //flags set to Shared memory read and write to allow said operations
    shmid = shmget(key, totalSupport, flag);
    if(shmid < 0) {
        shmid = shmget(key, totalSupport, flag | IPC_CREAT); //adding the IPC_CREAT flag to indicate that the shared memory needs to be created.
        if (shmid < 0) {
            perror("shmget | IPC_CREAT"); 
            exit(1);
        }
    }

    shm = (int *) shmat(shmid, NULL, 0); //letting the operating system pick the address, stroing the returned pointer in shm.
    if(shm == (int *) -1) {
        perror("shmat");
        exit(1);
    }

    shm[0] = getpid();
    shm[1] = totalSupport;

    //stdout is the GL_secret file such that printf writes to GL_secret.txt
    GL_secret_file = fopen("GL_secret.txt", "r+");


    //action for SIGUS1
    struct sigaction act1;

    act1.sa_sigaction = signal_handler1;
    sigemptyset(&act1.sa_mask);
    act1.sa_flags = SA_SIGINFO | SA_RESTART;
    sigaction(SIGUSR1, &act1, NULL);

    //action for SIGUSR2
    struct sigaction act2;

    act2.sa_sigaction = signal_handler2;
    sigemptyset(&act2.sa_mask);
    act2.sa_flags = SA_SIGINFO | SA_RESTART;
    sigaction(SIGUSR2, &act2, NULL);
    
    //send the signal to EC with number of supporters
    printf("Sent the signal with %d supporters\n", shm[1]);
    pid_t pid = EC_pid;
    union sigval sv;
    sv.sival_int = key;
    sigqueue(pid, SIGUSR1, sv);
    
    while(1);
    exit(0);
}
Leave a Comment