Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo MSI
Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo MSI
Con velocità teoriche fino a 11 Gbps, gestione tramite app intelligente e protezione avanzata dei dispositivi, Roamii BE Pro porta il Wi‑Fi 7 tri‑band nelle abitazioni più esigenti. Un sistema Wi-Fi Mesh proposto da MSI allo scopo di garantire agli utenti una rete fluida e continua capace di sostenere streaming 8K, gaming competitivo e le applicazioni moderne più esigenti in termini di banda
Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi
Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi
Mate X7 rinnova la sfida nel segmento dei pieghevoli premium puntando su un design ancora più sottile e resistente, unito al ritorno dei processori proprietari della serie Kirin. L'assenza dei servizi Google e del 5G pesa ancora sull'esperienza utente, ma il comparto fotografico e la qualità costruttiva cercano di compensare queste mancanze strutturali con soluzioni ingegneristiche di altissimo livello
Nioh 3: souls-like punitivo e Action RPG
Nioh 3: souls-like punitivo e Action RPG
Nioh 3 aggiorna la formula Team NINJA con aree esplorabili più grandi, due stili di combattimento intercambiabili al volo (Samurai e Ninja) e un sistema di progressione pieno di attività, basi nemiche e sfide legate al Crogiolo. La recensione entra nel dettaglio su combattimento, build, progressione e requisiti PC
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 30-08-2011, 21:21   #1
magnamel
Member
 
Iscritto dal: Feb 2005
Messaggi: 40
[C linux] fork in nuova console

Salve a tutti
ho il seguente rompicapo. Ho fatto un programmino semplice per imparare le fork ma vorrei far in modo che il processo figlio venga eseguito in un nuovo terminale. Attenzione il processo padre e figlio non sono eseguiti in maniera concorrenziale; il padre attende la fine dell'esecuzione del figlio.
Ho provato a girare su internet e diverse soluzioni non mi hanno portato a nulla.
Ad esempio nel codice filgio ho eseguito un system("gnome-terminal"); che mi apre solo un nuovo terminale mentre il mio intento e' quello di eseguire il processo filgio nel nuovo terminale (basta anche solamente una banale printf).

Qualche ideia.
Grazie a tuti
magnamel è offline   Rispondi citando il messaggio o parte di esso
Old 30-08-2011, 22:17   #2
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Mmm beh, quello che vuoi fare è anomalo. Purtroppo non credo ci sia un modo semplicissimo per farlo.

Comunque l'output di un terminale in genere è collegato a un file su disco , scrivendo su quel file scrivi nel terminale. Puoi sapere qual'è il file collegato ad un certo terminale usando il comando "tty"

Codice:
[hades@artemis ~]$ tty
/dev/pts/1
[hades@artemis ~]$
Per il mio primo terminale è /dev/pts/1 , scrivendo in questo file ho :

Codice:
[hades@artemis ~]$ echo "ciao" > /dev/pts/1
ciao
[hades@artemis ~]$
Quindi se vuoi scrivere in un altro terminale da un programma con printf basta che associ il file descriptor del file /dev/pts/1 allo standard output oppure usi una funzione per il quale puoi specificare il file, come fprintf.

Rimane il problema di come sapere il nome del file collegato al terminale aperto dal programma . O ce lo infili fisso dentro nel programma (ma visto che cambia a seconda del terminale non è una buona idea) o lo ottieni dinamicamente dal programma , ma è un po' più complicato (dovresti forkare, ridirezionare lo standard output del figlio in una pipe collegata al padre, fare execv sul programma "/usr/bin/tty" e la stringa che arriva dall'altro capo della pipe dovrebbe essere il file in questione). Forse visto che sei all'inizio ti conviene comunque infilarlo direttamente dentro nel programma

In ordine quello che dovresti fare è:

- forkare il programma e nel figlio fare "execv()" di gnome-terminal per aprire un nuovo terminale.

- nel padre del precedente fork apri il file relativo al nuovo terminale aperto (se hai solo due terminali aperti nel server X in genere uno è /dev/pts/1 e l'altro è /dev/pts/2 quindi il file da aprire dovrebbe essere /dev/pts/2 ).

- forki di nuovo il programma e nel figlio duplichi il file descriptor del nuovo terminale sostituendo il file descriptor dello standard output (puoi farlo con "dup2( new_terminal_fid, 1);" dove new_terminal_fid è la variabile che contiene il file descriptor aperto del file /dev/pts/2 ottenuto dalla "open()" )

- a questo punto nel figlio se chiami "printf()" dovrebbe scrivere nel nuovo terminale.

Ciao
__________________
GPU Compiler Engineer

Ultima modifica di AnonimoVeneziano : 30-08-2011 alle 22:19.
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 30-08-2011, 22:51   #3
magnamel
Member
 
Iscritto dal: Feb 2005
Messaggi: 40
Grazie per la risposta
Domani a mente lucida riflettero' su quello che hai detto.
A grandi linee ho capito devo "solo" trasformarlo in codice.

Grazie ancora
magnamel è offline   Rispondi citando il messaggio o parte di esso
Old 03-09-2011, 21:34   #4
magnamel
Member
 
Iscritto dal: Feb 2005
Messaggi: 40
Quote:
Originariamente inviato da AnonimoVeneziano Guarda i messaggi
o lo ottieni dinamicamente dal programma , ma è un po' più complicato (dovresti forkare, ridirezionare lo standard output del figlio in una pipe collegata al padre, fare execv sul programma "/usr/bin/tty" e la stringa che arriva dall'altro capo della pipe dovrebbe essere il file in questione)
Sto provando in questo modo ma la stringa che mi restituisce e' lo stesso terminale in cui si trova anche il padre (/dev/pts/0).
magnamel è offline   Rispondi citando il messaggio o parte di esso
Old 04-09-2011, 01:52   #5
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Il file descriptor della console di gnome-terminal non va bene, perche' e' la stessa del padre (e' l'output del programma gnome-terminal, non dei programmi che quest'ultimo fa girare).

Vedo due alternative semplici, che coinvolgono l'esecuzione di un piccolo script da parte di gnome-terminal (io usero' piu' sotto xterm, ma non cambia tanto la cosa).
La prima e' quella di far partire il terminale e fargli eseguire il comando "tty", salvarlo su un file in /tmp e poi mettersi in attesa. L'altro processo aprira' il file specificato, legge il nome della console, apre il device relativo e lo imposta come stdout.

Alternativa due: si salta il passaggio di scrivere da qualche parte il nome del terminale, si crea una fifo che viene impostata da una parte come output e dall'altra come input. Impostare l'input di gnome-terminal non e' altro che chiamare uno script che fa il cat della fifo

Sono abbastanza simili, ma mi piace di piu' la seconda fondamentalmente per il fatto che in questo modo il terminale si chiude automaticamente quando il processo scrivende finisce, mentre nell'altro caso devo fare una kill del processo relativo.

Questo e' un esempio di come puo' funzionare: fa partire una shell che scrive sulla seconda finestra.
Sostituisci i programmi indicati con quelli che usi tu
Codice:
#include <stdlib.h>
#include <stdio.h>

#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

char fifo_name[128];
int fifo_fd;


void display_proc()
{
    char cmd[128];
    snprintf(cmd,128,"/usr/local/bin/xterm -e \"cat %s\"",fifo_name);
    system(cmd);
}


void worker_proc()
{
    char cmd[128];
    freopen(fifo_name, "w+", stdout);
    
    system("/usr/local/bin/bash");
}



    


int main()
{
    int i,j;
    
    snprintf(fifo_name,128,"/tmp/tmpXXXX");
    mktemp(fifo_name);
    printf("Fifo name: %s\n", fifo_name);
    fifo_fd = mkfifo(fifo_name,0700);
    
    switch( fork())
    {
    case 0:
        display_proc();
        return;
    case -1:
        printf("Error while forking: %s\n", strerror(errno));
        return;
    default:
        break;
        
    }
    
    worker_proc();
}
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 04-09-2011, 02:36   #6
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da magnamel Guarda i messaggi
Sto provando in questo modo ma la stringa che mi restituisce e' lo stesso terminale in cui si trova anche il padre (/dev/pts/0).
Ti ritorna quella perchè è così che deve essere non so cosa HO bevuto quella sera, ma è ovvio che era qualcosa di forte perchè è naturale che ritorni quella del padre visto che il processo figlio è collegato a quel terminale.

Consiglio cannato
__________________
GPU Compiler Engineer

Ultima modifica di AnonimoVeneziano : 04-09-2011 alle 11:36.
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 04-09-2011, 03:07   #7
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Il file descriptor della console di gnome-terminal non va bene, perche' e' la stessa del padre (e' l'output del programma gnome-terminal, non dei programmi che quest'ultimo fa girare).

Vedo due alternative semplici, che coinvolgono l'esecuzione di un piccolo script da parte di gnome-terminal (io usero' piu' sotto xterm, ma non cambia tanto la cosa).
La prima e' quella di far partire il terminale e fargli eseguire il comando "tty", salvarlo su un file in /tmp e poi mettersi in attesa. L'altro processo aprira' il file specificato, legge il nome della console, apre il device relativo e lo imposta come stdout.

...
Questa soluzione fa il suo dovere, solo una cosa però:

snprintf(fifo_name,128,"/tmp/tmpXXXX");

dovrebbe essere


snprintf(fifo_name,128,"/tmp/tmpXXXXXX");

in quanto mktemp vuole almeno 6 X come minimo (almeno per la mia versione delle glibc)

Comunque mktemp dovrebbe essere deprecata, quindi se magari si potesse trovare un modo di non usarla sarebbe meglio (tanto per evitare un warning).
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 04-09-2011, 13:23   #8
magnamel
Member
 
Iscritto dal: Feb 2005
Messaggi: 40
Quote:
Originariamente inviato da AnonimoVeneziano Guarda i messaggi
è naturale che ritorni quella del padre visto che il processo figlio è collegato a quel terminale.
Avevo il sospetto che accadesse cio'.....ma visto che sono neofita ho provato ugualmente

Quote:
Originariamente inviato da AnonimoVeneziano Guarda i messaggi
non so cosa HO bevuto quella sera, ma è ovvio che era qualcosa di forte
pensa a me succede quando sono sobrio



Quote:
Originariamente inviato da marco.r
si salta il passaggio di scrivere da qualche parte il nome del terminale, si crea una fifo che viene impostata da una parte come output e dall'altra come input. Impostare l'input di gnome-terminal non e' altro che chiamare uno script che fa il cat della fifo
Codice a parte sto portando avanti questa soluzione. Domanda:
Posso usare una pipe invece di una fifo? Aprendo un terminale nuovo con system(....) c'e' rapporto di parentela tra il mio processo ed il nuovo terminale?

Grazie
magnamel è offline   Rispondi citando il messaggio o parte di esso
Old 04-09-2011, 13:51   #9
Tommo
Senior Member
 
L'Avatar di Tommo
 
Iscritto dal: Feb 2006
Messaggi: 1304
Non basta lanciare un terminal figlio che esegue un processo predefinito, e poi termina insieme a questo?

Il processo padre del secondo terminal così saprebbe perfettamente quando il task è finito!

Altrimenti, si possono fare due processi non padre/figlio che condividono una pipe... ma allora le possibilità sono infinite dato che è un generico problema di IPC.
__________________
*ToMmO*

devlog | twitter
Tommo è offline   Rispondi citando il messaggio o parte di esso
Old 04-09-2011, 15:45   #10
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da magnamel Guarda i messaggi
Codice a parte sto portando avanti questa soluzione. Domanda:
Posso usare una pipe invece di una fifo? Aprendo un terminale nuovo con system(....) c'e' rapporto di parentela tra il mio processo ed il nuovo terminale?

Grazie
No, non puoi usare una pipe, perchè xterm quando si apre ridireziona stdin e out , quindi una eventuale dup sulla pipe non ha effetto e non puoi fare "cat" di una pipe dal terminale perchè non esiste fisicamente .

Per una soluzione senza fifo ho modificato la versione di marco tirando fuori una roba del genere :

Codice:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pty.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

char name[100];

void display_proc()
{
        system("/usr/bin/xterm");
}


void worker_proc()
{
    char cmd[128];
    int fd;
    while ((fd = open(name, O_WRONLY)) == -1);
    fd = dup2(fd, 1);
    execl("/bin/bash", "/bin/bash", NULL);
}
int main()
{
    int i,j, pid;
    
    openpty(&i, &j, name, NULL, NULL);
    close(i);
    close(j);
    printf("%s\n", name);    
    switch( pid = fork())
    {
    case 0:
        display_proc();
        return 0;
    case -1:
        printf("Error while forking: %s\n", strerror(errno));
        return 1;
    default:
        break;
        
    }
    
    worker_proc();
    return 0;
}
In pratica cerca di determinare con "openpty" in nome del file del terminale con cui XTERM si aprirà, poi appena xterm crea il file si collega e ridireziona lo stdout del padre sulla pty del figlio.
Se venisse aperto un terminale da un altra parte tra la chiamata a "openpty" e l'apertura di xterm potrebbe non funzionare (è comunque una cosa quasi impossibile visto che accade tutto molto velocemente). La stessa cosa potrebbe succedere con la fifo se un programma tra la chiamata a mktemp e mkfifo creasse una fifo con lo stesso nome.

Ciao
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 04-09-2011, 15:49   #11
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da Tommo Guarda i messaggi
Non basta lanciare un terminal figlio che esegue un processo predefinito, e poi termina insieme a questo?

Il processo padre del secondo terminal così saprebbe perfettamente quando il task è finito!

Altrimenti, si possono fare due processi non padre/figlio che condividono una pipe... ma allora le possibilità sono infinite dato che è un generico problema di IPC.
Lui vuole scrivere da un padre sul figlio. (cioè, vuole che il figlio generi a sua volta un figlio che è un terminale e che possa scrivere su di esso)

Tecnicamente si potrebbe scrivere un altro programma server che ad esempio usa i socket o un altro sistema di IPC che viene lanciato sul terminale "figlio" e rimane in ascolto di dati da visualizzare da parte di un processo padre. Il padre gli spedirebbe i dati da visualizzare e lui li printerebbe sul terminale aperto. In tutti i casi sono soluzioni non semplicissime
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 04-09-2011, 16:21   #12
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da AnonimoVeneziano Guarda i messaggi
Questa soluzione fa il suo dovere, solo una cosa però:

snprintf(fifo_name,128,"/tmp/tmpXXXX");

dovrebbe essere


snprintf(fifo_name,128,"/tmp/tmpXXXXXX");

in quanto mktemp vuole almeno 6 X come minimo (almeno per la mia versione delle glibc)
Non tutti usano la glibc

Quote:
Comunque mktemp dovrebbe essere deprecata, quindi se magari si potesse trovare un modo di non usarla sarebbe meglio (tanto per evitare un warning).
Non mi risulta che sia deprecata , di sicuro e' potenzialmente pericolosa.
Questo perche' se io mi faccio generare un nome di file E poi non creo subito il file E un attaccante crea il file al posto mio (visto che il nome e' facilmente indovinabile) E poi io creo il file piu' tardi senza controllare se c'e' gia', allora c'e' un rischio di sicurezza e quindi in generale conviene mkstemp. Ma direi che nel nostro caso non e' cosi' importante, visto che la necessita' e' solo quella di visualizzare su un altro schermo mentre si fanno delle prove.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo MSI Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo M...
Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi Recensione HUAWEI Mate X7: un foldable ottimo, m...
Nioh 3: souls-like punitivo e Action RPG Nioh 3: souls-like punitivo e Action RPG
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti Test in super anteprima di Navimow i220 LiDAR: i...
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto Dark Perk Ergo e Sym provati tra wireless, softw...
La Cina lancia un servizio simile a Dire...
SpaceX: Elon Musk torna a parlare dei pr...
G.Skill risarcisce 2,4 milioni di dollar...
Test degli annunci su ChatGPT avviati: '...
TSMC approva investimenti record da quas...
L'IA agentica arriva anche sullo storage...
Euro digitale, il Parlamento UE cambia r...
Alphabet e la sua obbligazione centenari...
L'UE anticipa un intervento per bloccare...
Il Trump Phone esiste ma è molto ...
Frodi deepfake fuori controllo: perch&ea...
Consumano il 30% in meno: arrivano i nuo...
Tesla Semi svela i numeri definitivi: 80...
La Air Force statunitense vieta occhiali...
Wi-Fi Intel e Windows: le novità ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 04:43.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v