ProvaPratica 2013.02.15

From Sistemi Operativi
Jump to navigation Jump to search

Esercizio 1 del 2013.02.15

/*
 *  Prova Pratica di Lab SO 2013.02.15
 *  http://www.cs.unibo.it/~renzo/so/pratiche/2013.02.15.pdf
 *  Es.1
 *  Eduardo Santarelli
 */
#include <dirent.h>
#include <string.h>
#include <unistd.h>

/*  Selector function, called by scandir. Only selects
 *  palindrome file names. Discards implied directories.
 */
int dir_is_pal(const struct dirent* dir){
  int i,j;

  //discard implied dirs
  if(dir->d_name[0]=='.' && strlen(dir->d_name)<3)
    return 0;

  for(i=0, j=strlen(dir->d_name)-1; i<j; i++, j--)
    if(dir->d_name[i]!=dir->d_name[j])
      return 0;

  return 1;
}

int main(int argc, char** argv){
  struct dirent** entry;
  int i, items;
  pid_t pid;

  items=scandir("./", &entry, dir_is_pal, alphasort);

  for(i=0; i<items; i++){
   if(access(entry[i]->d_name, X_OK)==0){  //Check execution rights
     if((pid=fork())) ; //do nothing
     else
       execl(entry[i]->d_name, entry[i]->d_name, (char*)0);
    }
  }

  return 0;
}

-Eduardo
edit: avevo dimenticato un pezzo.


Seconda parte dell'esercizio

/*
 *	Prova Pratica di Lab SO 2013.02.15
 *	http://www.cs.unibo.it/~renzo/so/pratiche/2013.02.15.pdf
 *	Es.2
 *	Eduardo Santarelli
 */
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <libgen.h>
#include <sys/stat.h>
#include <fcntl.h>

/* Global variables
 * declaration
 */
const char *PROGRAM_NAME, *WORKING_DIR;
int b_flag, c_flag, p_flag;  //option flags

/* Function
 * prototypes
 */
int selector(const struct dirent *file);
int checkbang(char *file_name);
void init(int argc, char **argv);

/* Main function
 */
int main(int argc, char **argv){
	struct dirent **entry;
	int i, items, count=0;
	pid_t pid;

	init(argc, argv);

	items=scandir(WORKING_DIR, &entry, selector, alphasort);

	for(i=0; i<items; i++){
		if((pid=fork())){
			if(!c_flag)
				count++;
			else{
				int status;
				waitpid(pid, &status, 0);
			}
		}
 		else{
			execl(entry[i]->d_name, entry[i]->d_name, (char*)0);
			exit(EXIT_FAILURE);
		}
	}

	if(c_flag){
		for(i=0; i<count; i++){
			int status;
			wait(&status);
		}
	}

	return EXIT_SUCCESS;
}


/* Check first two bytes of file for #!
 */
int checkbang(char *file_name){
	int fd;
	char bang[2];

	fd=open(file_name, O_RDONLY);
	read(fd, bang, 2);

	if((strncmp(bang, "#!", 2)) == 0)
		return 1;
	else
		return 0;
}


/* Initialize variables: program name(global const),
 * current directory, option flags
 */
void init(int argc, char **argv){
	int options;

	while((options=getopt(argc, argv, "bcp")) != -1 )
		switch(options){
			case 'b':
				b_flag=1;
				break;
			case 'c':
				c_flag=1;
				break;
			case 'p':
				p_flag=1;
				break;
			case '?':
				printf("Invalid option: '%c'\n", optopt);
				break;
			default:
				abort();
		}
	PROGRAM_NAME=basename(strdup(argv[0]));

	//accept a target directory as an argument from command line
	if(optind==argc)
		WORKING_DIR=getcwd(NULL,0);
	else
		WORKING_DIR=argv[optind];

}

/*	Selector function, called by scandir. Selects files
 *	depending on command line options.
 *	Discards implied directories.
 */
int selector(const struct dirent *file){
	int i,j;
	char *filename;

	filename=strdup(file->d_name);
	//discard implied files
	if(strcmp(filename, ".")==0 || strcmp(filename, "..")==0)
		return 0;

	//Check if file is executable
	if(!access(filename, X_OK)==0)
		return 0;

	//prevent the program from running itself
	if(strcmp(filename, PROGRAM_NAME)==0)
		return 0;

	//if flag is set check if program is a script
	if(b_flag && !(checkbang(filename)))
		return 0;

	//if flag is set, check if prog. name is palindrome
	if(p_flag){
	  for(i=0, j=strlen(filename)-1; i<j; i++, j--)
  	  if(filename[i]!=filename[j])
    	  return 0;
	}

  return 1;
}

-Eduardo