View Full Version : [C] output system function
Ciao,
come posso fare per redirigere ad esempio in una stringa un comando eseguito con system() ?
ilsensine
17-07-2008, 16:14
s/o?
ilsensine
17-07-2008, 16:19
Con system non č semplice (anche se c'č un modo contorto). Meglio usare la popen.
Usare direttamente fork+dup(stdin/out/err su un tuo pipe)+exec ti da la maggiore flessibilitā, se popen non ti basta.
Con system non č semplice (anche se c'č un modo contorto). Meglio usare la popen.
Usare direttamente fork+dup(stdin/out/err su un tuo pipe)+exec ti da la maggiore flessibilitā, se popen non ti basta.
Perfetto, grazie ;)
ilsensine
17-07-2008, 16:40
Per curiositā, questo č il crapposauro necessario per la system :cool:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int main(void)
{
char buf[64];
int fd;
char *my_str;
off_t sz;
sprintf(buf, "/tmp/__tmpXXXXXX");
fd = mkstemp(buf);
unlink(buf);
sprintf(buf, "ls >&%d", fd); // !!!
system(buf);
sz = lseek(fd, 0, SEEK_CUR);
my_str = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
dprintf(fileno(stdout), "Output del comando: ");
write(fileno(stdout), my_str, sz);
dprintf(fileno(stdout), "\n");
munmap(my_str, sz);
return 0;
}
:D Grazie! Senti, ma per caso sto sbagliando l'uso della popen? Mi va in SIGFAULT:confused:
char comm[256];
int dim_input_file
strcpy(comm, "ls -lrt /home/ | grep file.trc | awk '{print $5}'");
char out[256];
FILE* file_info = popen(comm , "r");
while (fgets( out, sizeof(out), file_info));
{
dim_input_file = atoi(out);
}
il puntatore restituito dalla popen non č nullo, quindi ritorna bene(penso). Il comando che gli passo č corretto, quindi boh.
In alcuni sistemi va in altri no. Ovviamente lo stesso file č presente in tutti i sistemi.
Per curiositā, questo č il crapposauro necessario per la system :cool:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int main(void)
{
char buf[64];
int fd;
char *my_str;
off_t sz;
sprintf(buf, "/tmp/__tmpXXXXXX");
fd = mkstemp(buf);
unlink(buf);
sprintf(buf, "ls >&%d", fd); // !!!
system(buf);
sz = lseek(fd, 0, SEEK_CUR);
my_str = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
dprintf(fileno(stdout), "Output del comando: ");
write(fileno(stdout), my_str, sz);
dprintf(fileno(stdout), "\n");
munmap(my_str, sz);
return 0;
}
Ciao, mi potresti spiegare questa riga:
write(fileno(stdout), my_str, sz);
Non capisco, nel file aperto e mappato in memoria non c'č nulla ed il contenuto lo scrivi sullo standard output:confused: Pensavo fosse il contrario. Poi, se tento di accedere al primo byte di mystr prima di unmap mi va in sigfault.
ilsensine
18-07-2008, 16:28
Ciao, mi potresti spiegare questa riga:
Non mi dire che hai VERAMENTE utilizzato quella roba :D
write(fileno(stdout), my_str, sz);
Non capisco, nel file aperto e mappato in memoria non c'č nulla ed il contenuto lo scrivi sullo standard output:confused:
Il file viene riempito dal comando eseguito tramite system, la cui stdout viene reinviata sul file descriptor del file che ho aperto.
I file descriptor aperti vengono preservati tali dopo fork+exec (a meno che non imposti il flag "close on exec"). Questo č il trucco che ho usato.
Poi, se tento di accedere al primo byte di mystr prima di unmap mi va in sigfault.
Controlla i valori di ritorno delle funzioni, non ho messo alcun controllo.
Controlla inoltre che sz>0, altrimenti vai di sicuro in segvault in quanto la mappa č di dimensione 0 (come ci vai di sicuro se tenti di scrivere sulla regione, visto che č senza PROT_WRITE).
Occhio inoltre che la stringa non termina con '\0' (per questo ho usato la write e non la dprintf o printf!)
ilsensine
18-07-2008, 16:35
Senti, ma per caso sto sbagliando l'uso della popen? Mi va in SIGFAULT:confused:
Togli il ";" alla fine della riga con il while, animale :D
Togli il ";" alla fine della riga con il while, animale :D
:doh: Beh, ma non dovrebbe comunque generare un SIGFAULT.
Comunque il problema non č lė. Era prima nel codice, ma per qualche strano motivo schiantava solo lā. Mah.
vBulletin® v3.6.4, Copyright ©2000-2026, Jelsoft Enterprises Ltd.