나는이 질문을 머리 글자로 쓰고 싶다. 나는 C 언어에 익숙하지 않아서 끔찍한데, 그래서 나는 뻔뻔스러운 실수 나 나쁜 스타일에 대해 사전에 사과한다. 또한, 나는 당신이 내 코드를 표시하기 전에 문제를 소개하는 방법을 잘 모르겠어요, 그래서 여기있다 :프로그램이 이상하게 루프의 맨 위로 돌아 가기
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int MAX_INPUT_SIZE = 200;
volatile int running = 1;
while (running)
{
char input[MAX_INPUT_SIZE];
char *tokens[100];
const char *cmds[] = { "wait", "pwd", "cd", "exit" };
char *cmdargs[100];
printf("shell> ");
fgets(input, MAX_INPUT_SIZE, stdin);
// remove newline character at end
int nl = strlen(input) - 1;
if (input[nl] == '\n')
{
input[nl] = '\0';
}
// tokenize input string, put each token into an array
char *space;
space = strtok(input, " ");
tokens[0] = space;
int i = 1;
while (space != NULL)
{
space = strtok(NULL, " ");
tokens[i] = space;
++i;
}
// copy tokens after first one into string
int noargscheck;
if (tokens[1] != NULL)
{
noargscheck = 0;
strcpy((char *)cmdargs, tokens[1]);
for (i = 2; tokens[i] != NULL; i++)
{
strcat((char *)cmdargs, " ");
strcat((char *)cmdargs, tokens[i]);
}
}
else
{
noargscheck = 1;
}
// compare tokens[0] to list of internal commands
int isInternal = -1;
for (i = 0; i < 4; i++)
{
if (strcmp(tokens[0], cmds[i]) == 0)
{
isInternal = i;
}
}
// internal commands
char wd[200];
if (isInternal != -1)
{
switch (isInternal)
{
case 0:
// wait
break;
case 1:
// pwd
if (getcwd(wd, sizeof(wd)) == NULL)
{
perror("getcwd() error!");
}
else
{
printf("%s\n", wd);
}
break;
case 2:
// cd
if (noargscheck)
{
chdir("/home");
}
else if (chdir((const char *)cmdargs) != 0)
{
perror("cd failed");
}
break;
case 3:
// exit
exit(1);
break;
}
}
else
{
// external commands
pid_t child_pid;
switch (child_pid = fork())
{
case -1:
perror("Fork failed");
return 1;
case 0:
// child
printf("\nHERE\n"); // for debugging
execvp(tokens[0], cmdargs);
break;
}
}
}
}
내가 입력 echo hello world
이 코드를 실행하면 프로그램은 성공적으로 두 번째의 case 0
경우 진입 다음과 같이 switch (child_pid=fork())
하지만 예기치 않은 출력, 시작 스위치 문입니다 :
출력 :
shell> echo hello world
(내 입력)
shell>
는
HERE
shell>
가 (프로그램이 이제 다음 사용자 입력을위한 프롬프트에서 여기 대기)
내가 왜 추가를 알아낼 수 없습니다 (이것은 내가 이해하지 못하는 부분입니다) shell>
프롬프트가 인쇄 중입니다. 아무도 문제를 볼 수 있습니까?
EDIT : execvp의 첫 번째 매개 변수가 수정되었습니다. "echo"
(내가 어리석기 때문에 거기에 있었다)에서 tokens[0]
에 바뀌었다.
* 왜 보이지 않는지 설명 할 수 있습니까? 즉, 코드가이 동작을 초래해서는 안된다고 생각하는 방식을 설명하십시오. –
첫 번째'shell>'과'HERE' 사이에있는 여분의'shell>'이 인쇄되는 것을 원하지 않습니다. Dan은 문제는 내 자식 프로세스가 execvp에서 오류를보고하고 있음을 지적합니다.이 오류는 확인하지 않고 루프의 맨 위로 돌아갑니다. – flexcalibur6