Prova pratica 2014.09.25
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;
}