Mam zadanie, nad którym pracuję i mam trudności z jego wykończeniem. Chodzi o to, aby napisać program if.c, który wykonuje jeden program i jeśli mu się to uda, wykonuje drugi program. Powinienem tłumić standardowe wyjście pierwszego programu i wypuścić standardowe wyjście dla drugiego. Otrzymuję komunikat o błędzie podczas wielu testów. Na przykład: "./if echo no, echo yes" zwraca "echo: błąd zapisu: zły deskryptor pliku". Próbowałem znaleźć to, co robię źle online, ale bez powodzenia.W C, w jaki sposób mogę przekierować STDOUT_FILENO do/dev/null przy użyciu dup2, a następnie przekierować ponownie do pierwotnej wartości później?
Oto mój kod:
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include "tlpi_hdr.h"
int main(int argc, char *argv[])
{
if(argc < 4){
fprintf(stderr,"Incorrect number of arguments.\n");
exit(EXIT_FAILURE);
}
int thenArg = 0;
char then[4];
strcpy(then,"then");
for(int x=1; x<argc; x++){
if(strncmp(argv[x], then, 4) == 0) thenArg = x;
}
if(thenArg == 0){
fprintf(stderr,"No 'then' argument found.\n");
exit(EXIT_FAILURE);
}
int save_out = dup(STDOUT_FILENO);
if(save_out == -1){
fprintf(stderr,"Error in dup(STDOUT_FILENO)\n");
exit(EXIT_FAILURE);
}
int devNull = open("/dev/null",0);
if(devNull == -1){
fprintf(stderr,"Error in open('/dev/null',0)\n");
exit(EXIT_FAILURE);
}
int dup2Result = dup2(devNull, STDOUT_FILENO);
if(dup2Result == -1) {
fprintf(stderr,"Error in dup2(devNull, STDOUT_FILENO)\n");
exit(EXIT_FAILURE);
}
int program1argLocation = 1;
int program2argLocation = thenArg + 1;
int program1argCount = thenArg-1;
int program2argCount = argc-(program2argLocation);
char *program1args[program1argCount+1];
char *program2args[program2argCount+1];
for(int i=0; i<program1argCount; i++){
program1args[i]=argv[program1argLocation + i];
}
program1args[program1argCount] = NULL;
for(int i=0; i<program2argCount; i++){
program2args[i]=argv[program2argLocation + i];
}
program2args[program2argCount] = NULL;
pid_t pid = fork();
int child_status;
switch (pid) {
case -1:
fprintf(stderr,"Fork failed\n");
exit(EXIT_FAILURE);
case 0: //child
//child will run program 1
if(execvp(program1args[0],&program1args[0]) == -1){
fprintf(stderr,"Program 1 Failed.\n");
exit(EXIT_FAILURE);
}
default: //parent
//parent will run program2
pid = wait(&child_status);
if(WEXITSTATUS(child_status) == 0){
dup2(save_out, STDOUT_FILENO);
int prog2status = execvp(program2args[0],&program2args[0]);
if(prog2status == -1) {
fprintf(stderr,"Program 2 failed.\n");
exit(EXIT_FAILURE);
}
}
}
}
'char następnie [ 4]; strcpy (następnie "wtedy"); 'jest przepełnieniem bufora. Dlaczego po prostu nie użyjesz 'if (0 == strcmp (argv [x]," then ")) lub' if (0 == strncmp (argv [x], "then", 4)) zamiast tego? – nneonneo
Myślę, że próbowałem, że po raz pierwszy zaimplementowałem to i popadłem w jakiś błąd. Zapamiętam to i powrócę do niego następnym razem, gdy natknę się na to samo. Dziękuję Ci! Nie używane do C jeszcze, więc wszelkie dane wejściowe w ten sposób są świetne. – Frank