<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://so.v2.cs.unibo.it/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ale</id>
	<title>Sistemi Operativi - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://so.v2.cs.unibo.it/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ale"/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php/Special:Contributions/Ale"/>
	<updated>2026-05-04T09:22:12Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=1123</id>
		<title>Esercizio 1, prova pratica 20.01.2015</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=1123"/>
		<updated>2015-05-25T16:17:20Z</updated>

		<summary type="html">&lt;p&gt;Ale: /* Soluzione di AleZ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Scrivere un programma C di nome filepipe che abbia come unico parametro il pathnae di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con I rispettivi parametri, uno per riga.&lt;br /&gt;
Il programma deve mettere in esecuzione concorrente I due comandi in modo che l'output del primo venga fornito come input del secondo usando una pipe.&lt;br /&gt;
Il programma deve terminare quando entrambi I comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
      filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Soluzione di Stefano.zaniboni==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;error.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   int mypipe[2];&lt;br /&gt;
   FILE *stream;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
&lt;br /&gt;
   /*controllo il numero degli argomenti passati*/&lt;br /&gt;
   if(argc != 2){&lt;br /&gt;
      fprintf(stderr, &amp;quot;no such arguments \n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro il file in sola lettura*/&lt;br /&gt;
   stream=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(stream==NULL){&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro la pipe*/&lt;br /&gt;
   if(pipe(mypipe) == -1){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Error pipe\n&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(1); /*chiudo lo stdout*/&lt;br /&gt;
      dup(mypipe[1]); /*rimpiazzo lo stdout con la pipe*/&lt;br /&gt;
      close(mypipe[0]); /*chiudo la read della pipe*/&lt;br /&gt;
      close(mypipe[1]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
&lt;br /&gt;
      char *lines[2]={line, NULL};&lt;br /&gt;
      execvp(argv[1], lines);&lt;br /&gt;
      perror(&amp;quot;execvp failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(0); /*chiudo lo stdin*/&lt;br /&gt;
      dup(mypipe[0]); /*rimpiazzo lo stdin con la pipe read*/&lt;br /&gt;
      close(mypipe[1]); /*chiudo la write della pipe*/&lt;br /&gt;
      close(mypipe[0]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
      execvp(argv[1], &amp;amp;line);&lt;br /&gt;
      perror(&amp;quot;execvp 2 failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   close(mypipe[0]);&lt;br /&gt;
   close(mypipe[1]);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   free(line);&lt;br /&gt;
   fclose(stream);&lt;br /&gt;
   exit (0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il codice ho provato a testarlo ma la shell mi restituisce sempre su entrambe le exec &amp;quot;Permission Denied&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nota del Prof: execvp(argv[1], &amp;amp;line) tenta di eseguire il file di testo (argv[1]) [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 16:04, 7 April 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Soluzione di AleZ==&lt;br /&gt;
'''Nota''': ho messo la soluzione di questo esercizio solamente perché non ne ho trovata sulla wiki una versione funzionante. Non so se sia stato corretto in classe e/o se sia stato già postato da qualche altra parte. Nel caso mi scuso.&lt;br /&gt;
&lt;br /&gt;
Due versioni: una utilizzando la libreria s2argv e la funzione getline, l'altra senza entrambe.&lt;br /&gt;
&lt;br /&gt;
'''Versione 1 (con s2argv e getline)'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;quot;/home/alessandro/Scrivania/s2argv/s2argv.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
	//check arguments&lt;br /&gt;
	if (argc != 2) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error: Expected 1 parameter.\n&amp;quot;&lt;br /&gt;
			&amp;quot;Usage: %s &amp;lt;pathname&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	FILE *f;&lt;br /&gt;
	size_t n;&lt;br /&gt;
	int fd[2];&lt;br /&gt;
	char *command = NULL;&lt;br /&gt;
&lt;br /&gt;
	f = fopen(argv[1], &amp;quot;rt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	//get first command&lt;br /&gt;
	getline(&amp;amp;command, &amp;amp;n, f);&lt;br /&gt;
&lt;br /&gt;
	//create the pipe&lt;br /&gt;
	if (pipe(fd) == -1) {&lt;br /&gt;
		perror(&amp;quot;pipe&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//create child process&lt;br /&gt;
	switch (fork()) {&lt;br /&gt;
		case -1:&lt;br /&gt;
		perror(&amp;quot;fork&amp;quot;);&lt;br /&gt;
		break;&lt;br /&gt;
&lt;br /&gt;
		case 0:	//child process&lt;br /&gt;
		close(fd[0]);&lt;br /&gt;
		dup2(fd[1], STDOUT_FILENO); //redirect STDOUT to write to fd[1]-&amp;gt;fd[0]&lt;br /&gt;
		execsp(command);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
&lt;br /&gt;
		default:&lt;br /&gt;
		close(fd[1]);&lt;br /&gt;
		dup2(fd[0], STDIN_FILENO);	//redirect STDIN to read from fd[0]&amp;lt;-fd[1]&lt;br /&gt;
		wait(NULL);	//wait for child to terminate&lt;br /&gt;
		lseek (fd[1], 0, SEEK_SET);	//reposition STDOUT read offset to the start&lt;br /&gt;
		free(command);&lt;br /&gt;
		command = NULL;&lt;br /&gt;
		getline(&amp;amp;command, &amp;amp;n, f);	//get second command&lt;br /&gt;
		execsp(command);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Versione 2 (senza s2argv e getline)'''&lt;br /&gt;
&lt;br /&gt;
'''Nota 2''': Nella versione senza s2argv e getline, tutto funziona, però ho un &amp;quot;problema&amp;quot; incredibilmente strano: se cancello la variabile &amp;lt;code&amp;gt;char sono_forse_inutile[4096]&amp;lt;/code&amp;gt; dichiarata a riga 48, a run-time il programma restituisce segmentation fault. Quella variabile era stata introdotta in precedenza inizialmente per diversa scelta implementativa, e in seguito mantenuta per scopi di debug. Terminata la sua utilità, avevo pensato di rimuoverla, ma a quanto pare non mi è permesso, e il motivo mi sfugge davvero.&lt;br /&gt;
&lt;br /&gt;
La funzione fsplit è stata realizzata prendendo largamente spunto da un'altra funzione trovata su stackoverflow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char **fsplit(char **res, char str[]) {&lt;br /&gt;
	char *p = strtok(str, &amp;quot; &amp;quot;);&lt;br /&gt;
	int n_spaces = 0;&lt;br /&gt;
&lt;br /&gt;
	/* split string and append tokens to &amp;quot;res&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
	while (p) {&lt;br /&gt;
		n_spaces++;&lt;br /&gt;
		res = realloc(res, sizeof(char*) * n_spaces);&lt;br /&gt;
		if (res == NULL)&lt;br /&gt;
			exit(EXIT_FAILURE);	//allocation failed&lt;br /&gt;
		res[n_spaces - 1] = p;&lt;br /&gt;
		p = strtok(NULL, &amp;quot; &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* realloc one extra element for the last NULL */&lt;br /&gt;
&lt;br /&gt;
	res = realloc(res, sizeof(char*) * (n_spaces + 1));&lt;br /&gt;
	res[n_spaces] = NULL;&lt;br /&gt;
&lt;br /&gt;
	// debug purpose&lt;br /&gt;
	/* int i;&lt;br /&gt;
	for (i = 0; i &amp;lt; (n_spaces + 1); i++) {&lt;br /&gt;
		printf (&amp;quot;res[%d] = %s\n&amp;quot;, i, res[i]);&lt;br /&gt;
	}*/&lt;br /&gt;
&lt;br /&gt;
	return res;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char* argv[]) {&lt;br /&gt;
	//check arguments&lt;br /&gt;
	if (argc != 2) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error: Expected 1 parameter.\n&amp;quot;&lt;br /&gt;
			&amp;quot;Usage: %s &amp;lt;pathname&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	char *pathname = argv[1];&lt;br /&gt;
	FILE *f;&lt;br /&gt;
	struct stat f_info;&lt;br /&gt;
	char command_one[100], command_two[100], sono_forse_inutile[4096];&lt;br /&gt;
	int fd[2], file_desc_out;&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
&lt;br /&gt;
	f = fopen(pathname, &amp;quot;rt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	//check if file exists&lt;br /&gt;
	if(lstat(pathname, &amp;amp;f_info) == -1) {&lt;br /&gt;
		perror(&amp;quot;stat&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//read the commands from the first two lines - ignore the other lines&lt;br /&gt;
	if ( (fgets(command_one, 100, f) == NULL) ||&lt;br /&gt;
		(fgets(command_two, 100, f) == NULL) ) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error while reading text from %s.&amp;quot;, argv[1]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose(f);&lt;br /&gt;
&lt;br /&gt;
	//remove the \n patterns from the command strings&lt;br /&gt;
	strtok(command_one, &amp;quot;\n&amp;quot;);&lt;br /&gt;
	strtok(command_two, &amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	/*split the command strings in arrays, where&lt;br /&gt;
		- comm[0] is the command&lt;br /&gt;
		- comm[1], comm[2], etc, are the arguments*/&lt;br /&gt;
&lt;br /&gt;
	char **commv_1 = fsplit(commv_1, command_one);&lt;br /&gt;
	char **commv_2 = fsplit(commv_2, command_two);&lt;br /&gt;
&lt;br /&gt;
	//create the pipe&lt;br /&gt;
	//remember: fd[0] reads and fd[1] writes&lt;br /&gt;
	if (pipe(fd) == -1) {&lt;br /&gt;
		perror(&amp;quot;pipe&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//create the child and get its pid&lt;br /&gt;
	if ( (pid = fork()) == -1) {&lt;br /&gt;
		perror(&amp;quot;fork&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (pid == 0) {	//child&lt;br /&gt;
		dup2(fd[1], STDOUT_FILENO);	//connect pipe from execvp to standard output&lt;br /&gt;
		close(fd[0]);	//close read side from parent&lt;br /&gt;
		execvp(commv_1[0], commv_1);&lt;br /&gt;
		perror(commv_1[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	} else {&lt;br /&gt;
		close(fd[1]);	//close write side from child&lt;br /&gt;
		dup2(fd[0], file_desc_out);&lt;br /&gt;
		char *path;&lt;br /&gt;
&lt;br /&gt;
		// obtain absolute path of the reader-side file descriptor of the pipe&lt;br /&gt;
		realpath(&amp;quot;/proc/self/fd/file_desc_out&amp;quot;, path);&lt;br /&gt;
&lt;br /&gt;
		commv_2[1] = path;	//set the obtained path as argument for command 2&lt;br /&gt;
		wait(NULL);	//wait for child to terminate&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	execvp(commv_2[0], commv_2);&lt;br /&gt;
	perror(commv_2[0]);&lt;br /&gt;
	return(EXIT_FAILURE);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:Ale|Ale]] ([[User talk:Ale|talk]]) 14:01, 25 May 2015 (CEST)&lt;/div&gt;</summary>
		<author><name>Ale</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=1122</id>
		<title>Esercizio 1, prova pratica 20.01.2015</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=1122"/>
		<updated>2015-05-25T16:14:41Z</updated>

		<summary type="html">&lt;p&gt;Ale: /* Soluzione di AleZ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Scrivere un programma C di nome filepipe che abbia come unico parametro il pathnae di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con I rispettivi parametri, uno per riga.&lt;br /&gt;
Il programma deve mettere in esecuzione concorrente I due comandi in modo che l'output del primo venga fornito come input del secondo usando una pipe.&lt;br /&gt;
Il programma deve terminare quando entrambi I comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
      filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Soluzione di Stefano.zaniboni==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;error.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   int mypipe[2];&lt;br /&gt;
   FILE *stream;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
&lt;br /&gt;
   /*controllo il numero degli argomenti passati*/&lt;br /&gt;
   if(argc != 2){&lt;br /&gt;
      fprintf(stderr, &amp;quot;no such arguments \n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro il file in sola lettura*/&lt;br /&gt;
   stream=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(stream==NULL){&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro la pipe*/&lt;br /&gt;
   if(pipe(mypipe) == -1){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Error pipe\n&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(1); /*chiudo lo stdout*/&lt;br /&gt;
      dup(mypipe[1]); /*rimpiazzo lo stdout con la pipe*/&lt;br /&gt;
      close(mypipe[0]); /*chiudo la read della pipe*/&lt;br /&gt;
      close(mypipe[1]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
&lt;br /&gt;
      char *lines[2]={line, NULL};&lt;br /&gt;
      execvp(argv[1], lines);&lt;br /&gt;
      perror(&amp;quot;execvp failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(0); /*chiudo lo stdin*/&lt;br /&gt;
      dup(mypipe[0]); /*rimpiazzo lo stdin con la pipe read*/&lt;br /&gt;
      close(mypipe[1]); /*chiudo la write della pipe*/&lt;br /&gt;
      close(mypipe[0]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
      execvp(argv[1], &amp;amp;line);&lt;br /&gt;
      perror(&amp;quot;execvp 2 failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   close(mypipe[0]);&lt;br /&gt;
   close(mypipe[1]);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   free(line);&lt;br /&gt;
   fclose(stream);&lt;br /&gt;
   exit (0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il codice ho provato a testarlo ma la shell mi restituisce sempre su entrambe le exec &amp;quot;Permission Denied&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nota del Prof: execvp(argv[1], &amp;amp;line) tenta di eseguire il file di testo (argv[1]) [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 16:04, 7 April 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Soluzione di AleZ==&lt;br /&gt;
'''Nota''': ho messo la soluzione di questo esercizio solamente perché non ne ho trovata sulla wiki una versione funzionante. Non so se sia stato corretto in classe e/o se sia stato già postato da qualche altra parte. Nel caso mi scuso.&lt;br /&gt;
&lt;br /&gt;
Due versioni: una utilizzando la libreria s2argv e la funzione getline, l'altra senza entrambe.&lt;br /&gt;
&lt;br /&gt;
'''Versione 1 (con s2argv e getline)'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;quot;/home/alessandro/Scrivania/s2argv/s2argv.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
	//check arguments&lt;br /&gt;
	if (argc != 2) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error: Expected 1 parameter.\n&amp;quot;&lt;br /&gt;
			&amp;quot;Usage: %s &amp;lt;pathname&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	FILE *f;&lt;br /&gt;
	size_t n;&lt;br /&gt;
	int fd[2];&lt;br /&gt;
	char *command = NULL;&lt;br /&gt;
&lt;br /&gt;
	f = fopen(argv[1], &amp;quot;rt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	//get first command&lt;br /&gt;
	getline(&amp;amp;command, &amp;amp;n, f);&lt;br /&gt;
&lt;br /&gt;
	//create the pipe&lt;br /&gt;
	if (pipe(fd) == -1) {&lt;br /&gt;
		perror(&amp;quot;pipe&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//create child process&lt;br /&gt;
	switch (fork()) {&lt;br /&gt;
		case -1:&lt;br /&gt;
		perror(&amp;quot;fork&amp;quot;);&lt;br /&gt;
		break;&lt;br /&gt;
&lt;br /&gt;
		case 0:	//child process&lt;br /&gt;
		close(fd[0]);&lt;br /&gt;
		dup2(fd[1], STDOUT_FILENO); //redirect STDOUT to write to fd[1]-&amp;gt;fd[0]&lt;br /&gt;
		execsp(command);&lt;br /&gt;
		exit(1);&lt;br /&gt;
&lt;br /&gt;
		default:&lt;br /&gt;
		close(fd[1]);&lt;br /&gt;
		dup2(fd[0], STDIN_FILENO);	//redirect STDIN to read from fd[0]&amp;lt;-fd[1]&lt;br /&gt;
		wait(NULL);	//wait for child to terminate&lt;br /&gt;
		lseek (fd[1], 0, SEEK_SET);	//reposition STDOUT read offset to the start&lt;br /&gt;
		free(command);&lt;br /&gt;
		command = NULL;&lt;br /&gt;
		getline(&amp;amp;command, &amp;amp;n, f);	//get second command&lt;br /&gt;
		execsp(command);&lt;br /&gt;
		exit(1);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Versione 2 (senza s2argv e getline)'''&lt;br /&gt;
&lt;br /&gt;
'''Nota 2''': Nella versione senza s2argv e getline, tutto funziona, però ho un &amp;quot;problema&amp;quot; incredibilmente strano: se cancello la variabile &amp;lt;code&amp;gt;char sono_forse_inutile[4096]&amp;lt;/code&amp;gt; dichiarata a riga 48, a run-time il programma restituisce segmentation fault. Quella variabile era stata introdotta in precedenza inizialmente per diversa scelta implementativa, e in seguito mantenuta per scopi di debug. Terminata la sua utilità, avevo pensato di rimuoverla, ma a quanto pare non mi è permesso, e il motivo mi sfugge davvero.&lt;br /&gt;
&lt;br /&gt;
La funzione fsplit è stata realizzata prendendo largamente spunto da un'altra funzione trovata su stackoverflow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char **fsplit(char **res, char str[]) {&lt;br /&gt;
	char *p = strtok(str, &amp;quot; &amp;quot;);&lt;br /&gt;
	int n_spaces = 0;&lt;br /&gt;
&lt;br /&gt;
	/* split string and append tokens to &amp;quot;res&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
	while (p) {&lt;br /&gt;
		n_spaces++;&lt;br /&gt;
		res = realloc(res, sizeof(char*) * n_spaces);&lt;br /&gt;
		if (res == NULL)&lt;br /&gt;
			exit(EXIT_FAILURE);	//allocation failed&lt;br /&gt;
		res[n_spaces - 1] = p;&lt;br /&gt;
		p = strtok(NULL, &amp;quot; &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* realloc one extra element for the last NULL */&lt;br /&gt;
&lt;br /&gt;
	res = realloc(res, sizeof(char*) * (n_spaces + 1));&lt;br /&gt;
	res[n_spaces] = NULL;&lt;br /&gt;
&lt;br /&gt;
	// debug purpose&lt;br /&gt;
	/* int i;&lt;br /&gt;
	for (i = 0; i &amp;lt; (n_spaces + 1); i++) {&lt;br /&gt;
		printf (&amp;quot;res[%d] = %s\n&amp;quot;, i, res[i]);&lt;br /&gt;
	}*/&lt;br /&gt;
&lt;br /&gt;
	return res;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char* argv[]) {&lt;br /&gt;
	//check arguments&lt;br /&gt;
	if (argc != 2) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error: Expected 1 parameter.\n&amp;quot;&lt;br /&gt;
			&amp;quot;Usage: %s &amp;lt;pathname&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	char *pathname = argv[1];&lt;br /&gt;
	FILE *f;&lt;br /&gt;
	struct stat f_info;&lt;br /&gt;
	char command_one[100], command_two[100], sono_forse_inutile[4096];&lt;br /&gt;
	int fd[2], file_desc_out;&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
&lt;br /&gt;
	f = fopen(pathname, &amp;quot;rt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	//check if file exists&lt;br /&gt;
	if(lstat(pathname, &amp;amp;f_info) == -1) {&lt;br /&gt;
		perror(&amp;quot;stat&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//read the commands from the first two lines - ignore the other lines&lt;br /&gt;
	if ( (fgets(command_one, 100, f) == NULL) ||&lt;br /&gt;
		(fgets(command_two, 100, f) == NULL) ) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error while reading text from %s.&amp;quot;, argv[1]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose(f);&lt;br /&gt;
&lt;br /&gt;
	//remove the \n patterns from the command strings&lt;br /&gt;
	strtok(command_one, &amp;quot;\n&amp;quot;);&lt;br /&gt;
	strtok(command_two, &amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	/*split the command strings in arrays, where&lt;br /&gt;
		- comm[0] is the command&lt;br /&gt;
		- comm[1], comm[2], etc, are the arguments*/&lt;br /&gt;
&lt;br /&gt;
	char **commv_1 = fsplit(commv_1, command_one);&lt;br /&gt;
	char **commv_2 = fsplit(commv_2, command_two);&lt;br /&gt;
&lt;br /&gt;
	//create the pipe&lt;br /&gt;
	//remember: fd[0] reads and fd[1] writes&lt;br /&gt;
	if (pipe(fd) == -1) {&lt;br /&gt;
		perror(&amp;quot;pipe&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//create the child and get its pid&lt;br /&gt;
	if ( (pid = fork()) == -1) {&lt;br /&gt;
		perror(&amp;quot;fork&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (pid == 0) {	//child&lt;br /&gt;
		dup2(fd[1], STDOUT_FILENO);	//connect pipe from execvp to standard output&lt;br /&gt;
		close(fd[0]);	//close read side from parent&lt;br /&gt;
		execvp(commv_1[0], commv_1);&lt;br /&gt;
		perror(commv_1[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	} else {&lt;br /&gt;
		close(fd[1]);	//close write side from child&lt;br /&gt;
		dup2(fd[0], file_desc_out);&lt;br /&gt;
		char *path;&lt;br /&gt;
&lt;br /&gt;
		// obtain absolute path of the reader-side file descriptor of the pipe&lt;br /&gt;
		realpath(&amp;quot;/proc/self/fd/file_desc_out&amp;quot;, path);&lt;br /&gt;
&lt;br /&gt;
		commv_2[1] = path;	//set the obtained path as argument for command 2&lt;br /&gt;
		wait(NULL);	//wait for child to terminate&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	execvp(commv_2[0], commv_2);&lt;br /&gt;
	perror(commv_2[0]);&lt;br /&gt;
	return(EXIT_FAILURE);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:Ale|Ale]] ([[User talk:Ale|talk]]) 14:01, 25 May 2015 (CEST)&lt;/div&gt;</summary>
		<author><name>Ale</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=1121</id>
		<title>Esercizio 1, prova pratica 20.01.2015</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=1121"/>
		<updated>2015-05-25T13:55:56Z</updated>

		<summary type="html">&lt;p&gt;Ale: /* Soluzione di AleZ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Scrivere un programma C di nome filepipe che abbia come unico parametro il pathnae di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con I rispettivi parametri, uno per riga.&lt;br /&gt;
Il programma deve mettere in esecuzione concorrente I due comandi in modo che l'output del primo venga fornito come input del secondo usando una pipe.&lt;br /&gt;
Il programma deve terminare quando entrambi I comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
      filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Soluzione di Stefano.zaniboni==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;error.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   int mypipe[2];&lt;br /&gt;
   FILE *stream;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
&lt;br /&gt;
   /*controllo il numero degli argomenti passati*/&lt;br /&gt;
   if(argc != 2){&lt;br /&gt;
      fprintf(stderr, &amp;quot;no such arguments \n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro il file in sola lettura*/&lt;br /&gt;
   stream=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(stream==NULL){&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro la pipe*/&lt;br /&gt;
   if(pipe(mypipe) == -1){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Error pipe\n&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(1); /*chiudo lo stdout*/&lt;br /&gt;
      dup(mypipe[1]); /*rimpiazzo lo stdout con la pipe*/&lt;br /&gt;
      close(mypipe[0]); /*chiudo la read della pipe*/&lt;br /&gt;
      close(mypipe[1]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
&lt;br /&gt;
      char *lines[2]={line, NULL};&lt;br /&gt;
      execvp(argv[1], lines);&lt;br /&gt;
      perror(&amp;quot;execvp failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(0); /*chiudo lo stdin*/&lt;br /&gt;
      dup(mypipe[0]); /*rimpiazzo lo stdin con la pipe read*/&lt;br /&gt;
      close(mypipe[1]); /*chiudo la write della pipe*/&lt;br /&gt;
      close(mypipe[0]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
      execvp(argv[1], &amp;amp;line);&lt;br /&gt;
      perror(&amp;quot;execvp 2 failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   close(mypipe[0]);&lt;br /&gt;
   close(mypipe[1]);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   free(line);&lt;br /&gt;
   fclose(stream);&lt;br /&gt;
   exit (0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il codice ho provato a testarlo ma la shell mi restituisce sempre su entrambe le exec &amp;quot;Permission Denied&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nota del Prof: execvp(argv[1], &amp;amp;line) tenta di eseguire il file di testo (argv[1]) [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 16:04, 7 April 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Soluzione di AleZ==&lt;br /&gt;
'''Nota''': ho messo la soluzione di questo esercizio solamente perché non ne ho trovata sulla wiki una versione funzionante. Non so se sia stato corretto in classe e/o se sia stato già postato da qualche altra parte. Nel caso mi scuso.&lt;br /&gt;
&lt;br /&gt;
'''Nota 2''': La mia versione dovrebbe funzionare, però ho un &amp;quot;problema&amp;quot; incredibilmente strano: se cancello la variabile &amp;lt;code&amp;gt;char sono_forse_inutile[4096]&amp;lt;/code&amp;gt; dichiarata a riga 48, a run-time il programma restituisce segmentation fault. Quella variabile era stata introdotta in precedenza inizialmente per diversa scelta implementativa, e in seguito mantenuta per scopi di debug. Terminata la sua utilità, avevo pensato di rimuoverla, ma a quanto pare non mi è permesso, e il motivo mi sfugge davvero.&lt;br /&gt;
&lt;br /&gt;
La funzione fsplit è stata realizzata prendendo largamente spunto da un'altra funzione trovata su stackoverflow.&lt;br /&gt;
&lt;br /&gt;
Ho cercato di non usare la libreria s2argv (ovviamente complicandomi la vita).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char **fsplit(char **res, char str[]) {&lt;br /&gt;
	char *p = strtok(str, &amp;quot; &amp;quot;);&lt;br /&gt;
	int n_spaces = 0;&lt;br /&gt;
&lt;br /&gt;
	/* split string and append tokens to &amp;quot;res&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
	while (p) {&lt;br /&gt;
		n_spaces++;&lt;br /&gt;
		res = realloc(res, sizeof(char*) * n_spaces);&lt;br /&gt;
		if (res == NULL)&lt;br /&gt;
			exit(EXIT_FAILURE);	//allocation failed&lt;br /&gt;
		res[n_spaces - 1] = p;&lt;br /&gt;
		p = strtok(NULL, &amp;quot; &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* realloc one extra element for the last NULL */&lt;br /&gt;
&lt;br /&gt;
	res = realloc(res, sizeof(char*) * (n_spaces + 1));&lt;br /&gt;
	res[n_spaces] = NULL;&lt;br /&gt;
&lt;br /&gt;
	// debug purpose&lt;br /&gt;
	/* int i;&lt;br /&gt;
	for (i = 0; i &amp;lt; (n_spaces + 1); i++) {&lt;br /&gt;
		printf (&amp;quot;res[%d] = %s\n&amp;quot;, i, res[i]);&lt;br /&gt;
	}*/&lt;br /&gt;
&lt;br /&gt;
	return res;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char* argv[]) {&lt;br /&gt;
	//check arguments&lt;br /&gt;
	if (argc != 2) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error: Expected 1 parameter.\n&amp;quot;&lt;br /&gt;
			&amp;quot;Usage: %s &amp;lt;pathname&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	char *pathname = argv[1];&lt;br /&gt;
	FILE *f;&lt;br /&gt;
	struct stat f_info;&lt;br /&gt;
	char command_one[100], command_two[100], sono_forse_inutile[4096];&lt;br /&gt;
	int fd[2], file_desc_out;&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
&lt;br /&gt;
	f = fopen(pathname, &amp;quot;rt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	//check if file exists&lt;br /&gt;
	if(lstat(pathname, &amp;amp;f_info) == -1) {&lt;br /&gt;
		perror(&amp;quot;stat&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//read the commands from the first two lines - ignore the other lines&lt;br /&gt;
	if ( (fgets(command_one, 100, f) == NULL) ||&lt;br /&gt;
		(fgets(command_two, 100, f) == NULL) ) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error while reading text from %s.&amp;quot;, argv[1]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose(f);&lt;br /&gt;
&lt;br /&gt;
	//remove the \n patterns from the command strings&lt;br /&gt;
	strtok(command_one, &amp;quot;\n&amp;quot;);&lt;br /&gt;
	strtok(command_two, &amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	/*split the command strings in arrays, where&lt;br /&gt;
		- comm[0] is the command&lt;br /&gt;
		- comm[1], comm[2], etc, are the arguments*/&lt;br /&gt;
&lt;br /&gt;
	char **commv_1 = fsplit(commv_1, command_one);&lt;br /&gt;
	char **commv_2 = fsplit(commv_2, command_two);&lt;br /&gt;
&lt;br /&gt;
	//create the pipe&lt;br /&gt;
	//remember: fd[0] reads and fd[1] writes&lt;br /&gt;
	if (pipe(fd) == -1) {&lt;br /&gt;
		perror(&amp;quot;pipe&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//create the child and get its pid&lt;br /&gt;
	if ( (pid = fork()) == -1) {&lt;br /&gt;
		perror(&amp;quot;fork&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (pid == 0) {	//child&lt;br /&gt;
		dup2(fd[1], STDOUT_FILENO);	//connect pipe from execvp to standard output&lt;br /&gt;
		close(fd[0]);	//close read side from parent&lt;br /&gt;
		execvp(commv_1[0], commv_1);&lt;br /&gt;
		perror(commv_1[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	} else {&lt;br /&gt;
		close(fd[1]);	//close write side from child&lt;br /&gt;
		dup2(fd[0], file_desc_out);&lt;br /&gt;
		char *path;&lt;br /&gt;
&lt;br /&gt;
		// obtain absolute path of the reader-side file descriptor of the pipe&lt;br /&gt;
		realpath(&amp;quot;/proc/self/fd/file_desc_out&amp;quot;, path);&lt;br /&gt;
&lt;br /&gt;
		commv_2[1] = path;	//set the obtained path as argument for command 2&lt;br /&gt;
		wait(NULL);	//wait for child to terminate&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	execvp(commv_2[0], commv_2);&lt;br /&gt;
	perror(commv_2[0]);&lt;br /&gt;
	return(EXIT_FAILURE);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:Ale|Ale]] ([[User talk:Ale|talk]]) 14:01, 25 May 2015 (CEST)&lt;/div&gt;</summary>
		<author><name>Ale</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=1120</id>
		<title>Esercizio 1, prova pratica 20.01.2015</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=1120"/>
		<updated>2015-05-25T12:01:26Z</updated>

		<summary type="html">&lt;p&gt;Ale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Scrivere un programma C di nome filepipe che abbia come unico parametro il pathnae di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con I rispettivi parametri, uno per riga.&lt;br /&gt;
Il programma deve mettere in esecuzione concorrente I due comandi in modo che l'output del primo venga fornito come input del secondo usando una pipe.&lt;br /&gt;
Il programma deve terminare quando entrambi I comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
      filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Soluzione di Stefano.zaniboni==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;error.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   int mypipe[2];&lt;br /&gt;
   FILE *stream;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
&lt;br /&gt;
   /*controllo il numero degli argomenti passati*/&lt;br /&gt;
   if(argc != 2){&lt;br /&gt;
      fprintf(stderr, &amp;quot;no such arguments \n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro il file in sola lettura*/&lt;br /&gt;
   stream=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(stream==NULL){&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro la pipe*/&lt;br /&gt;
   if(pipe(mypipe) == -1){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Error pipe\n&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(1); /*chiudo lo stdout*/&lt;br /&gt;
      dup(mypipe[1]); /*rimpiazzo lo stdout con la pipe*/&lt;br /&gt;
      close(mypipe[0]); /*chiudo la read della pipe*/&lt;br /&gt;
      close(mypipe[1]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
&lt;br /&gt;
      char *lines[2]={line, NULL};&lt;br /&gt;
      execvp(argv[1], lines);&lt;br /&gt;
      perror(&amp;quot;execvp failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(0); /*chiudo lo stdin*/&lt;br /&gt;
      dup(mypipe[0]); /*rimpiazzo lo stdin con la pipe read*/&lt;br /&gt;
      close(mypipe[1]); /*chiudo la write della pipe*/&lt;br /&gt;
      close(mypipe[0]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
      execvp(argv[1], &amp;amp;line);&lt;br /&gt;
      perror(&amp;quot;execvp 2 failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   close(mypipe[0]);&lt;br /&gt;
   close(mypipe[1]);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   free(line);&lt;br /&gt;
   fclose(stream);&lt;br /&gt;
   exit (0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il codice ho provato a testarlo ma la shell mi restituisce sempre su entrambe le exec &amp;quot;Permission Denied&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nota del Prof: execvp(argv[1], &amp;amp;line) tenta di eseguire il file di testo (argv[1]) [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 16:04, 7 April 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Soluzione di AleZ==&lt;br /&gt;
'''Nota''': ho messo la soluzione di questo esercizio solamente perché non ne ho trovata sulla wiki una versione funzionante. Non so se sia stato corretto in classe e/o se sia stato già postato da qualche altra parte. Nel caso mi scuso.&lt;br /&gt;
&lt;br /&gt;
'''Nota 2''': La mia versione dovrebbe funzionare, però ho un &amp;quot;problema&amp;quot; incredibilmente strano: se cancello la variabile &amp;lt;code&amp;gt;char sono_forse_inutile[4096]&amp;lt;/code&amp;gt; dichiarata a riga 48, a run-time il programma restituisce segmentation fault. Quella variabile era stata introdotta in precedenza inizialmente per diversa scelta implementativa, e in seguito mantenuta per scopi di debug. Terminata la sua utilità, avevo pensato di rimuoverla, ma a quanto pare non mi è permesso, e il motivo mi sfugge davvero.&lt;br /&gt;
&lt;br /&gt;
La funzione fsplit è stata realizzata prendendo largamente spunto da un'altra funzione trovata su stackoverflow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char **fsplit(char **res, char str[]) {&lt;br /&gt;
	char *p = strtok(str, &amp;quot; &amp;quot;);&lt;br /&gt;
	int n_spaces = 0;&lt;br /&gt;
&lt;br /&gt;
	/* split string and append tokens to &amp;quot;res&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
	while (p) {&lt;br /&gt;
		n_spaces++;&lt;br /&gt;
		res = realloc(res, sizeof(char*) * n_spaces);&lt;br /&gt;
		if (res == NULL)&lt;br /&gt;
			exit(EXIT_FAILURE);	//allocation failed&lt;br /&gt;
		res[n_spaces - 1] = p;&lt;br /&gt;
		p = strtok(NULL, &amp;quot; &amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* realloc one extra element for the last NULL */&lt;br /&gt;
&lt;br /&gt;
	res = realloc(res, sizeof(char*) * (n_spaces + 1));&lt;br /&gt;
	res[n_spaces] = NULL;&lt;br /&gt;
&lt;br /&gt;
	// debug purpose&lt;br /&gt;
	/* int i;&lt;br /&gt;
	for (i = 0; i &amp;lt; (n_spaces + 1); i++) {&lt;br /&gt;
		printf (&amp;quot;res[%d] = %s\n&amp;quot;, i, res[i]);&lt;br /&gt;
	}*/&lt;br /&gt;
&lt;br /&gt;
	return res;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char* argv[]) {&lt;br /&gt;
	//check arguments&lt;br /&gt;
	if (argc != 2) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error: Expected 1 parameter.\n&amp;quot;&lt;br /&gt;
			&amp;quot;Usage: %s &amp;lt;pathname&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	char *pathname = argv[1];&lt;br /&gt;
	FILE *f;&lt;br /&gt;
	struct stat f_info;&lt;br /&gt;
	char command_one[100], command_two[100], sono_forse_inutile[4096];&lt;br /&gt;
	int fd[2], file_desc_out;&lt;br /&gt;
	pid_t pid;&lt;br /&gt;
&lt;br /&gt;
	f = fopen(pathname, &amp;quot;rt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	//check if file exists&lt;br /&gt;
	if(lstat(pathname, &amp;amp;f_info) == -1) {&lt;br /&gt;
		perror(&amp;quot;stat&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//read the commands from the first two lines - ignore the other lines&lt;br /&gt;
	if ( (fgets(command_one, 100, f) == NULL) ||&lt;br /&gt;
		(fgets(command_two, 100, f) == NULL) ) {&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error while reading text from %s.&amp;quot;, argv[1]);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	fclose(f);&lt;br /&gt;
&lt;br /&gt;
	//remove the \n patterns from the command strings&lt;br /&gt;
	strtok(command_one, &amp;quot;\n&amp;quot;);&lt;br /&gt;
	strtok(command_two, &amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	/*split the command strings in arrays, where&lt;br /&gt;
		- comm[0] is the command&lt;br /&gt;
		- comm[1], comm[2], etc, are the arguments*/&lt;br /&gt;
&lt;br /&gt;
	char **commv_1 = fsplit(commv_1, command_one);&lt;br /&gt;
	char **commv_2 = fsplit(commv_2, command_two);&lt;br /&gt;
&lt;br /&gt;
	//create the pipe&lt;br /&gt;
	//remember: fd[0] reads and fd[1] writes&lt;br /&gt;
	if (pipe(fd) == -1) {&lt;br /&gt;
		perror(&amp;quot;pipe&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//create the child and get its pid&lt;br /&gt;
	if ( (pid = fork()) == -1) {&lt;br /&gt;
		perror(&amp;quot;fork&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (pid == 0) {	//child&lt;br /&gt;
		dup2(fd[1], STDOUT_FILENO);	//connect pipe from execvp to standard output&lt;br /&gt;
		close(fd[0]);	//close read side from parent&lt;br /&gt;
		execvp(commv_1[0], commv_1);&lt;br /&gt;
		perror(commv_1[0]);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	} else {&lt;br /&gt;
		close(fd[1]);	//close write side from child&lt;br /&gt;
		dup2(fd[0], file_desc_out);&lt;br /&gt;
		char *path;&lt;br /&gt;
&lt;br /&gt;
		// obtain absolute path of the reader-side file descriptor of the pipe&lt;br /&gt;
		realpath(&amp;quot;/proc/self/fd/file_desc_out&amp;quot;, path);&lt;br /&gt;
&lt;br /&gt;
		commv_2[1] = path;	//set the obtained path as argument for command 2&lt;br /&gt;
		wait(NULL);	//wait for child to terminate&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	execvp(commv_2[0], commv_2);&lt;br /&gt;
	perror(commv_2[0]);&lt;br /&gt;
	return(EXIT_FAILURE);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:Ale|Ale]] ([[User talk:Ale|talk]]) 14:01, 25 May 2015 (CEST)&lt;/div&gt;</summary>
		<author><name>Ale</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_12/02/2009&amp;diff=837</id>
		<title>Esercizio 1, prova pratica 12/02/2009</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_12/02/2009&amp;diff=837"/>
		<updated>2014-12-01T19:39:04Z</updated>

		<summary type="html">&lt;p&gt;Ale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ho provato a svolgere l'esercizio 1 dell'esame di laboratorio del 2 febbraio 2009 ([http://www.cs.unibo.it/~renzo/so/pratiche/2009.02.12.pdf]).&lt;br /&gt;
&lt;br /&gt;
Consegna:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Esercizio1 (obbligatorio): (10 punti)&lt;br /&gt;
Scrivere un programma C denominato “invarg” che esegua il programma passato come parametro invertendo gli argomenti.&lt;br /&gt;
Esempio:&lt;br /&gt;
invarg cat a b c&lt;br /&gt;
deve avere l'effetto di&lt;br /&gt;
cat c b a&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc , char* argv[]){&lt;br /&gt;
	char *nargv[argc-1] ;	/*nargv è il vettore degli argomenti da passare al programma da eseguire*/&lt;br /&gt;
	int i , j ;		/*puntatori che scorrono, rispettivamente, argv ed nargv per riempire correttamente nargv*/&lt;br /&gt;
	nargv[0] = argv[1] ;	/*il primo valore di nargv deve essere il programma chiamato, l'ultimo deve essere NULL*/&lt;br /&gt;
	nargv[argc-1] = NULL ;&lt;br /&gt;
	for( i = argc - 1 , j = 1 ; i &amp;gt; 1 , j &amp;lt; (argc - 1) ; i-- , j++ ) nargv[j] = argv[i] ;	/*metto in nargv (dal secondo elemento in poi) gli argomenti presenti &lt;br /&gt;
in argv in ordine invertito*/&lt;br /&gt;
	execvp( nargv[0] , nargv  ) ;	/*eseguo il programma (il cui nome è contenuto in nargv[0]) passandogli nargv come vettore di parametri*/&lt;br /&gt;
	fprintf( stderr , &amp;quot;programma errato\n&amp;quot; ) ;	/*se ci troviamo in questo punto significa che la chiamata a execvp è fallita, probabilmente&lt;br /&gt;
 perchè il programma indicato non è stato trovato*/&lt;br /&gt;
	exit(1) ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Eddy==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void scambia_ordine(int argc, char **argv, int j);&lt;br /&gt;
&lt;br /&gt;
int main(int argc , char* argv[])&lt;br /&gt;
{&lt;br /&gt;
	if (argc &amp;lt; 2) return 2;&lt;br /&gt;
	argv++;	argc--;&lt;br /&gt;
	scambia_ordine(argc, argv, 1);&lt;br /&gt;
	execvp(argv[0], argv);&lt;br /&gt;
	perror(&amp;quot;execvp&amp;quot;);&lt;br /&gt;
	return 3;	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* piccola funzione ricorsiva che:&lt;br /&gt;
 * -memorizza in tmp gli argomenti dalla fine&lt;br /&gt;
 * -assegna ad argv in ordine inverso&lt;br /&gt;
 *&lt;br /&gt;
 *  non scambia il primo argomento&lt;br /&gt;
 */&lt;br /&gt;
void scambia_ordine(int argc, char **argv, int j)&lt;br /&gt;
{&lt;br /&gt;
	char *tmp;&lt;br /&gt;
	if (argc &amp;gt; 1){&lt;br /&gt;
		tmp = argv[argc-1];&lt;br /&gt;
		scambia_ordine (argc-1, argv, j+1);&lt;br /&gt;
		argv[j]=tmp;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[User:Eddy|Eddy]] ([[User talk:Eddy|talk]]) 21:00 Saturday, 22 November 2014 (CET)&lt;br /&gt;
&lt;br /&gt;
==Soluzione di GFede==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void scambia(int offset, int argc, char* argv[]);&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   if(argc &amp;lt;= 1)&lt;br /&gt;
   {&lt;br /&gt;
      printf(&amp;quot;Usage: invarg.exe command [arguments...]\n&amp;quot;);&lt;br /&gt;
      return 2;&lt;br /&gt;
   }&lt;br /&gt;
   scambia(2, argc - 1, argv);&lt;br /&gt;
&lt;br /&gt;
   execvp(argv[1], argv + 1);&lt;br /&gt;
   perror(&amp;quot;execvp&amp;quot;);&lt;br /&gt;
   return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Scambia le stringhe all'interno dell'array&lt;br /&gt;
 * void scambia&lt;br /&gt;
 * int offset     Indice da cui iniziare a scambiare&lt;br /&gt;
 * int argc       Numero di valori nell'array (Compreso l'offset)&lt;br /&gt;
 * char* argv[]   array di stringhe da scambiare&lt;br /&gt;
 */&lt;br /&gt;
void scambia(int offset, int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   int i;&lt;br /&gt;
   char* tmp;&lt;br /&gt;
   for( i = offset; i &amp;lt; argc - i + offset; i++ )&lt;br /&gt;
   {&lt;br /&gt;
      tmp = argv[i];&lt;br /&gt;
      argv[i] = argv[argc - i + offset];&lt;br /&gt;
      argv[argc - i + offset] = tmp;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di LorenzoV==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void swap(char **p, char **q){		// La swap modifica solo i puntatori&lt;br /&gt;
	char *tmp;&lt;br /&gt;
	tmp=*p;&lt;br /&gt;
	*p=*q;&lt;br /&gt;
	*q=tmp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){	&lt;br /&gt;
	char **begin, **end;&lt;br /&gt;
	if (argc&amp;lt;3){&lt;br /&gt;
		fprintf(stderr, &amp;quot;Usage:\n\t%s command ...arguments...\n&amp;quot;, argv[0]);&lt;br /&gt;
		exit(1);	&lt;br /&gt;
	}	&lt;br /&gt;
	begin=argv+2;&lt;br /&gt;
	end=argv+argc-1;&lt;br /&gt;
	while (begin&amp;lt;end){		// Inverte i parametri passati al comando&lt;br /&gt;
		swap(begin, end);&lt;br /&gt;
		begin++;&lt;br /&gt;
		end--;&lt;br /&gt;
	}&lt;br /&gt;
	execvp(argv[1], argv+1);&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:LorenzoV|LorenzoV]] ([[User talk:LorenzoV|talk]]) 18:35, 25 November 2014 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Soluzione di BoldrinD==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void invarg(int Qparametri, char* Rargv[], char* argv[]);&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
	int Qparametri=argc-1;	&lt;br /&gt;
	char *Rargv[Qparametri];&lt;br /&gt;
	invarg(Qparametri, Rargv, argv);&lt;br /&gt;
	printf(&amp;quot;%s\n&amp;quot;,&amp;quot;il nuovo vettore dei parametri è stato creato con successo&amp;quot;);&lt;br /&gt;
   	execvp(Rargv[0], Rargv);&lt;br /&gt;
  	 perror(&amp;quot;execvp&amp;quot;);&lt;br /&gt;
   return 1;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void invarg(int Qparametri, char* Rargv[], char* argv[]){&lt;br /&gt;
	Rargv[0]=argv[1];&lt;br /&gt;
	Rargv[Qparametri]=NULL;&lt;br /&gt;
	int i=2;&lt;br /&gt;
		while(argv[i]!=NULL){&lt;br /&gt;
		Rargv[Qparametri-1]=(argv[i]);&lt;br /&gt;
		i++;&lt;br /&gt;
		Qparametri--;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Soluzione di AleZ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
int main (int argc, char* argv[]) {&lt;br /&gt;
	if (argc == 1) {	// Non è stato passato alcun comando per la execvp&lt;br /&gt;
		fprintf(stderr, &amp;quot;Error: Segmentation fault\nUsage: [command] [arguments...]\n&amp;quot;);&lt;br /&gt;
		return(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
	char* tmp[argc];	// vettore che conterrà gli argomenti scambiati&lt;br /&gt;
	int i = 0;&lt;br /&gt;
	tmp[0] = argv[1];	// per convenzione il primo argomento è il programma chiamato&lt;br /&gt;
	tmp[argc-1] = (char*)NULL;	// come da manuale&lt;br /&gt;
	for (i = argc-2; i &amp;gt; 0; i--) tmp[i] = argv[(argc-i)];	// inverto gli argomenti &lt;br /&gt;
	execvp(tmp[0], tmp);&lt;br /&gt;
	fprintf(stderr, &amp;quot;%s: command not found\n&amp;quot;, argv[1]);	//execvp ha fallito&lt;br /&gt;
	return(EXIT_FAILURE);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:Ale|Ale]] ([[User talk:Ale|talk]]) 20:39, 1 December 2014 (CET)&lt;/div&gt;</summary>
		<author><name>Ale</name></author>
	</entry>
</feed>