내부 명령 구현 질문이요(오류 잡아주세요)

qurinel의 이미지

main...
while(1) { //while ctrl + d or other interrupt means stop is input
status = 0;
printf("Osshell>");
count = 0;
do {
temp[count] = getc(stdin);
//getc함수로 한글자한글자 받아서 변환을 위해 temp에 저장한다 아직까지는 execvp를 수행할 수 없으며 이 string을 변환할 필요가 있다 왜냐하면 execvp함수의 parameter 형태는 (char** char*)의 형태를 갖추고 있고 그것의 올바른 형태를 만들어줄 필요가 있다.
if(temp[count] == EOF) { //if ctrl + d is inputed
printf("^d is called\n");
break; //end input and end program
}
//여기서 oscd인지 비교하면 세그먼테이션 오류 메모리가 덤프됨 뜸..
count++;
}
while(temp[count-1] != '\n');

if (temp[count] == EOF) // for break loop when ctrl + d is inputed
break;

temp[count-1] = '\0';

if(count == 1) //nothing is inputed, then continue the loop
continue;

if(makeargv(temp, &myargv) == -1) {
perror("makeargv error");
}
//makeargv 함수를 통해서 execvp 함수의 parameter의 올바른 형태를 만들어 낸다.
else if(strcmp(myargv[0], "oscd")==0){
oscd(myargv);
}

else if(strcmp(myargv[0], "osexport")==0){
osexport(myargv);
}
else if(strcmp(myargv[0], "exit")==0){
printf("end shell\n");
exit(0);
}

childpid = fork();

if(childpid == -1) {
perror("Failed to fork");
return 1;
}

else if(childpid == 0) {
write(pd[1], &status, sizeof(int));

//여기서 oscd 등등인지 비교하면 또 세그멘테이션 오류...
execvp(myargv[0], &myargv[0]);
if (errno != 0){
read(pd[0], &status, sizeof(int));
status = -1;
if(write(pd[1], &status, sizeof(int)) == -1)
perror("write error");
}
//만약 잘못된 명령이 들어왔을 경우 기존의 write에 넣었던 state를 error 로 바꾸고 그것을 pipe를 통해서 부모 프로세스로 넘겨준다. 이 동작은 부모프로세스에서 올바르지 않은 명령어에 대한 log를 만들지 않도록 하기 위함이다.
perror("child failed to execvp the command\n");

return 1;
}

void oscd(char **argv){
char env[80];
int chdir_ch = 0, i;
memset(env, '\0', 80);

if(strcmp(argv[1], "~") == 0) {// cd ~ 홈 디렉토리로 이동
strcpy(env, getenv("HOME"));
chdir_ch = chdir(env);
printf("test\n");
}
else if(strcmp(argv[1], "..") == 0) {// cd .. 상위 디렉토리로 이동
getcwd(env, 80);
for(i = strlen(env); i >= 0; i--) {
if(env[i] == '/'){
env[i] ='\0';
break;
}
}
chdir_ch = chdir(env);
}
else if(strcmp(argv[1], ".") == 0) {//cd . 현재 디렉토리로 이동
getcwd(env, 80);
chdir_ch = chdir(env);
}

else if(strcmp(argv[1], "-") == 0) {// cd - 이전 디렉토리로 이동
strcpy(env, getenv("OLDPWD"));
chdir_ch = chdir(env);
}

else {// cd [path] [path]로 이동
chdir_ch = chdir(argv[1]);
}
if(chdir_ch == -1)
printf("디렉토리 이동 실패\n");
}

일단 cd부터 올립니다.
처음에 사용자로부터 입력을 받아서 파싱을 하고
만약 oscd, osls...등등 제가 짠 내부 명령어이면 oscd(argv)해서 해당 함수로 넘어가고
아니면 자식 프로세스 생성하고 나서 거기서 실행하도록... 했는데
외부 명령어는 잘만 됩니다만..
내부명령어가 문제에요
컴파일은 아무 문제가 없는데 oscd ~ 이런 명령 입력하면 세그먼트 오류 메모리가 덤프됨이 뜹니다.
\일일이 프린트에프 넣어줘서 확인해보니깐 저위에 ~인 경우만 보면 test 이 문자 출력한 후에 뜨더라구요..
chdir_ch = chdir(env) 여기서 걸리는 거 같은데.. ㅠ
뭐가 문제인지 아시는 분 없나요..;
아 부모프로세스에서 비교해서 넘어갈 때는 세그멘테이션 오류 뜨구요
자식프로세스에서 비교해서 넘어가면 오류는 안 뜨는데 cd ..이든 ~이든 변함이 없어요;;; 현재 디렉토리 그대로 있습니다.exit도 안 되네요

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.