Prova pratica 2014.09.25

From Sistemi Operativi
Revision as of 17:34, 29 April 2017 by LeonardoF (talk | contribs)
Jump to navigation Jump to search

Testo: [1]

Esercizio 2

//ESERCIZIO 2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "execs.h"  //https://github.com/rd235/s2argv-execs
#include <fcntl.h>

#define AOI_LENSTEP 8
#define AOS_LENSTEP 8
#define BUFFLEN  256
/*
 * Define a struct for managing and array of pointer to strings.
 */
struct array_of_strings {
    char **strings;
    size_t currentlength; //the length of number of string in memory
    size_t arraylength; //the length of memory allocated
};
 
typedef struct array_of_strings array_of_strings;
 
void array_of_strings_add(array_of_strings *arrayOfStrings, char *string) {
    //if there is not enough space for the string increase it
    if (arrayOfStrings->currentlength >= arrayOfStrings->arraylength) {
        //increase the array length by the size of a string pointer
        size_t newlength = arrayOfStrings->arraylength + AOS_LENSTEP;
        //reallocate the arrayOfString with the new size
        char **new_string = realloc(arrayOfStrings->strings, newlength * sizeof(arrayOfStrings->strings[0]));
        //if the reallocation is successful
        if (new_string != NULL) {
            arrayOfStrings->arraylength = newlength;
            arrayOfStrings->strings = new_string;
        }
    }
    //if there is enough space for the string insert it
    if (arrayOfStrings->currentlength < arrayOfStrings->arraylength)
        //strdup return a pointer to a duplicate of the string
        arrayOfStrings->strings[arrayOfStrings->currentlength++] = strdup(string);
}
 
void array_of_strings_print(array_of_strings *v) {
    size_t i;
    for (i = 0; i < v->currentlength; i++)
        printf("[%3lu]: %s\n", i, v->strings[i]);
}

//readapting the struct and the functions above to manage integers
//polymorphism?
struct array_of_integers {
    int **integers;
    size_t currentlength; //the length of number of integers in memory
    size_t arraylength; //the length of memory allocated
};
 
typedef struct array_of_integers array_of_integers;
 
void array_of_integers_add(array_of_integers *arrayOfIntegers, int val) {
   
    if (arrayOfIntegers->currentlength >= arrayOfIntegers->arraylength) {
        size_t newlength = arrayOfIntegers->arraylength + AOI_LENSTEP;
         int **new_vec = realloc(arrayOfIntegers->integers, newlength * sizeof(arrayOfIntegers->integers[0]));

        if (new_vec != NULL) {
            arrayOfIntegers->arraylength = newlength;
            arrayOfIntegers->integers = new_vec;
        }
    }
    if (arrayOfIntegers->currentlength < arrayOfIntegers->arraylength)  
        arrayOfIntegers->integers[arrayOfIntegers->currentlength] = malloc(sizeof(int));
        *(arrayOfIntegers->integers[arrayOfIntegers->currentlength++]) = val;


}
 
void array_of_integers_print(array_of_integers *v) {
    size_t i;
    for (i = 0; i < v->currentlength; i++)
        printf("[%3lu]: %d\n", i, *(v->integers[i]));
}


int main(int argc, char *argv[]) {
	/*opening and reading the file*/
	int commandNumber= 0;
    char* line = NULL;
    size_t lineLength = 0;
	ssize_t numberOfCharactersRead;
    static array_of_strings arrayOfStrings;
    
    FILE* fd1 = fopen(argv[1],"r");

    while ((numberOfCharactersRead = getline(&line, &lineLength, fd1)) >= 0) {
        if (line[numberOfCharactersRead - 1] == '\n')
            line[numberOfCharactersRead - 1] = 0;
        array_of_strings_add(&arrayOfStrings, line);
        commandNumber ++;
    }
 	
 	free(line);
 	/*done*/
 	/* opening output files, forking , saving pids and file descriptors*/
 	int pid;
	int i = 0; //iterator
	int fd; //file descriptor
	char concat[BUFFLEN];
    static array_of_integers arrayOfPid;
    static array_of_integers arrayOfFd;
    
 	while(commandNumber > 0 ){
            sprintf(concat,"./temp%d",i);
            fd = open(concat,O_RDWR | O_CREAT | O_TRUNC , 0666);

 			pid = fork();
 			switch(pid){
 				case 0: //children
                                        //children stdio = file fd
                                        dup2(fd,STDOUT_FILENO);
				        //execution of the command
				        execsp(arrayOfStrings.strings[i]);
 				        exit(-1); // in case of execsp failure
 				default: //parent 
                                         //must save all the pids
                                         array_of_integers_add(&arrayOfPid,pid);
                                         //must save all the fds. ( they will have the same order of the pids);
                                          array_of_integers_add(&arrayOfFd,fd); 
 					  commandNumber --;
 					  i ++;
 					  break;
 			}
 		
 	}
    printf("arrayofFd\n");
    array_of_integers_print(&arrayOfFd);
    /*done*/
    /*waiting first process and killing the others*/
 	int firstpid;
 	size_t j; //iterator
    size_t firstpid_pos; //position of the first pid in the array
    //wait the first process
 	firstpid = wait(NULL);
 	//printf("%d\n",firstpid );
    //sigterm the other processes iterating the pids vector
    for (j = 0; j < (&arrayOfPid)->currentlength; j++){
        int temp = *((&arrayOfPid)->integers[j]);

        if(temp != firstpid)
            kill( temp,SIGTERM);
        else 
        	firstpid_pos = j ;
    }
    /*done*/

 
    /*printign the file of the "fisrt pid" process , unlinking the file and closing them*/
    for (j = 0; j < (&arrayOfFd)->currentlength; j++){
    	 fd = *((&arrayOfFd)->integers[j]);
    
    	sprintf(concat,"./temp%lu",j);
    	if (j == firstpid_pos){
    		int c;
    		//lseek is needed because the file is inherited
    		lseek(fd,0,SEEK_SET);
    		
    		FILE *fdp = fdopen(fd,"r");
    		

    		   while ((c = getc(fdp)) != EOF)
        			putchar(c);
   
    		

    	}
    	
    	//unlink file fd
    	unlink(concat);
    	//close file fd
    	close(fd);

    }
    /*done*/

    return 0;
}

--LeonardoF (talk) 11:33, 26 April 2017 (CEST)LeonardoF