Difference between revisions of "ProvaPratica 2009.02.12"

From Sistemi Operativi
Jump to navigation Jump to search
(Created page with "<h1>http://www.cs.unibo.it/~renzo/so/compiti/2009-02-12.pdf</h1> == Esercizio 1 == <syntaxhighlight lang="C"> #include <stdio.h> #include <stdlib.h> #include <string.h> #in...")
 
m (Aggiunte soluzioni di altri studenti)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<h1>http://www.cs.unibo.it/~renzo/so/compiti/2009-02-12.pdf</h1>
+
[http://www.cs.unibo.it/~renzo/so/pratiche/2009.02.12.pdf Link al testo]
  
  
 
== Esercizio 1 ==
 
== Esercizio 1 ==
  
 +
===Soluzione di Stefano92===
 +
<source lang="text">
 +
Scrivere un programma C denominato “invarg” che esegua il programma passato
 +
come parametro invertendo gli argomenti.
 +
Esempio:
 +
invarg cat a b c
 +
deve avere l'effetto di
 +
cat c b a
 +
</source>
 
<syntaxhighlight lang="C">
 
<syntaxhighlight lang="C">
 
#include <stdio.h>
 
#include <stdio.h>
Line 17: Line 26:
 
int main(int argc,char* argv[])
 
int main(int argc,char* argv[])
 
{
 
{
   char* tmp_i,*tmp_x,*bin="/bin/";
+
   char* tmp_i,*tmp_x;
 
   int x=(argc-1),i=2;
 
   int x=(argc-1),i=2;
 
   if (argc<2)
 
   if (argc<2)
Line 39: Line 48:
 
argc--;
 
argc--;
 
execvp(argv[0],argv);
 
execvp(argv[0],argv);
 +
        //equivalentemente avrei potuto lanciare execvp(argv[1],argv+1) evitando di modificare argv[]
 
return 0;
 
return 0;
 +
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
stefano92
 
stefano92
 +
 +
===Soluzione di Maldus===
 +
<source lang="c">
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
 +
int main(int argc , char* argv[]){
 +
char *nargv[argc-1] ; /*nargv è il vettore degli argomenti da passare al programma da eseguire*/
 +
int i , j ; /*puntatori che scorrono, rispettivamente, argv ed nargv per riempire correttamente nargv*/
 +
nargv[0] = argv[1] ; /*il primo valore di nargv deve essere il programma chiamato, l'ultimo deve essere NULL*/
 +
nargv[argc-1] = NULL ;
 +
for( i = argc - 1 , j = 1 ; i > 1 , j < (argc - 1) ; i-- , j++ ) nargv[j] = argv[i] ; /*metto in nargv (dal secondo elemento in poi) gli argomenti presenti
 +
in argv in ordine invertito*/
 +
execvp( nargv[0] , nargv  ) ; /*eseguo il programma (il cui nome è contenuto in nargv[0]) passandogli nargv come vettore di parametri*/
 +
fprintf( stderr , "programma errato\n" ) ; /*se ci troviamo in questo punto significa che la chiamata a execvp è fallita, probabilmente
 +
perchè il programma indicato non è stato trovato*/
 +
exit(1) ;
 +
}
 +
</source>
 +
 +
===Soluzione di Eddy===
 +
<source lang="c">
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <errno.h>
 +
 +
void scambia_ordine(int argc, char **argv, int j);
 +
 +
int main(int argc , char* argv[])
 +
{
 +
if (argc < 2) return 2;
 +
argv++; argc--;
 +
scambia_ordine(argc, argv, 1);
 +
execvp(argv[0], argv);
 +
perror("execvp");
 +
return 3;
 +
}
 +
 +
/* piccola funzione ricorsiva che:
 +
* -memorizza in tmp gli argomenti dalla fine
 +
* -assegna ad argv in ordine inverso
 +
*
 +
*  non scambia il primo argomento
 +
*/
 +
void scambia_ordine(int argc, char **argv, int j)
 +
{
 +
char *tmp;
 +
if (argc > 1){
 +
tmp = argv[argc-1];
 +
scambia_ordine (argc-1, argv, j+1);
 +
argv[j]=tmp;
 +
}
 +
 +
}
 +
</source>
 +
[[User:Eddy|Eddy]] ([[User talk:Eddy|talk]]) 21:00 Saturday, 22 November 2014 (CET)
 +
 +
===Soluzione di GFede===
 +
<source lang="c">
 +
#include <stdio.h>
 +
#include <unistd.h>
 +
#include <errno.h>
 +
 +
void scambia(int offset, int argc, char* argv[]);
 +
 +
int main(int argc, char* argv[])
 +
{
 +
  if(argc <= 1)
 +
  {
 +
      printf("Usage: invarg.exe command [arguments...]\n");
 +
      return 2;
 +
  }
 +
  scambia(2, argc - 1, argv);
 +
 +
  execvp(argv[1], argv + 1);
 +
  perror("execvp");
 +
  return 1;
 +
}
 +
 +
/**
 +
* Scambia le stringhe all'interno dell'array
 +
* void scambia
 +
* int offset    Indice da cui iniziare a scambiare
 +
* int argc      Numero di valori nell'array (Compreso l'offset)
 +
* char* argv[]  array di stringhe da scambiare
 +
*/
 +
void scambia(int offset, int argc, char* argv[])
 +
{
 +
  int i;
 +
  char* tmp;
 +
  for( i = offset; i < argc - i + offset; i++ )
 +
  {
 +
      tmp = argv[i];
 +
      argv[i] = argv[argc - i + offset];
 +
      argv[argc - i + offset] = tmp;
 +
  }
 +
}
 +
</source>
 +
 +
===Soluzione di LorenzoV===
 +
<source lang="c">
 +
#include <stdlib.h>
 +
#include <stdio.h>
 +
 +
void swap(char **p, char **q){ // La swap modifica solo i puntatori
 +
char *tmp;
 +
tmp=*p;
 +
*p=*q;
 +
*q=tmp;
 +
}
 +
 +
int main(int argc, char* argv[]){
 +
char **begin, **end;
 +
if (argc<3){
 +
fprintf(stderr, "Usage:\n\t%s command ...arguments...\n", argv[0]);
 +
exit(1);
 +
}
 +
begin=argv+2;
 +
end=argv+argc-1;
 +
while (begin<end){ // Inverte i parametri passati al comando
 +
swap(begin, end);
 +
begin++;
 +
end--;
 +
}
 +
execvp(argv[1], argv+1);
 +
return 0;
 +
}
 +
</source>
 +
--[[User:LorenzoV|LorenzoV]] ([[User talk:LorenzoV|talk]]) 18:35, 25 November 2014 (CET)
 +
 +
 +
 +
 +
===Soluzione di BoldrinD===
 +
<source lang="c">
 +
#include <stdio.h>
 +
#include <unistd.h>
 +
#include <errno.h>
 +
 +
void invarg(int Qparametri, char* Rargv[], char* argv[]);
 +
 +
int main(int argc, char* argv[]){
 +
int Qparametri=argc-1;
 +
char *Rargv[Qparametri];
 +
invarg(Qparametri, Rargv, argv);
 +
printf("%s\n","il nuovo vettore dei parametri è stato creato con successo");
 +
  execvp(Rargv[0], Rargv);
 +
  perror("execvp");
 +
  return 1;
 +
 +
}
 +
 +
void invarg(int Qparametri, char* Rargv[], char* argv[]){
 +
Rargv[0]=argv[1];
 +
Rargv[Qparametri]=NULL;
 +
int i=2;
 +
while(argv[i]!=NULL){
 +
Rargv[Qparametri-1]=(argv[i]);
 +
i++;
 +
Qparametri--;
 +
}
 +
 +
}
 +
</source>
 +
 +
 +
===Soluzione di AleZ===
 +
<source lang="c">
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
 +
int main (int argc, char* argv[]) {
 +
if (argc == 1) { // Non è stato passato alcun comando per la execvp
 +
fprintf(stderr, "Error: Segmentation fault\nUsage: [command] [arguments...]\n");
 +
return(EXIT_FAILURE);
 +
}
 +
char* tmp[argc]; // vettore che conterrà gli argomenti scambiati
 +
int i = 0;
 +
tmp[0] = argv[1]; // per convenzione il primo argomento è il programma chiamato
 +
tmp[argc-1] = (char*)NULL; // come da manuale
 +
for (i = argc-2; i > 0; i--) tmp[i] = argv[(argc-i)]; // inverto gli argomenti
 +
execvp(tmp[0], tmp);
 +
fprintf(stderr, "%s: command not found\n", argv[1]); //execvp ha fallito
 +
return(EXIT_FAILURE);
 +
}
 +
</source>
 +
--[[User:Ale|Ale]] ([[User talk:Ale|talk]]) 20:39, 1 December 2014 (CET)
 +
 +
==Esercizio 2==
 +
===Soluzione di Dado e Pierg===
 +
<source lang="text">
 +
Scrivere un programma in linguaggio C che crei due named pipe (passate per argomento), le apra in lettura e
 +
e copi in standard output i dati via via disponibili da ogni pipe.
 +
Test di funzionamento: aprire tre finestre di emulazione terminale. Nella prima lanciare: mergepipe p1 p2, nella seconda:
 +
cat >p1, nella terza cat>p2.
 +
Tutto cio' che scriverete o nella seconda o nella terza finestra deve comparire nella prima.
 +
</source>
 +
<source lang="c">
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <poll.h>
 +
#include <sys/types.h>
 +
#include <sys/stat.h>
 +
#include <fcntl.h>
 +
 +
#define MAX 2048
 +
 +
int main (int argc, char *argv[]) {
 +
    if (argc < 3) {
 +
        perror("Argomenti sbagliati");
 +
    }
 +
    else {
 +
        struct pollfd pino [2];
 +
        nfds_t n = 2;
 +
        char buf[MAX];
 +
       
 +
        mkfifo(argv[1], 0666);
 +
        mkfifo(argv[2], 0666);
 +
        pino[0].fd = open(argv[1], O_RDONLY | O_NONBLOCK);
 +
        pino[1].fd = open(argv[2], O_RDONLY | O_NONBLOCK);
 +
        pino[0].events = POLLIN;
 +
        pino[1].events = POLLIN;
 +
       
 +
        while(1) {
 +
            int ret = poll(pino, n, 100);
 +
            if (ret == 1) {
 +
                if (pino[0].revents == POLLIN) {
 +
                    ssize_t x = read(pino[0].fd, buf, MAX);
 +
                    buf[x+1] = '\0';
 +
                    printf("%s", buf);
 +
                    pino[0].revents = 0;
 +
                }
 +
                else {
 +
                    ssize_t x = read(pino[1].fd, buf, MAX);
 +
                    buf[x+1] = '\0';
 +
                    printf("%s", buf);
 +
                    pino[1].revents = 0;
 +
                }
 +
            }
 +
            else if (ret == 2) {
 +
                ssize_t x = read(pino[0].fd, buf, MAX);
 +
                buf[x+1] = '\0';
 +
                printf("%s", buf);
 +
                pino[0].revents = 0;
 +
                x = read(pino[1].fd, buf, MAX);
 +
                buf[x+1] = '\0';
 +
                printf("%s", buf);
 +
                pino[1].revents = 0;
 +
            }
 +
        }
 +
    }
 +
}
 +
</source>

Latest revision as of 08:44, 10 May 2017

Link al testo


Esercizio 1

Soluzione di Stefano92

Scrivere un programma C denominato “invarg” che esegua il programma passato
come parametro invertendo gli argomenti.
Esempio:
invarg cat a b c
deve avere l'effetto di
cat c b a
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void usage()
{
	printf("usage: ./invarg.out EXEC_NAME [ARG1] [ARG2] ... [ARGN]\n");
}

int main(int argc,char* argv[])
{
   char* tmp_i,*tmp_x;
   int x=(argc-1),i=2;
   if (argc<2)
   {
   		usage();
   		return(1);
   }
   while(i<x)
   {
       tmp_i=argv[i];
       tmp_x=argv[x];
       argv[i]=tmp_x;
       argv[x]=tmp_i;
       i++;
       x--;
   }
	for(i=0;i<argc-1;i++)
		argv[i]=argv[i+1];
	
	argv[argc-1]=NULL;
	argc--;
	execvp(argv[0],argv);
        //equivalentemente avrei potuto lanciare execvp(argv[1],argv+1) evitando di modificare argv[]
	return 0;

}

stefano92

Soluzione di Maldus

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

int main(int argc , char* argv[]){
	char *nargv[argc-1] ;	/*nargv è il vettore degli argomenti da passare al programma da eseguire*/
	int i , j ;		/*puntatori che scorrono, rispettivamente, argv ed nargv per riempire correttamente nargv*/
	nargv[0] = argv[1] ;	/*il primo valore di nargv deve essere il programma chiamato, l'ultimo deve essere NULL*/
	nargv[argc-1] = NULL ;
	for( i = argc - 1 , j = 1 ; i > 1 , j < (argc - 1) ; i-- , j++ ) nargv[j] = argv[i] ;	/*metto in nargv (dal secondo elemento in poi) gli argomenti presenti 
in argv in ordine invertito*/
	execvp( nargv[0] , nargv  ) ;	/*eseguo il programma (il cui nome è contenuto in nargv[0]) passandogli nargv come vettore di parametri*/
	fprintf( stderr , "programma errato\n" ) ;	/*se ci troviamo in questo punto significa che la chiamata a execvp è fallita, probabilmente
 perchè il programma indicato non è stato trovato*/
	exit(1) ;
}

Soluzione di Eddy

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

void scambia_ordine(int argc, char **argv, int j);

int main(int argc , char* argv[])
{
	if (argc < 2) return 2;
	argv++;	argc--;
	scambia_ordine(argc, argv, 1);
	execvp(argv[0], argv);
	perror("execvp");
	return 3;	
}

/* piccola funzione ricorsiva che:
 * -memorizza in tmp gli argomenti dalla fine
 * -assegna ad argv in ordine inverso
 *
 *  non scambia il primo argomento
 */
void scambia_ordine(int argc, char **argv, int j)
{
	char *tmp;
	if (argc > 1){
		tmp = argv[argc-1];
		scambia_ordine (argc-1, argv, j+1);
		argv[j]=tmp;
	}

}

Eddy (talk) 21:00 Saturday, 22 November 2014 (CET)

Soluzione di GFede

#include <stdio.h>
#include <unistd.h>
#include <errno.h>

void scambia(int offset, int argc, char* argv[]);

int main(int argc, char* argv[])
{
   if(argc <= 1)
   {
      printf("Usage: invarg.exe command [arguments...]\n");
      return 2;
   }
   scambia(2, argc - 1, argv);

   execvp(argv[1], argv + 1);
   perror("execvp");
   return 1;
}

/**
 * Scambia le stringhe all'interno dell'array
 * void scambia
 * int offset     Indice da cui iniziare a scambiare
 * int argc       Numero di valori nell'array (Compreso l'offset)
 * char* argv[]   array di stringhe da scambiare
 */
void scambia(int offset, int argc, char* argv[])
{
   int i;
   char* tmp;
   for( i = offset; i < argc - i + offset; i++ )
   {
      tmp = argv[i];
      argv[i] = argv[argc - i + offset];
      argv[argc - i + offset] = tmp;
   }
}

Soluzione di LorenzoV

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

void swap(char **p, char **q){		// La swap modifica solo i puntatori
	char *tmp;
	tmp=*p;
	*p=*q;
	*q=tmp;
}

int main(int argc, char* argv[]){	
	char **begin, **end;
	if (argc<3){
		fprintf(stderr, "Usage:\n\t%s command ...arguments...\n", argv[0]);
		exit(1);	
	}	
	begin=argv+2;
	end=argv+argc-1;
	while (begin<end){		// Inverte i parametri passati al comando
		swap(begin, end);
		begin++;
		end--;
	}
	execvp(argv[1], argv+1);
	return 0;
}

--LorenzoV (talk) 18:35, 25 November 2014 (CET)



Soluzione di BoldrinD

#include <stdio.h>
#include <unistd.h>
#include <errno.h>

void invarg(int Qparametri, char* Rargv[], char* argv[]);

int main(int argc, char* argv[]){
	int Qparametri=argc-1;	
	char *Rargv[Qparametri];
	invarg(Qparametri, Rargv, argv);
	printf("%s\n","il nuovo vettore dei parametri è stato creato con successo");
   	execvp(Rargv[0], Rargv);
  	 perror("execvp");
   return 1;

}

void invarg(int Qparametri, char* Rargv[], char* argv[]){
	Rargv[0]=argv[1];
	Rargv[Qparametri]=NULL;
	int i=2;
		while(argv[i]!=NULL){
		Rargv[Qparametri-1]=(argv[i]);
		i++;
		Qparametri--;
		}

}


Soluzione di AleZ

#include <stdio.h>
#include <stdlib.h>
 
int main (int argc, char* argv[]) {
	if (argc == 1) {	// Non è stato passato alcun comando per la execvp
		fprintf(stderr, "Error: Segmentation fault\nUsage: [command] [arguments...]\n");
		return(EXIT_FAILURE);
	}
	char* tmp[argc];	// vettore che conterrà gli argomenti scambiati
	int i = 0;
	tmp[0] = argv[1];	// per convenzione il primo argomento è il programma chiamato
	tmp[argc-1] = (char*)NULL;	// come da manuale
	for (i = argc-2; i > 0; i--) tmp[i] = argv[(argc-i)];	// inverto gli argomenti 
	execvp(tmp[0], tmp);
	fprintf(stderr, "%s: command not found\n", argv[1]);	//execvp ha fallito
	return(EXIT_FAILURE);
}

--Ale (talk) 20:39, 1 December 2014 (CET)

Esercizio 2

Soluzione di Dado e Pierg

Scrivere un programma in linguaggio C che crei due named pipe (passate per argomento), le apra in lettura e
e copi in standard output i dati via via disponibili da ogni pipe.
Test di funzionamento: aprire tre finestre di emulazione terminale. Nella prima lanciare: mergepipe p1 p2, nella seconda:
cat >p1, nella terza cat>p2.
Tutto cio' che scriverete o nella seconda o nella terza finestra deve comparire nella prima.
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define MAX 2048

int main (int argc, char *argv[]) {
    if (argc < 3) {
        perror("Argomenti sbagliati");
    }
    else {
        struct pollfd pino [2];
        nfds_t n = 2;
        char buf[MAX];
        
        mkfifo(argv[1], 0666);
        mkfifo(argv[2], 0666);
        pino[0].fd = open(argv[1], O_RDONLY | O_NONBLOCK);
        pino[1].fd = open(argv[2], O_RDONLY | O_NONBLOCK);
        pino[0].events = POLLIN;
        pino[1].events = POLLIN;
        
        while(1) {
            int ret = poll(pino, n, 100);
            if (ret == 1) {
                if (pino[0].revents == POLLIN) {
                    ssize_t x = read(pino[0].fd, buf, MAX);
                    buf[x+1] = '\0';
                    printf("%s", buf);
                    pino[0].revents = 0;
                }
                else {
                    ssize_t x = read(pino[1].fd, buf, MAX);
                    buf[x+1] = '\0';
                    printf("%s", buf);
                    pino[1].revents = 0;
                }
            }
            else if (ret == 2) {
                ssize_t x = read(pino[0].fd, buf, MAX);
                buf[x+1] = '\0';
                printf("%s", buf);
                pino[0].revents = 0;
                x = read(pino[1].fd, buf, MAX);
                buf[x+1] = '\0';
                printf("%s", buf);
                pino[1].revents = 0;
            }
        }
    }
}