Prova Pratica 2012.05.30

From Sistemi Operativi
Jump to navigation Jump to search

Esercizio 1

Scrivere un minimake, cioe' una versione minimale del programma make.
Questo programma legge il file minimakefile nella directory corrente che ha il seguente formato:
target: comando
Il minimakefile e' scritto in modo che se le dipendenze sono generate da regole del minimakefile queste vengano definite
prima. Ad esempio il minimakefile per compilare ed eseguire il programma hw.c (hello world) sara':
hw.o: gcc -c hw.c
hw: gcc -o hw hw.o
run: ./hw
minimake deve scorrere il minimakefile, se il file indicato come target non esiste esegue il comando (e' vietato l'uso di popen,
system e simili!)

Soluzione di Dado e Pierg

#include <stdio.h>
#include <stdlib.h>
#include "s2argv/s2argv.h"
#define MAKEFILE "minimakefile"
#define RUN "run"

int main(int argc, char * argv[]){
	FILE *mf;
	char *line=NULL;
	char *target,*command;
	int dim=0;
	mf=fopen(MAKEFILE,"r");
	if(mf==NULL){
		fprintf(stderr,"minimakefile not found!\n");
		exit(1);
	}
	while(getline(&line,&dim,mf)>0){
		target=strtok(line,":");
		command=strtok(NULL,"\n");
		if(strcmp(target,RUN)==0){
			system_noshell(command);
		}
		else if(fopen(target,"r")==NULL){
			system_noshell(command);
		}
        else{
			fprintf(stderr,"target %s già esistente: non eseguo\n",target);
		}
	}
	free(line);
	fclose(mf);
	return 0;
}

Soluzione di FedericoB

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <execs.h>

int main(int argc, char* argv[]) {
    FILE* file;
    if ((file = fopen("minimake", "r")) != NULL) {
        char target[256], path[256], args[256];
        while (fscanf(file, "%40[^:]: %99[^\n]\n", target, path) != EOF) {
            //check if target file exist
            if (access(target, F_OK) != 0) {
                //if not fork and exec command
                int status;
                switch (fork()) {
                    case 0:
                        execsp(path);
                        break;
                    default:
                        wait(&status);
                        break;
                }
            }
        }
        fclose(file);
    } else {
        perror(NULL);
    }
    return 0;
}

Esercizio 2

Soluzione di Dado e Pierg

la sintassi del minimakefile per l'esercizio2 deve prevedere le dipendenze come il vero makefile.
target: dependence1 dependence2
comando
comando
(come per il makefile il target viene scritto a inizio linea, i comandi hanno un tab come primo carattere)
es per compilare hw.c.
hw.o: hw.c
gcc -c hw.c
hw: hw.o
gcc -o hw hw.o
run: hw
hw
in questo caso occorre eseguire i comandi che seguono la regola di dipendenza solo se il file target non esiste o
se un file indicato come dipendenza e' stato modificato piu' recentemente del target.
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include "s2argv/s2argv.h"
#define MAKEFILE "minimakefile"
#define RUN "run"

int main(int argc, char * argv[]){
	FILE *mf;
	char *line=NULL;
	char *target, *tmp;
	int dim = 0;
    int a = b = 0;
    struct stat st_target, st_tmp;
    
	mf=fopen(MAKEFILE,"r");
	if(fd==NULL){
		fprintf(stderr,"minimakefile not found!\n");
		exit(1);
	}
	while(getline(&line,&dim,mf)>0){
        if (line[0] == "\t") {
            if(a || b){
                system_noshell(line + 1);
            }
        }
		else{
			a = b = 0;
            target = strtok(line, ":")
            if(fopen(target,"r")==NULL){
                a = 1;
		    }
            else if(strcmp(target,RUN)==0){
                char *command = strtok(NULL, "\n");
                system_noshell(command);
		    }
            else {
                stat(target, &st_target);
                while ((tmp = (strtok(NULL, " "))!=NULL){
                    stat(tmp, &st_tmp);
                    if (st_tmp.st_mtime > st_target.st_mtime ) {
                        b = 1;
                        break;
                    }
                }
		    }
		}
	}
	free(line);
	fclose(fd);
	return 0;
}

Esercizio 3

Lo script o il programma python prende il nome di una directory come parametro e deve listare i file nella directory che hanno
un file corrispondente con nome scritto al contrario (il file ailati deve essere nella lista solo se nella directory c'e' anche italia, i
palindromi devono essere listati una sola volta).

Soluzione di Pierg

import sys, os

lines = []
directory = sys.argv[1]

for file in os.listdir(directory):
    lines.append(file)
    
for el in lines:
    for le in lines:
        if el[::-1] == le:
            print el

Soluzione di Dado

#! /bin/bash
cd $1
files=`ls`
ls > /tmp/tmp.txt
rev /tmp/tmp.txt > /tmp/tmp2.txt
for file in $files; do
	grep $file /tmp/tmp2.txt
done
rm /tmp/tmp.txt
rm /tmp/tmp2.txt