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 BUFFLEN 256
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*/
char* line = NULL;
size_t lineLength = 0;
ssize_t numberOfCharactersRead;
FILE* fd1 = fopen(argv[1],"r");
static array_of_integers arrayOfPid;
static array_of_integers arrayOfFd;
int fd; //file descriptor
int i = 0; //iterator
char concat[BUFFLEN];
while ((numberOfCharactersRead = getline(&line, &lineLength, fd1)) >= 0) {
if (line[numberOfCharactersRead - 1] == '\n')
line[numberOfCharactersRead - 1] = 0;
///
/*done*/
/* opening output files, forking , saving pids and file descriptors*/
sprintf(concat,"./temp%d",i);
fd = open(concat,O_RDWR | O_CREAT | O_TRUNC , 0666);
int pid = fork();
switch(pid){
case 0: //children
//children stdio = file fd
dup2(fd,STDOUT_FILENO);
//execution of the command
execsp(line);
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);
i ++;
break;
}
}
free(line);
/*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);
/*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*/
/*printing 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;
}