Newsgroup: it.comp.os.linux.development
Titolo: GTK+ e fork

Ho un problemuccio con GTK, e, cercando sull'Internet, ho notato che
non sono l'unico ad averlo, sebbene non abbia ancora trovato una
risposta chiara.
Dunque: ho una applicazione che ne lancia un'altra (con la "combo"
fork+execl), e quest'ultima deve aprire una finestrella GTK e fare
altre cosucce.
In breve:
Codice della prima applicazione:
[...]
pid = fork ();
switch ( pid ) {
	case -1:
		return -1;
	case 0:
		execl ( "eseguibile", "", NULL );
		_exit ( -1 );
		break;
	default:
		break;
}
[...]
Codice dell'applicazione lanciata:
[...]
gtk_init ( &argc, &argv );
window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
[...]
Ebbene: la seconda applicazione arriva a quel "gtk_window_new" e... Non
fa piu' assolutamente nulla! Quell'invocazione non torna mai (lo
testimonia la printf che dovrebbe seguirla ma non stampa mai nulla a
video)!
Qualche suggerimento in proposito? Non ditemi "usa _exit()", come ho
gia' letto da qualche parte, perche' la seconda applicazione non
dovrebbe uscire *mai*, dunque in ogni caso non avrebbe nessuna
influenza...
Grazie :-)

 influenza...
Prova quindi a passare lo stesso puntatore alla lista di variabili di
ambiente del padre.
extern char** environ;
int main( int argc, char** argv ) {
	/* ... */
	execl ( "eseguibile", "", environ );
}
-- 
Matteo Settenvini
FSF Associated Member
Email : 
mat...@member.fsf.org
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d--(-) s+:- a-- C++ UL+++
P?>++ L+++>$ E+>+++ W+++ N++ o?
w--- O- M++ PS++ PE- Y+>++
PGP+++ t+ 5 X- R tv-- b+++ DI+
D++ G++ e h+ r-- y?
------END GEEK CODE BLOCK------

 DISPLAY) e quindi non riesce a connettersi alla risorsa giusta?
Ciao,
  attento! Quel NULL non si riferisce all'environment ... serve solo per 
terminare il vettore di argomenti, cioe' quello che verra' visto come argv 
nella main del processo chiamato.
 Ciao
 Federico

 		execl ( "eseguibile", "", NULL );
casomai 
    execl("eseguibile","eseguibile","",NULL);
Il fatto che argv[0] sia impostato al nome dell'eseguibile è solo una
convenzione tra applicativi, non è forzato dalla system call.
Tant'è vero che una shell di login viene avviata stile
    execl("/bin/bash","-bash",....)
(se fai il login da una console testuale e da essa fai un 
"cat /proc/$$/cmdline" vedrai che è così).
Detto questo mi pare strano che GTK si arrabbi solo perché argv[0] è una
stringa vuota (cosa che non vedo perché non dovrebbe essere legittima),
però non lo escluderei a priori.
-- 
  |   \    \  | ___|_  |_  |  ianezz a casa sua... :-)
  |  _ \  | \ | _|    /   /   Verba volant, scripta
 _|_/  _\_|  _|____|___|___|  manent, data corrupted


Infatti non si arrabbia per quello, non funziona neppure mettendo la
stringa corretta come secondo parametro.
Ho provato anche con system(), ma i risultati non sono stati certo
migliori...
Non so piu' che inventare!

 Non so piu' che inventare!
Ciao,
 non e' detto che sia particolamente utile, pero' "strace -f" potrebbe 
dirti quale syscall si pianta ... oppure potrebbe farti capire se c'e' un 
loop infinito ...
 Buona fortuna!
 Federico


Aggiornamento: mi sono accorto che il problema deriva dal fatto che in
realta' la finestra non viene proprio aperta dalla seconda applicazione
(quella che viene lanciata con execlp, system o quel che volete), ma
dal codice incluso in una libreria dinamica cui viene linkato.
Spostando il codice da una parte all'altra, infatti, l'applicazione non
si pianta piu' nello stesso punto ma prosegue.
Ora provo a linkare staticamente sta' libreria, faccio sapere se
ottengo qualcosa... Nel mentre, qualcuno ha da fornire qualche
delucidazione?


Fatto, e il risultato non e' stato particolarmente illuminante: e'
andato a cercare un fantomatico file "gtkrc", l'ha aperto ed e' andato
in segfault.
Loop infiniti ne ha pochi da fare: il codice e' piu' o meno
printf ( "1\n" );
win = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
printf ( "2\n" );
Inutile dire che "1" viene stampato e "2" no...
Giudicando il link alla libreria dinamica il responsabile del pasticcio
sono pure arrivato al punto di definire le funzioni di creazione della
grafica come macro, in modo da far fare al precompilatore il lavoro
sporco cacciando direttamente nel codice della seconda applicazione in
compilazione il codice incriminato: i risultati son stati identici
rispetto all'uso delle funzioni normali...

 delucidazione?
Magari non sono molto utile, ma la variabile window l'hai dichiarata? E
hai allocato memoria per contenere il risultato di gtk_window_new() ?
Poi, non so se sia questo il problema, ma in python quando usi i thread
devi isolare le chiamate a gtk in modo che "escano dal flusso del
thread", altrimenti danno comportamenti strani. Non so se sia la stessa
cosa anche in C.
Bye.
-- 
Alessandro Pellizzari


Dalle mie parti quella funzione alloca da se' lo spazio, restituendone
il puntatore...
In ogni caso, e' appurato che non si tratta di un problema di thread
ne' di fork, ma dell'uso di una libreria dinamicamente linkata...
Che ci sia qualche particolare opzione esoterica da passare a gcc???

 qualche particolare opzione esoterica da passare a gcc???
Ciao,
 ci sono alcune cose che non capisco:
il problema qual e'? Il tuo programma si pianta o va in segmentation 
fault?
questa tua applicazione ha mai funzionato? Dal tuo primo post avrei detto
di si', e che l'unico problema era legato al fork ...
qual e' il problema con questa libreria dinamica? Chi la carica questa
libreria? /lib/ld-linux.so all'inizio, o qualche dlopen piu' avanti?
in rete cosa dicono? Che questa libreria non funziona mai? O hanno gia'
trovato qualche condizione che sembra particolarmente "nefasta"?
 Ciao
 Federico


Nulla di tutto questo: la libreria dinamica l'ho generata io ;-).
Per la cronaca, il codice e' disponibile sul CVS del progetto che porto
avanti:
qui ->
http://cvs.sourceforge.net/viewcvs.py/braintop/braintop/braintop/BrainAppletsManager/src/main.c?rev=1.2&view=auto
(funzione exec_applet() ) viene lanciato il secondo eseguibile;
qua ->
http://cvs.sourceforge.net/viewcvs.py/braintop/braintop/braintop/BrainApplets/taskbar/braintaskbar.c?rev=1.1&view=auto
il codice di suddetto secondo eseguibile (il problema si verifica
nell'invocazione di brain_applet_init(), nel main);
quo ->
http://cvs.sourceforge.net/viewcvs.py/braintop/braintop/braintop/BrainApplets/src/brain_applets_generic.c?rev=1.4&view=auto
il sorgente della libreria incriminata: tutto si pianta all'invocazione
della prima gtk_window_new() nella funzione init_graphs().

 avanti:
Darei volentieri un'occhiata, ma non ne ho il tempo ...
Cmq, se provi a fare una diagnostica un po' piu' precisa di "non
funziona", vedremo un po' tutti di darti una mano!
 Ciao
 Federico


Sara'... Ma le librerie linkate dinamicamente le ho sempre chiamate
"dinamiche" e la roba che viene aperta esplicitamente con dlopen
"moduli"...

 Implicitamente (niente dlopen o affini, insomma...)
come dice Federcio, la libreria l'hai compilata con -fPIC?

 come dice Federcio, la libreria l'hai compilata con -fPIC?
Ciao david,
 per favore, se incontri questo Federcio portagli i saluti da parte mia 
:-))
 Ciao
 Federico


gcc -c BrainApplets/src/*.c -Wall -fPIC `pkg-config --libs --cflags
gtk+-2.0 \
libxfcegui4-1.0 libxfce4util-1.0` -I BrainManager/src &&
gcc -shared -o libbrain-applets.so *.o `pkg-config --libs --cflags
--libs gtk+-2.0 \
libxfcegui4-1.0 libxfce4util-1.0` -L/usr/local/BrainTop/lib -lbrain-mcs

Ciao,
scusa se mi intrometto, dato che non saprei darti una risposta!
Volevo però usare il thread già aperto per chiedere se qualcuno sa 
consigliarmi qualche buon testo per imparare a usare le gtk; ho dato 
un'occhiata su 
gtk.org
 ma il materiale, oltre a essere un pò 
frammentario, è anche un pò datato!!
Grazie a tutti, Alberto

 frammentario, è anche un pò datato!!
Il tutorial su GTK-2.0 e` un buon punto di partenza per iniziare a
capire i concetti di base, che sono rimasti uguali anche in Gtk 2.6.
Una volta capiti i concetti, usi le API Reference (c'e` anche il book
per devhelp), dove, all'inizio di ogni widget, e` spiegato piu` o meno
come funziona. Avendo presente i concetti base del tutorial e`
(solitamente) semplice capire tutto.
Ci sono dei widget obiettivamente ostici (TreeView su tutti) ma una
volta capiti ti chiederai come hai fatto a farne a meno. :)
Se vuoi un consiglio, e` molto piu` semplice capire Gtk se usi Glade (o
Gazpacho) per costruire l'interfaccia, e scrivi il software in Python
con PyGtk.
Bye.
-- 
Alessandro Pellizzari

* Alberto [2005-11-14 23:21]:

Partendo da:
 
http://developer.gnome.org
Dovresti trovare le API reference, alcuni tutorial e altri articoli a
riguardo.
Per il resto, il consiglio è: se *non* conosci il C, e stai imparando,
usa le GTK con uno dei binding in linguaggi ad alto livello o di
differente paradigma (Perl, Python, Ruby, C++, Haskell, Scheme, e chi
più ne ha, più ne metta).
Se conosci il C, prendi un progetto ospitato sul CVS di GNOME, scaricati
i sorgenti e leggi quelli; si impara meglio che in un tutorial.
Ciao,
 Emmanuele.

Ehm... Non vorrei sembrare insistente, ma... Ora che e' stato appurato
che la mia libreria viene compilata con -fPIC, cosa cambia?
Mi e' passato per la testa che magari compilando la libreria come
statica potrei risolvere il problema, il fatto e' che in fase di
linking l'eseguibile finale deve essere linkato anche ad altre librerie
dinamiche e non so come fare a linkare il tutto da una parte ad una
cosa statica e dall'altra a cose dinamiche; suggerimenti?