2014-11-06 3 views
0

유닉스/리눅스 쉘의 간접 입력 기능을 구현하기위한 간단한 코드를 작성했습니다. 문제가 무엇인지 제발, 그냥 내가 답변을주지 않고이 붙어간접 입력이있는 단순한 쉘

sort -r <fileList 

는 쉘

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <fcntl.h> 

extern void error(char* message);  
void 
cisshRedirectedInput(char* command[], char* inputFile) 
{ 
    //Try to implement the RedirectInput from here 
    pid_t pid; 
    int status; 
    int fd;   
//For the child process 
    if ((pid=fork())==0) 
    { 
     //Try to input files, failing on an error 
    fd=open(inputFile,O_RDONLY);//To read input file 

     if(fd < 0) 
     { 
      error("sampleSh: error opening standard input file"); 
      exit(1); 
     } 
     //use dup() to copy file 
     close(1); 
     if(dup(fd) < 0) 
     { 
      error("sampleSh: error duplicating standard input"); 
      perror("dup()"); 
      exit(1); 
     } 

     //Close file and exec() 
     close(fd); 
     execvp(command[0], command); 
     //If failure in any case 
     error("sampleSh: failure to execute command"); 
     exit(1); 
    }   
    else 
    { 
     /* This is the parent process. 
     * Wait for the child to terminate. 
     */ 
     if(wait(&status) < 0) 
     { 
      error("sampleSh: error waiting for child."); 
      perror("wait"); 
     } 

     if(status != 0) 
      error("sampleSh: command exited with nonzero error status."); 
    } 

} 

그러나, 컴파일 후 (오류가보고되지),하지만 난 때 (파일 목록이 이미 생성)?

답변

2

표준 입력 파일 설명자가 1 (또는 STDOUT_FILENO)이 아닌 0 (또는 STDIN_FILENO)입니다.

중 하나를 사용 :

int fd = open(inputFile, O_RDONLY); 

if (fd < 0) … 
close(0); 
if (dup(fd) < 0) … 
close(fd); 

또는 :

int fd = open(inputFile, O_RDONLY); 

if (fd < 0) … 
if (dup2(fd, 0) < 0) … 
close(fd); 

당신의 코드는 표준 I/O 기술자를 복제 한 후 close(fd)을 수행하는 것이 좋습니다 - 그것은 거의 항상 올바른 것입니다. 중요한 시스템 호출이 성공했는지 확인하는 것도 좋습니다. (많은 close()이 실패하면 당신이 할 수 없습니다.)


코드의이 간단한 수정 : 나를 위해 작동 (키 변경 대신 close(1);close(0); 사용). 인수 목록을 null로 종료 했습니까?

#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <unistd.h> 

static inline void error(char *message) 
{ 
    fprintf(stderr, "%s\n", message); 
} 

void 
cisshRedirectedInput(char *command[], char *inputFile); 

void 
cisshRedirectedInput(char *command[], char *inputFile) 
{ 
    // Try to implement the RedirectInput from here 
    pid_t pid; 
    int status; 
    int fd; 
    // For the child process 
    if ((pid = fork()) == 0) 
    { 
     // Try to input files, failing on an error 
     fd = open(inputFile, O_RDONLY); // To read input file 

     if (fd < 0) 
     { 
      error("sampleSh: error opening standard input file"); 
      exit(1); 
     } 
     // use dup() to copy file 
     close(0); 
     if (dup(fd) < 0) 
     { 
      error("sampleSh: error duplicating standard input"); 
      perror("dup()"); 
      exit(1); 
     } 

     // Close file and exec() 
     close(fd); 
     execvp(command[0], command); 
     // If failure in any case 
     error("sampleSh: failure to execute command"); 
     exit(1); 
    } 
    else 
    { 
     /* This is the parent process. 
     * Wait for the child to terminate. 
     */ 
     if (wait(&status) < 0) 
     { 
      error("sampleSh: error waiting for child."); 
      perror("wait"); 
     } 

     if (status != 0) 
      error("sampleSh: command exited with nonzero error status."); 
    } 
} 

int main(void) 
{ 
    char *args[] = { "sort", "-r", 0 }; 
    cisshRedirectedInput(args, "fileList"); 
    return 0; 
} 

입력 파일 :

bash-assoc-arrays.sh 
cissh.c 
fileList 
kwargs.py 
makefile 
posixver.h 
rangeinc.c 
select.c 
spc.py 
testcsv.py 
uncrustify.bug 
yield.py 

출력 : 귀하의 답변에 대한

yield.py 
uncrustify.bug 
testcsv.py 
spc.py 
select.c 
rangeinc.c 
posixver.h 
makefile 
kwargs.py 
fileList 
cissh.c 
bash-assoc-arrays.sh 
+0

고마워, 그것을 확인합니다. –

+0

안녕하세요 조나단, 답장을 보내 주셔서 대단히 감사합니다. 나는 당신이 지적한대로 오류를 수정했다. 그러나 이러한 오류는 여전히 나옵니다. "sort : fflush failed : 표준 출력 : 잘못된 파일 설명자" "sort : write error", 이유는 무엇입니까? –

+0

고마워요. 그것은 모든 것을 해결합니다. 방금 오자가 있었어. –