psh3.c
// 이전 코드에서 실행 측면에선 완벽하다고 했는데...
// 그럼 뭐가 문제일까...
// 바로 시그널 핸들링입니다!
// shell 프로그램이 cntrl c 공격에 무너진다면 shell 의 역할을 다하지 못하는 것 아니겠습니까 ㅋㅋ
// 그래서 cntrl c 에 대항하는 (사실 이건 이 전에도 나온 내용입니다. sigact나 뭐 그 유사한 이름으로 검색해보세요)
// 코드를 작성하는 것이 목표 입니다.
// 라고 거창하게 적었지만 사실 signal 헤더 파일을 인클루드 하고, 셸 부분 (부모 프로세스) 에서 시그널을 ignore 했다가, 소임을 다하면
// accept 하게 만들어 버리면 됩니다.
// 참 쉽죠?
// .... 는 사실 엄청 헤멤 ㅜ 이게 뭐라고 ㅜㅠ
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.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:
signal(SIGINT,SIG_IGN);
while(wait(&exitstatus) != pid)
;
printf("child exited with stauts %d, %d \n", exitstatus>>8, exitstatus&0377);
signal(SIGINT,SIG_DFL);
}
}
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;
}