PDA

View Full Version : [C] output system function


Unrue
17-07-2008, 16:09
Ciao,
come posso fare per redirigere ad esempio in una stringa un comando eseguito con system() ?

ilsensine
17-07-2008, 16:14
s/o?

Unrue
17-07-2008, 16:16
s/o?

Linux :)

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.

Unrue
17-07-2008, 16:28
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;
}

Unrue
18-07-2008, 09:59
: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.

Unrue
18-07-2008, 14:42
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

Unrue
18-07-2008, 17:28
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.