Torna indietro   Hardware Upgrade Forum > Software > Programmazione

 Recensione OPPO Find X10 Pro Max: un top di gamma completo con tre fotocamere da 200MP
Recensione OPPO Find X10 Pro Max: un top di gamma completo con tre fotocamere da 200MP
OPPO ha appena lanciato sul mercato la nuova serie Find X10, che ha come smartphone premium il Find X10 Pro Max, uno smartphone completo, che fa del comparto fotografico il suo vero punto di forza. Ma sono tante le novità, tra cui l'AI che adesso diventa agentica. Ma andiamo a vedere nel dettaglio questo nuovo smartphone.
WoW Forever provato: il MMORPG che la community chiedeva da anni è arrivato
WoW Forever provato: il MMORPG che la community chiedeva da anni è arrivato
Abbiamo provato la beta di World of Warcraft: Forever, il Classic+ di Blizzard in arrivo il 4 novembre: la nuova razza Skyborne restituisce la sensazione di un gioco nuovo, ma le zone storiche conservano la noia divertita di Classic. Classi ribilanciate, sciamani anche nell'Alleanza e un motore grafico che in 4K gira bene anche su una RTX 3070. Cosa cambia in Forever? La risposta nell'articolo
TCL P80 Ultra: con un display AMOLED opaco è una gioia per gli occhi e per le dita
TCL P80 Ultra: con un display AMOLED opaco è una gioia per gli occhi e per le dita
TCL P80 Ultra abbina per la prima volta un pannello AMOLED alla tecnologia NXTPAPER con finitura opaca, affiancandoci una fotocamera periscopica da 50 MP con zoom ottico 3x, il SoC Dimensity 7400 Elite e una batteria da 5.800 mAh. Nella prova sul campo emergono luminosità di picco molto elevata, comparto fotografico solido per la fascia di prezzo e autonomia nella media, a fronte di velocità di scrittura dello storage piuttosto contenute
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 30-08-2011, 20: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, 21: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 21:19.
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 30-08-2011, 21: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, 20: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, 00: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, 01: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 10:36.
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 04-09-2011, 02: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, 12: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, 12: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, 14: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, 14: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, 15: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


 Recensione OPPO Find X10 Pro Max: un top di gamma completo con tre fotocamere da 200MP Recensione OPPO Find X10 Pro Max: un top di gam...
WoW Forever provato: il MMORPG che la community chiedeva da anni è arrivato WoW Forever provato: il MMORPG che la community ...
TCL P80 Ultra: con un display AMOLED opaco è una gioia per gli occhi e per le dita TCL P80 Ultra: con un display AMOLED opaco &egra...
HUAWEI MatePad Air recensione: OLED opaco e tastiera dedicata per lavorare meglio HUAWEI MatePad Air recensione: OLED opaco e tast...
NVIDIA RTX Spark: il PC Windows on ARM costruito per l'IA agentica NVIDIA RTX Spark: il PC Windows on ARM costruito...
L'Air Force Research Laboratory ha utili...
L'ONU esprime preoccupazione per le oper...
OpenAI: GPT-6.1 Sol migra il COBOL all'8...
Cyberpunk 2077 porta le mod su console e...
Agenti di IA, per Akamai la sicurezza pa...
Non solo in Europa: Apple dovrà a...
iPhone Duo, il compromesso del display p...
Reolink OMVI 2i Ultra, la videocamera ib...
PowerToys 0.102: con un nuovo tool il mo...
Bose acquisisce Skullcandy per raggiunge...
I videogiochi di Star Wars dovranno sorp...
Cos'è Flint: l'AI locale per la programm...
Perplexity Computer ora gira offline sul...
LG lancia in Italia i nuovi laptop gram ...
Spotify dice addio ai vincoli di Android...
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: 23:26.


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