기계는 거짓말하지 않는다

Linux ls 명령어 구현 (2) 본문

Linux

Linux ls 명령어 구현 (2)

KillinTime 2021. 8. 17. 20:40

Linux ls 명령어 구현 (1)

 

Linux ls 명령어 구현 (1)

ls의 옵션 중 –l, -a, -R, -al, -aR, 파이프(-pi)를 구현 코드의 전문이 아닌 일부만 서술 typedef struct info_set { // 파일의 세부정보 저장을 위한 구조체 long link; // 하드링크 개수 long size; // 파일..

machine-does-not-lie.tistory.com

 

lsPipe 함수는 fork를 이용하여 자식 프로세스를 생성하고

dup2 함수를 이용하여 파일 디스크립터를 복제한다.

그리고 execl 함수에 디렉터리 path를 넘겨받는다.

execlp 함수에서 command를 받는다.

void lsPipe(char * dirpath, char * command, char * otherop) {
	int pid1, pid2, fd[2], status;

	if(pipe(fd) == -1) {
		perror("pipe");
		exit(1);
	}
	pid1 = fork();
	if(pid1 == 0) {		// 자식 프로세스 생성
    ...
    }
    else {
    	pid2 = fork();
        if(pid2 == 0) {
        	...
        }
        else {
        	close(fd[0]);
			close(fd[1]);
			waitpid(pid1, &status, 0);
			waitpid(pid2, &status, 0);
        }
    }
    exit(0);
 }

maxWidthCalc 함수는 세부정보 출력시 숫자가 차지하는 너비를 계산하기 위해 필요하다.

setInfo 함수에서 파일 타입, 권한, 링크 수, 시간 등등을 설정한다.

void setInfo(info_set * info, char * path, char * name) {
	struct stat buf;
	struct passwd * pwd;
    struct group * grp;
	struct tm *t;
	int chk = 0;
	char temp[512];
	
	if (lstat(path, &buf) == -1)
    {
        perror("Error: ");
        exit(1);
    }
	
    if (S_ISDIR(buf.st_mode))		// 파일 타입 결정
        info->permission[0] = 'd';
    else if (S_ISCHR(buf.st_mode))
        info->permission[0] = 'c';
    else if (S_ISBLK(buf.st_mode))
        info->permission[0] = 'b';
    else if (S_ISFIFO(buf.st_mode))
        info->permission[0] = 'p';
    else if (S_ISSOCK(buf.st_mode))
        info->permission[0] = 's';
	else if (S_ISLNK(buf.st_mode))  
        info->permission[0] = 'l';
	else
		info->permission[0] = '-';
	
	info->permission[1] = ((buf.st_mode & S_IRUSR) != 0 ? 'r' : '-');		// 권한 문자 지정
	info->permission[2] = ((buf.st_mode & S_IWUSR) != 0 ? 'w' : '-');
	info->permission[3] = ((buf.st_mode & S_IXUSR) != 0 ? 'x' : '-');
	if(buf.st_mode & S_ISUID) info->permission[3] = 'S';
	
	info->permission[4] = ((buf.st_mode & S_IRGRP) != 0 ? 'r' : '-');
	info->permission[5] = ((buf.st_mode & S_IWGRP) != 0 ? 'w' : '-');
	info->permission[6] = ((buf.st_mode & S_IXGRP) != 0 ? 'x' : '-');
	if(buf.st_mode & S_ISGID) info->permission[6] = 'S';
	
	info-> permission[7] = ((buf.st_mode & S_IROTH) != 0 ? 'r' : '-');
	info-> permission[8] = ((buf.st_mode & S_IWOTH) != 0 ? 'w' : '-');
	info-> permission[9] = ((buf.st_mode & S_IXOTH) != 0 ? 'x' : '-');
	if(buf.st_mode & S_ISVTX) info->permission[9] = 'T';
	info->permission[10] = '\0';
	
	pwd = getpwuid(buf.st_uid);
    grp = getgrgid(buf.st_gid);
	
	info->link = buf.st_nlink;		// 링크 수
	info->UID = pwd->pw_name;		// 소유자ID
	info->GID = grp->gr_name;		// 그룹ID
...
}

lsRecurse 함수는 -R 옵션을 이용할 때 재귀적으로 함수를 호출하여 모든 파일을 출력한다.

실행 결과

ls (좌)기본 명령어, (우)구현 명령어
ls -l (좌)기본 명령어, (우)구현 명령어
ls -R (좌)기본 명령어, (우)구현 명령어
ls -al (좌)기본 명령어, (우)구현 명령어

Comments