수업/System Programming

[System Programming] who 공부

hw-ani 2022. 11. 2. 12:19

`who` 명령어누가 현재 접속 중인지를 출력한다.

이걸 차근차근 구현해보자. (중간중간 유용한 정보 많음)

 

우선 who 명령어가 어떤 명령어인지 알아보려면, `man who` 명령어를 통해 who의 manual page를 볼 수 있다.

읽다보면 who 명령어가 `/var/run/utmp` 파일을 사용해 정보를 읽어와 출력한다는 것을 알 수 있다.(구체 경로는 아마 환경따라 다를거임)

교수님께서 알려주셨는데, 보통 `/var`에 시스템 로그 관련 파일들이 있다.

 

utmp가 이젠 궁금하니, `man utmp` 명령어를 통해 utmp의 manual page를 보자.

참고로 utmp라는 keyword가 나오는 모든 manual page를 검색하고 싶다면, `man -k utmp` 명령어를 이용하면 된다.

그럼 해당 manpage 이름과 해당 keyword가 나오는 page 번호를 알려준다.

강의 자료에선 utmp 5페이지에 utmp 구조체의 선언부가 보인다.

 

자, 이제 우리가 할 일은 간단하다. utmp 파일을 읽고, 출력 형식에 맞게 프린트 하면 된다.

참고로 utmp 파일에는 utmp 구조체가 그대로 저장돼있으니 utmp 구조체를 이용해 읽어오면 된다.

 

이렇게 파일을 읽고 쓰기 위해선

`write()``read()` system call을 이용하면 된다. (return value, parameter 등 세부사항은 생략)

`lseek()' system call은 파일의 특정 position으로 점프해서 contents를 수정할 수 있게 해준다.

 

보면 file open시 mode도 그렇고 이런 write 같은 함수도 그렇고, C 표준 함수랑 대응되는게 자꾸 보인다.
C의 표준 함수들은 그 위에 한번 더 wrapping 한 함수를 제공한다고 보면 될 것 같다.
C도 출발은 UNIX였기때문에 상당히 유사하지만, 다른 OS에선 표준 함수들이 다르게 구현될 수 있다. 그래서 C 표준에선 OS Specific을 피해서 좀 더 일반화해서 말하는 것 같다. (그러니 "왜 write도 있고 fwrite도 있지?" 같은 고민은 세상에 운영체제가 하나 뿐일때나 말이 된다.)

 

 

 

좀 더 효율적으로...

System call을 호출할때 어떤 일이 일어날까?

Linux에는 User mode와 Kernal mode란게 있다. 모든 system call들은 kernal mode로 바껴서 kernal에서 실행된다.

즉, 이는 시간이 꽤 소모되는 작업이다. kernal mode로 바뀌기도 해야하고, 그 내부의 코드들을 실행하기 때문이다.

따라서 System call은 줄일 수 있다면 줄이는게 낫다.

특히 read/write System call은 utmp 구조체 하나씩 받아오는 것보다 buffer를 이용해 read 호출시 여러개를 꺼내오는게 훨씬 이득이다.

 

참고로 system call들 오류 체크는 매번 호출할때마다 해줘야 한다. 그냥 놔두면 좋지 않은 결과가 나올 수 있다.
"보통" System Call들은 반환값을 return으로 주지 않고, 인자로 포인터를 받아서 값을 저장해주는 방식으로 작동한다.
그래서 return 값을 오류 체크로 활용하도록 한다. `0`이면 정상 종료, `nonzero`면 비정상 종료이다.
하지만 전부 위처럼 만들어 지진 않았다. opendir, getgrgid, getpwuid 같은 system calls은 반환값을 구조체 포인터로 주기때문에 반환값이 `NULL`이면 비정상 종료를 나타낸다.

 

 

 


Error Handling

바로 위에서 말한 방법으론 error의 발생 유무만 알 수 있지, 어떤 에러인진 알 수 없다.

<errno.h> 의 errno 변수를 이용해 발생한 error의 종류를 알 수 있다.

perror() 함수는 인자로 받는 string과 errno의 값을 조합해 error 메시지를 출력해준다.