Newsgroup: it.comp.os.linux.development
Titolo: eseguire applicazione con parametri in un'unica stringa

Salve.
Mi ritrovo ad avere i parametri di un'applicazione su di un'unica 
stringa, solo che non riesco a trovare il modo di sfruttarla :(
esempio:
char parametri[] = "ls -1 -l -a"
a me ora servirebbe un qualche cosa che mi permettesse di fare una cosa 
simile:
funzione("/usr/bin/, parametri);
Le varie funzioni della famiglia exec, non mi aiutano a risolvere la 
situazione :(
avete ida di un qualche modo per risolvere la situazione ?
Grazie

man system?
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy              ROT13: 
ybe...@cq.vasa.vg

 avete ida di un qualche modo per risolvere la situazione ?
Se il problema e' prendere e attaccare al comando il path, allore (e che
Cthulhu mi perdoni per questo anglicismo) tokenizza la stinga usando lo
spazio come delimitatore e costruisci un vettore di stringhe con il
comando e i suoi parametri. Poi "appiccica" il path al primo elemento
del vettore. Alle, passa tutto quando a execve.
Con le GLib, g_strsplit() fa alla bisogna.
Ciao,
 Emmanuele.

Emmanuele Bassi ha scritto:

Ok e in caso ci si rtirovasse con una cosa come:
-a -l -i -q "pippo pluto paperino"
"pippo pluto paperino" dovrebbe rimanere unito :/
( idem se si usa il cast )
Grazie
ciao

 ( idem se si usa il cast )
Che cast?
Ciao,
 Emmanuele.

 il path e concatenarci il resto del comando; poi passa tutto a execl().
tu intendi una cosa tipo cosi' ?
execl("/bin/ls", "-l -a -1", NULL);
Non mi funziona :(
mi esegue il comando ls, ma senza i parametri
Grazie
	Ciao

 mi esegue il comando ls, ma senza i parametri
Allora stai facendo qualcosa di errato.
Prova a compilare questo test:
+++
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main (int argc, char *argv[])
{
	pid_t child_pid;
 
	child_pid = fork ();
	if (child_pid == -1) {
		perror ("fork");
	}
	else if (child_pid == 0) {
		execl ("/bin/ls", "-l -a -1", NULL);
		exit (1); /* not executed */
	}
	else {
		int status;
 
		waitpid (child_pid, &status, 0);
		if (WIFEXITED (status))
			return EXIT_SUCCESS;
	}
	return EXIT_FAILURE;
}
+++
E vedere se ti funziona (come dovrebbe).
Ciao,
 Emmanuele.

 execl("/bin/ls", "-l -a -1", NULL);
Anche con:
execl("/bin/ls", "ls", "-l -a -1", NULL);
mi dice che "--" non e' un parametro valido ( ls: invalid option -- )
:(
Grazie
	Ciao

 
system purtroppo non va bene per quello che devo fare io.
grazie.
ciao

 Prova a compilare questo test:
Per eseguire lo esegue il comando ls, ma non considera per nulla i 
parametri :(
( gcc test.c -o test && ./test )
quindi un "ls" puro e crudo.
sob !
grazie
ciao

Filippo ha scritto:

Ho risolto creandomi una funzione che mi ritorna la lista dei parametri, 
piu' una funzione che dato il nome dell'eseguibile e la stringa dei 
parametri, le unisce e poi chiama la funzione per lo split della lista.
char** splitParameters(char* param, int* size )
{
	int i;
	char** retList = NULL;
	int tot = 0;
	int flag=0;
	char* xstr = NULL;
	for(i=0; i<strlen(param); i++)
	{
 
		if( ( *(param+i) == ' ' && flag != 1  && flag != 2 ) || ( i == 0 && 
*(param+i)!='"' && *(param+i)!='\'' ) || (flag == 3) )
		{
			if( flag == 0 && i > 0 )
			{
				flag=3;
			} else {
 
				if(flag==0) flag=3;
				if( ( *(param+i) == '\\' && *(param+i+1) == '\\' ) || ( *(param+i) 
== '\\' && *(param+i+1) == ' '  ) )
				{
					flag=3;
				} else if ( ( *(param+i)==' ' && *(param+i-1)!='\\' ) || ( 
*(param+i)=='"' && *(param+i-1)!='\\' ) || ( *(param+i)=='\'' && 
*(param+i-1)!='\\' ) ) {
 
					if(xstr != NULL)
					{
						tot++;
						retList = (char**) realloc( retList, sizeof(char*)*tot );
						retList[tot-1] = xstr;
						xstr=NULL;
					}
					i--;
					flag=0;
 
				} else {
					int xstrLen = ((xstr==NULL)?0:strlen(xstr));
					xstr= (char*) realloc( xstr, xstrLen+2 );
					bzero(xstr+xstrLen, 2);
					strncat(xstr, param+i, 1);
				}
			}
		}
		if( (*(param+i) == '"' && flag != 2 && flag != 3 ) || flag == 1)
		{
			if( flag == 0 )
			{
				flag=1;
			} else {
 
				if( ( *(param+i) == '\\' && *(param+i+1) == '\\' ) || ( *(param+i) 
== '\\' && *(param+i+1) == '"'  ) )
				{
					flag=1;
				} else if ( *(param+i) == '"' && *(param+i-1) != '\\' ) {
 
					tot++;
					retList = (char**) realloc( retList, sizeof(char*)*tot );
					retList[tot-1] = xstr;
					xstr=NULL;
					flag=0;
 
				} else {
					int xstrLen = ((xstr==NULL)?0:strlen(xstr));
					xstr= (char*) realloc( xstr, xstrLen+2 );
					bzero(xstr+xstrLen, 2);
					strncat(xstr, param+i, 1);
				}
			}
		}
 
 
		if( (*(param+i) == '\'' && flag != 1 && flag != 3) || flag == 2)
		{
			if( flag == 0 )
			{
				flag=2;
			} else {
 
				if( ( *(param+i) == '\\' && *(param+i+1) == '\\' ) || ( *(param+i) 
== '\\' && *(param+i+1) == '\''  ) )
				{
					flag=2;
				} else if ( *(param+i) == '\'' && *(param+i-1) != '\\' ) {
 
					tot++;
					retList = (char**) realloc( retList, sizeof(char*)*tot );
					retList[tot-1] = xstr;
					xstr=NULL;
					flag=0;
 
				} else {
					int xstrLen = ((xstr==NULL)?0:strlen(xstr));
					xstr= (char*) realloc( xstr, xstrLen+2 );
					bzero(xstr+xstrLen, 2);
					strncat(xstr, param+i, 1);
				}
			}
		}
	}
 
	if(xstr != NULL)
	{
		tot++;
		retList = (char**) realloc( retList, sizeof(char*)*tot );
		retList[tot-1] = xstr;
		xstr=NULL;
	}
	tot++;
	retList = (char**) realloc( retList, sizeof(char*)*tot );
	retList[tot-1] = NULL;
	if(size != NULL) *size = tot;
 
/*	
	for(i=0; i<tot-1; i++)
	{
		printf("#%s#\n", retList[i]);
	}
*/	
	return retList;
}
char** makeParamList(char* rsExecName, char* rsParam, int* size)
{
	char** list = NULL;
	char* patternPointer = NULL;
	char* startPointer = NULL;
	int q=0;
 
	char* param = (char*) malloc( sizeof(char) * ( strlen(rsExecName) + 
strlen(rsParam) + 2 ) );
	bzero(param, ( sizeof(char) * ( strlen(rsExecName) + strlen(rsParam) + 
2 ) ) );
	strcat(param, rsExecName);
	strcat(param, " ");
	strcat(param, rsParam);
 
	return splitParameters(param,size);
}
Quindi:
int totListElement;
execv("/bin/ls", ParamList( "ls", "-l -i -1 \"/home/pippo\"", 
&totListElement) );

 stringa, solo che non riesco a trovare il modo di sfruttarla :(
]zac[
Sembra che hai bisogno di eseguire una tokenizzazione, se è cosi leggi la
mia risposta al post ' sostituzione in una stringa .... in C ', nella
stessa libreria ci sono funzioni per il parsing e per la tokenizzazione
(safe parsing e safe tokenizzazione).

Giuseppe Della Bianca ha scritto:

Suppongo che mi serva BaseString.c e BaseString.h, giusto ?
Grazie
Ciao

Giuseppe Della Bianca ha scritto:

Ci ho guardato un po', ma non mi pare ci sia una funzione che faccia al 
caso mio.
Io avevo bisogno di una funzione in grado di crearmi una "lista" di 
parametri data una stringa.
Ho detto "avevo bisogno", perche' spesso si fa prima a farsi le cose da 
per se, che stare a cercare in giro delle implementazioni gia' fatte.
(il codice lo puoi vedere in un mio messaggio sempre in questo thread).
Un esempio di cio' che fa e' questo:
int totListElement;
char** lista = splitParameters( "-l -i \"/home/pi \\\"ppo\" -1", 
&totListElement);
in lista avro i seguenti elementi :
	-l
	-i
	/home/pi "ppo   (volutamente bastardo :) )
	-1
	NULL  (il terminatore)
e in totListElement avro' il numero degli elementi presenti in lista 
(compreso il terminatore), quindi in questo caso: 5
Ciao

 caso mio.
Hai già risolto per altra strada, ma visto che hai chiesto ti rispondo
comunque.
Da altro post: Si, se non vuoi linkare la libreria, usa solo BaseString.* e
il file global.h .
Un estratto di un uso (MAX_NUMPAR e LENSTR vanno definiti con un #define ...
(file global.h)):
 int result= true, ParNum, NumPar;
 char row[LENSTR];
 char *pRow, par[MAX_NUMPAR][LENSTR + 1], *pPar[MAX_NUMPAR];
 pRow= row;
 NumPar= MAX_NUMPAR;
// set the parameter pointers
 for (ParNum= 0; ParNum < MAX_NUMPAR; ParNum++)
   pPar[ParNum]= par[ParNum];
 strcpy (row, "-l -i \"/home/pi \\\"ppo\" -1");     
 result= ParamsFromRow (&pRow, pPar, " ", 0, &NumPar, LENSTR);
 if (result && NumPar >= 3){         
        ...................
 }
In NumPar setti il numero massimo di parametri che vuoi avere (in accordo
con le dimensioni del buffer), LENSTR è la massima dimensione che i
parametri devono avere (in accordo con le dimensioni del buffer).
Se non ci sono errori ParamsFromRow ritorna true e in NumPar ritorna il
numero di parametri effettivamenti trovati.
Se ti sembra contorto l'uso del puntatore e di una lista di puntatori ci
sono motivi tecnici e di realizzazione di una funzione di carattere
generale.
P.S. nota che ParamsFromRow usa strtoken, che è la funzione che esegue il
parsing dei token.

 }
Il ritorno di un riferimento a una variabile locale di una funzione è da
evitare come la peste.
E' fortemente sconsigliato è non è per niente  garantito che la memoria
della variabile locale non venga sovrascritta dal momento dell'uscita dalla
funzione fino alla copia del valore ritornato.
Nella realtà di programmi molto semplici non da problemi nel 99,99% dei
casi, ma poi basta poco per trovarsi malfunzionamenti che sembrano casuali.

 evitare come la peste.
]zac[
Ho il non vago dubbio di aver scritto una cosa completamente sbagliata.
In realtà l'area di memoria è allocata da alloc e non viene liberata
all'uscita dalla funzione, quindi ' return retList ' non dovrebbe dare
nessun problema, è più o meno uguale a un ' return long '

 nessun problema, è più o meno uguale a un ' return long '
Infatti era quello che penavo anche io ... mi avevi tolto delle certezze ;)
Grazie
	Ciao