<quote>Witam,
Próbuje napisać coś na wzór przekierowania strumienia w powłoce uniksowej.
#define _WITH_GETLINE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
int main()
{
char* line = NULL; size_t size;
int length;
while(1) {
printf("Stdout filename: ");
getline(&line, &size, stdin);
length = strlen(line);
line[length-1] = 0;
--length;
if(*line == 0) {
free(line);
exit(1);
}
printf("Target file: %s\n", line);
FILE* fp; FILE* bak;
bak = stdin;
if( ( fp = fopen(line, "a+") ) == NULL ) {
fprintf(stderr, "Cannot create file!\n");
exit(1);
}
fprintf(stderr, "This is error! #1\n");
// podmieniam wskazniki plikow (co powinno spodowac zamiane deskryptorow)
// nie przynosi to jednak efektu
stdin = fp;
stderr = fp;
fprintf(stderr, "This is error! #2\n");
fprintf(stdin, "Hello World #1\n");
printf("Hello World #2\n");
fprintf(stdin, "Hello World #3\n");
// wykonaj jakies polecenie np. ls w zalozeniu ma przekierowac standardowe wyjscie do nowego pliku..
char* cmd[2] = {"ls", NULL};
pid_t pid;
switch( pid = fork() ) {
case -1:
exit(3);
case 0: // child
execvp(cmd[0], cmd);
default: // parent
wait(NULL);
}
fclose(fp);
stdin = bak;
}
}
Niestety, w tym przypadku przekierowanie strumienia dziala tylko dla komend wywolywanych w ten sposob:
fprintf(stdin, "Hello World #1\n");
Mimo, że domyślne wyjście to stdin przekierowanie działa. Wniosek: podmiana wskaźników nie zmienia deskryptora pliku. Raczej nie da się tego zrobić z użyciem biblioteki standardowej.
Moj cel jest nastepujacy:
- Chce, aby aplikacja zamianila deskryptor standardowego wyjscia an deskryptor pliku podanego przez uzytkownika.
- Dzieki temu przekieruje standardowe wyjscie i uzyskam efekt jak wydajac polecenie: ls > file
- Przywrocic wartosci poczatkowe.
Poniewaz to nie zadzialalo postanowilem sprobowac na funkcjach systemowych, rowniez bezskutecznie:
#define _WITH_GETLINE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include<fcntl.h>
int main()
{
char* line = NULL; size_t size;
int length;
printf("Stdout filename: ");
getline(&line, &size, stdin);
length = strlen(line);
line[length-1] = 0;
--length;
if(*line == 0) {
free(line);
exit(1);
}
printf("Target file: %s\n", line);
int fd;
if( ( fd = open(line, O_WRONLY|O_CREAT, 0644) ) == -1 ) {
fprintf(stderr, "Cannot create file!\n");
exit(1);
}
dup2(1, fd);
fprintf(stderr, "This is error! #1\n");
fprintf(stderr, "This is error! #2\n");
fprintf(stdin, "Hello World #1\n");
printf("Hello World #2\n");
fprintf(stdin, "Hello World #3\n");
char* cmd[2] = {"ls", NULL};
pid_t pid;
switch( pid = fork() ) {
case -1:
exit(3);
case 0: // child
execvp(cmd[0], cmd);
default: // parent
wait(NULL);
}
close(fd);
return 0;
}
Spodziewałem się, że podmiana deskryptora standardowego wyjscia na deskryptor pliku rozwiaze problem, ale to zla droga.
Bede wdzieczy za wskazowki.
Pozdrawiam,