ProvaPratica 2013.05.29

From Sistemi Operativi
Jump to navigation Jump to search

Link al compito

Esercizio 1

Scrivere un programma testeventfd che faccia uso della system call eventfd.
In particolare il programma deve eseguire una fork, quando l'utente digita un numero letto dal processo padre, il processo
figlio deve stampare un numero uguale di x.
$ testeventfd
3
x
x
x
2
x
x

Soluzione di GiuliaN.

#include <sys/eventfd.h>
#include <stdio.h>
#include <unistd.h>

#define BUFFSIZE 10

int main(int argc, char *argv[]){
	int efd,n,i;
	char buf1[BUFFSIZE];
	char buf2[BUFFSIZE];
	
	do{
		efd = eventfd(0,0);
	}while(efd<0);
	
	while(1){
		if(fork()){ /*padre*/
				read(0,buf1,sizeof(buf1)); /*0 indica lo standard input*/
				write(efd, buf1, sizeof(buf1));
				}
			
		else{ /*figlio*/
			read(efd, buf2, sizeof(buf2));
			n=atoi(buf2);
			for(i=0; i<n; i++) printf("x\n");
		}
	}
}

GiuliaN. con grande aiuto da parte dei colleghi

Soluzione del Prof. Davoli

(visto a lezione , soluzione del Prof. Davoli ricopiata da Pirata_20131203)

#include <sys/eventfd.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
 
#define BUFFSIZE 10
 
int main(int argc, char *argv[]){
	int efd , n , i;
	uint64_t a , b;
	if ( ( efd = eventfd( 0 , EFD_SEMAPHORE ) ) < 0 )
		exit( 1 );
	if ( fork() > 0 ){
		while ( 1 ) {
		uint64_t a;
		scanf( "%lld" , &a );
		write( efd , &a , sizeof( a ) );
				}
		}
	else {
		while ( 1 ) {
		uint64_t b;
		read( efd , &b , sizeof( b ) );
		printf( "x\n" );
		}
	}
}

Soluzione di Pierg

#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h> 

int main (int argc, char *argv[]) {
	
	int efd, i; 
	long long unsigned int val;
    	ssize_t s;
	
	/* Check for eventfd error */
	efd = eventfd(0, 0);
	if (efd == -1) {
		perror("Eventfd Error"); 
	}

	/* Use fork to move eventfd form parent to child */
	switch (fork()) {
		
		case 0:
			/* Read parent event */
			s = read(efd, &val, sizeof(long long unsigned int));

            		if (s != sizeof(long long unsigned int)) {
                		perror("Read Error");
				exit(EXIT_FAILURE);
        		}

			/* For is used to print the 'x' of the argument passed by terminal */
			for (i = (int)val; i > 0; i--) {
				printf ("x\n");
			}

			exit(EXIT_SUCCESS);
		
		/* Check for error */
		case -1:
			perror("Fork Error"); 
			exit(EXIT_FAILURE);

		default:
			/* Wait for number */
			printf ("Inserisci un intero diverso da 0: \n");
			scanf ("%llu", &val);

			/* Write parent event */
           		s = write(efd, &val, sizeof(long long unsigned int));

            		if (s != sizeof(long long unsigned int)) {
                		perror("Write Error");
				exit(EXIT_FAILURE);
        		}
	
			exit(EXIT_SUCCESS);
	}
}

Soluzione di Maldus

Semaforo implementato usando un altro eventfd.

#include <stdio.h>
#include <sys/eventfd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <signal.h>


int main(){
	pid_t son ;
	int ed1 , ed2 ,  i;
	uint64_t x = 1;
	int y = 1 ;
	ed1 = eventfd(0,0) ;	/*eventfd usato per la comunicazione effettiva del numero*/
	ed2 = eventfd( 1 , EFD_SEMAPHORE ) ;	/*eventfd usato come semaforo*/
	switch( son = fork() ){
		case 0:
			while( 1 ){
				read( ed1 , &x , 8) ;	/*se ci sono dei dati li legge*/
				for(i = x ; i > 0 ; i--) printf( "x" ) ;
				printf("\n");
				write(ed2 , &y , 8 ) ;	/*dopo la lettura dei dati, dà il via libera sul semaforo per scrivere di nuovo*/
				}
			return 1;
		default:
			while( x ){
				read( ed2 , &y , 8 ) ;	/*si blocca sul semaforo se i dati non sono ancora stati letti*/
				scanf("%" PRIu64 , &x) ;
				write(ed1 , &x , 8 ) ;	/*scrittura dei dati*/
			}
			kill(son ,SIGTERM);
			return 0 ;		
	}
}

Esercizio 2

Soluzione di Eduardo Santarelli

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/eventfd.h>

#define SIZE 64

int main(int argc, char **argv){
	int efd_parent, efd_child;
	pid_t pid;

	efd_parent = eventfd(0, 0);
	efd_child = eventfd(0, 0);

	pid = fork();
	if(pid < 0){
		perror("Fork error. ");
		exit(EXIT_FAILURE);
	}
	/* parent */
	if(pid){
		int okToWrite = 1;
		ssize_t n;
		char buf[SIZE];

		for(;;){
			if(okToWrite){
				scanf("%s", buf);
			
				n = write(efd_parent, buf, SIZE);
				if(n < 0){
					perror("Parent: write error.");
					exit(EXIT_FAILURE);
				}
			okToWrite = 1-okToWrite;
			}
			else{
				n = read(efd_child, buf, SIZE);
				if( n < sizeof(uint64_t) ){
					printf("Parent: something bad happened");
					exit(EXIT_FAILURE);
				}

				printf("padre: %s\n", buf);
				okToWrite = 1-okToWrite;
			}
		}
		close(efd_parent);
	}
	/* child */
	else{
		int okToWrite = 0;
		char buf[SIZE];
		int n;
	
		for(;;){
			if(okToWrite){
				scanf("%s", buf);
			
				n = write(efd_child, buf, SIZE);
				if(n < 0){
					perror("child: write error.");
					exit(EXIT_FAILURE);
				}
				okToWrite = 1-okToWrite;
			}
			else{
				n = read(efd_parent, buf, SIZE);
				if( n < sizeof(uint64_t) ){
					printf("Child: something bad happened");
					exit(EXIT_FAILURE);
				}
				printf("figlio: %s\n", buf);
				okToWrite = 1-okToWrite;
			}
		}
		close(efd_child);
	}

	return EXIT_SUCCESS;
}

- Eduardo


Esercizio 3

===Soluzione di Tommaso Ognibene(Python 3)

'''
Prova Pratica di Laboratorio di Sistemi Operativi
29 maggio 2013
Esercizio 3

URL: http://www.cs.unibo.it/~renzo/so/pratiche/2013.05.29.pdf

@author: Tommaso Ognibene
'''

import os, sys

def Main(argv):
    # Check number of arguments
    if len(argv) != 2:
        print("The function requires one argument to be passed in.")
        return
    
    # Check parameters
    topDir = str(sys.argv[1])
    if not os.path.isdir(topDir):
        print("The parameter should be an existing directory.")
        return
    
    # Build a dictionary with key-value pair {file extension - total size}
    extensionSize = { }
    GetSize(topDir, extensionSize)
    
    # Print results
    PrintResults(extensionSize)

def GetSize(topDir, extensionSize):
    for dirPath, dirNames, files in os.walk(topDir):
        for file in files:
            # 'example.mp3' -> ['example', 'mp3']
            # 'example.tar.gz' -> ['example', 'tar', 'gz']
            parts = file.split('.')
            # ['example', 'mp3'] -> ['mp3']
            # ['example', 'tar', 'gz'] -> ['tar', 'gz']
            parts = parts[1:]
            # ['mp3'] -> '.mp3'
            # ['tar', 'gz'] -> '.tar.gz'
            fileExtension = ".{0}".format(".".join(str(part) for part in parts))
            
            # Compute the size in Bytes and update the dictionary
            filePath = os.path.join(dirPath, file)   
            fileSize = os.path.getsize(filePath)
            extensionSize[fileExtension] = extensionSize.get(fileExtension, 0) + fileSize

# Print results
def PrintResults(extensionSize):
    for key, value in sorted(extensionSize.items()):
        print('{0}: {1} Bytes.'.format(key, value))
        
if __name__ == "__main__":
    sys.exit(Main(sys.argv))


Soluzione di Fede(python 3)

import os, sys, copy

def dotsubstr(a):#restituisce la sottostringa .suffisso
	#fcd = os.listdir('{0}'.format(arg1))
	i=0
	try:
		while a[i]!='.':
			i=i+1
		return a[i:]
	except IndexError:
		return -1

def compliarg(li,arg):#restituisce una lista di tutti gli elementi contenenti la sottostringa arg come suffisso
	res=[]
	while li != []:
		a=li.pop()
		if a.endswith(arg): res.append(a)
	return res

def listremintsect(l2,l1):#restituisce una lista res = l1 - intersezione di l1 ed l2
	res=[]
	while l1 != []:
		a=l1.pop()
		if not a in l2: res.append(a)
	return res

def createpathlist(c,path):#restituisce una lista di path 'path' relativi ai file contenuti in c.
	res = []
	while c != []:
		res.append('{0}/{1}'.format(path,c.pop()))
	return res

def totsizes(d): #data una lista d di path restituisce la somma di tutti i size di d
	res = 0
	while d != []:
		a = d.pop()
		if os.path.isfile('{0}'.format(a)):
			res = res + os.path.getsize('{0}'.format(a))
	return res

def listsubstr(arg): #ritorna un dizionario del tipo diz[str(suffisso)] = int(size relativo al suffisso)
	res = {}
	fcd = os.listdir('{0}'.format(arg))
	while fcd != []:
		fcdtmp=copy.deepcopy(fcd) #BUGGONE SENZA COPY!!!!!!
		a = fcd.pop()
		b = dotsubstr(a)
		if b == -1: continue
		else: pass
		c = compliarg(fcdtmp,b)
		s=copy.deepcopy(c) #!!!!!!!!!!!!!!!!!!!!!!!!!
		d = createpathlist(c,arg)
		res[b] = totsizes(d)

		fcd = listremintsect(s,fcd)

	return res
		

try:
	res = listsubstr(sys.argv[1])
	a=list(res.keys())
	while a != []:
		b = a.pop()
		print('{0}:\t{1}'.format(b,res[b]))
except OSError:
	print("Could not solve path")


Soluzione in bash(Pirata & Fede)

#! /bin/bash

for f in "$1"/*.* ; do
	somma=0
	ext=${f##*.}
	for file in *."$ext"
	do
		somma=$(expr $somma + $(stat -c%s "$file"))
	done
	echo -n "size of file with extension "$ext" : "
	echo "$somma"
done

Per (Pirata & Fede) -Bash-: ci siamo quasi...però forse rifate gli stessi calcoli un po' di volte in più del necessario ;-) (am_20131127).


Soluzione di Eduardo Santarelli (python)

#!/usr/bin/env python3
#
# Prova Pratica di Lab SO 2013.05.29
# Es. 3
# Eduardo Santarelli
#####################################

import os, sys

# return the suffix of file named fname, if present.
# return boolean value False otherwise
def get_suffix(fname):
	if '.' in fname:
		separator = fname.find('.')
		return fname[separator : ]
	else:
		return False	

# Place a file in a dictionary. Each key corresponds
# to a specific suffix, its value is a list of all the
# file with that suffix
def build_dict(item, suffix):
	if suffix in all_files:
		all_files[suffix].append(item)
	else:
		all_files[suffix] = []
		all_files[suffix].append(item)

# For each suffix key in the dictionary,
# calculates the total size of the files
# in the corresponding list
def size_of_entry(file_list):
		size = 0
		for item in file_list:
			size += os.path.getsize(item)
		return size

# This dictionary will contain a key for each suffix,
# associated with a list of all the files ending with
# that suffix
all_files = dict()

# Go to target directory and build a list containing all filenames
try:
	target_dir = sys.argv[1]
except:
	target_dir = '.'
os.chdir(target_dir)
dir_list = os.listdir('.')

# For each file call get_suffix and then build_dict
# (unless get_suffix returns False)
for item in dir_list:
	suffix = get_suffix(item)
	if not suffix:
		pass
	else:
		build_dict(item, suffix)

for key in all_files :
	print("{0}: {1} Bytes".format(key, size_of_entry(all_files[key])))

-Eduardo --edit: dir_list = os.listdir(target_dir) non funzionava bene coi path relativi. Ora os.listdir('.') dovrebbe andare bene.