사전 지식
envp: main() 함수 중 프로그램 환경 변수 값을 담고있는 인수이다.
사용 예시
int main( int argc, char **argv, char **envp)
{
while( *envp)
printf( "%s\n", *envp++);
return 0;
}
출력 결과
다음과 같이 환경변수 목록이 출력됨을 확인할 수 있다.
unlink: 파일을 삭제하는 시스템 콜 함수로, 하드링크의 이름을 삭제하고, 하드 링크가 참조하는 count를 1 감소시킨다. rm 명령어 처리할 때 써야하는 것 같다.
사용 예시
int main(int argc, char **argv)
{
unlink(argv[1]);
return (0);
}
execve:
int execve(const char filename, char const argv[], char *const envp[])
첫번째 매개변수로 받은 파일명을 실행시킨다. 이 때 두번째 인자로 옵션을 추가할 수 있다. 환경변수는 어디에 쓰이는건지 잘 모르겠다..
사용 예시
int main(int argc, char **argv, char **envp)
{
execve("/bin/ls", argv, envp);;
return (0);
}
dup2:
int dup2(int fildes, int fildes2)
첫번째 매개변수로 받은 파일디스크립터를 두번째 매개변수의 파일디스크립터로 복제한다. fildes2가 0이면 fildes의 내용을 표준 입력으로 받겠다는 의미이다.
pipe:
int pipe(int fd[2])
하나의 파이프 및 파이프에 대한 두개의 파일 디스크립터를 생성한다.
fd[0] : 데이터를 입력받는 파일 디스크립터이다.
fd[1] : 데이터를 출력할 수 있는 파일 디스크립터이다.
사용 예시
int main(int argc, char *argv[], char *envp[])
{
int pid;
int fd1;
int fd[2];
// 보기 편하라고 정적할당으로 적었지만 실제로는 동적 할당으로 해야하는 것 같다.
const char *grep[3] = {"/usr/bin/grep", "a", 0};
const char *wc[3] = {"/usr/bin/wc", "-w", 0};
int pipe1;
int status;
// infile을 열어 fd1에 저장한다.
fd1 = open("./infile", O_RDONLY);
// 파이프라인을 생성한다.
pipe1 = pipe(fd);
// 표준 입력으로 infiile의 내용을 받는다.
dup2(fd1, 0);
close(fd1);
// 프로세스를 복제한다. (자식 프로세스가 먼저 실행됨)
pid = fork();
if (pid > 0) // 부모 프로세스
{
// 파이프에서 출력된 내용을 표준 입력으로 읽는다.
dup2(fd[0], 0);
close(fd[1]);
close(fd[0]);
// 자식 프로세스가 종료될 때 까지 대기한다.
waitpid(pid, &status, 0);
// 읽어낸 표준 입력의 길이를 카운트한다.
execve(wc[0], wc, envp);
}
else // 자식 프로세스
{
// 파이프에 표준 출력된 내용을 작성한다.
dup2(fd[1], 1);
close(fd[0]);
close(fd[1]);
// 표준 입력으로 받은 infile 내용에서 a를 찾는다.
execve(grep[0], grep, envp);
}
}
문자열 파싱
char **get_cmds(int argc, char **argv)
{
char **cmds;
int i;
int j;
i = -1;
cmds = (char **)malloc(sizeof(char *) * (argc - 1));
if (!cmds)
return (0);
while (++i + 2 < argc - 1)
{
j = 1;
cmds[i] = (char *)malloc(sizeof(char) * (ft_strlen(argv[i + 2]) + 2));
if (!cmds[i])
return (0);
cmds[i][0] = '/';
while (*argv[i + 2])
cmds[i][j++] = *argv[i + 2]++;
cmds[i][j] = 0;
}
cmds[i] = 0;
return (cmds);
}
리다이렉션