psh2.c
// 짜잔!
// 이제 드디어 shell의 모습을 갖췄습니다.
// fork 해서 exec 하고 wait까지 할 수 있네요 ㅎㅎ
// psh1.c 처럼 입력을 받아서 엔터를 버리고 null을 집어 넣고
// 배열에 집어 넣은 다음에 fork해서 자식 프로세스가 그 배열 속 내용을 실행하도록 되어있습니다.
// 부모는 wait하구요...
// 더 할 나위 없이 완벽한 코드네요... (실행하는 측면에서만 보면요...)
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxargs 20
#define arglen 100
int execute(char* arglist[]);
char* makestring(char* buf);
main()
{
char* arglist[maxargs+1];
int numargs = 0;
char argbuf[arglen];
while(numargs<maxargs)
{
printf("arg[%d] ? \n",numargs);
if (fgets(argbuf, arglen, stdin) && *argbuf !='\n')
arglist[numargs++] = makestring(argbuf);
else
{
if(numargs>0)
{
arglist[numargs] = NULL;
execute(arglist);
numargs = 0;
}
}
}
}
int execute(char* arglist[])
{
int pid, exitstatus;
pid = fork();
switch (pid)
{
case -1:
perror("fork failed");
exit(1);
case 0:
execvp(arglist[0], arglist);
perror("execvp failed");
exit(1);
default:
while(wait(&exitstatus) != pid)
;
printf("child exited with stauts %d, %d \n", exitstatus>>8, exitstatus&0377);
}
}
char* makestring(char* buf)
{
char* cp;
buf[strlen(buf) - 1] = '\0';
cp = malloc(strlen(buf) + 1 );
if ( cp == NULL)
{
fprintf(stderr,"no memory\n");
exit(1);
}
strcpy(cp, buf);
return cp;
}