본문 바로가기
컴퓨터 기초/운영체제 실습

[운영체제 실습] 8.시스템 정보 다루기 - (그룹, 시간)

by 인생여희 2020. 6. 27.

 

#.그룹정보검색 - getgid, getegid 함수 사용하기 

 

예제

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
/*
유닉스 시스템에서 사용자는 하나 이상의 그룹에 속한다.
그룹도 사용자와 마찬가지로 그룹 id 가 있다.
그룹 id를 검색하는 함수로는 getgid(), getegid() 가 있다.
*/
int main(void) {
gid_t gid, egid;
//실제 그룹 id 리턴(로그인할때 사용한 사용자 계정의 기본 그룹)
gid = getgid();
//유효 그룹 id 리턴(프로세스에 대한 접근 권한을 부여할때 사용)
egid = getegid();
printf("GID=%d, EGID=%d\n", (int)gid, (int)egid);
return 0;
}
view raw ex4_12.c hosted with ❤ by GitHub

결과

 

 

 참고 : 유닉스에서는 그룹에 관한 정보를 /etc/group 파일에 별도로 저장한다.

 사용자가 속한 그룹 중 /etc/passwd 파일의 GID 항목에 지정된 그룹이 기본 그룹이며,

 2차 그룹은 /etc/group 파일에서 지정한다.

 

#.그룹 파일 검색 - getgrnam 함수 사용하기

 

예제

#include <grp.h>
/*
유닉스에서는 그룹에 관한 정보를 /etc/group 파일에 별도로 저장한다.
사용자가 속한 그룹 중 /etc/passwd 파일의 GID 항목에 지정된 그룹이 기본 그룹이며,
2차 그룹은 /etc/group 파일에서 지정한다.
*/
int main(void) {
//etc/group파일을 읽어오기 위한 그룹구조체
struct group *grp;
int n;
//adm 그룹의 정보를 검색한다.
grp = getgrnam("adm");
printf("Group Name : %s\n", grp->gr_name);
printf("GID : %d\n", (int)grp->gr_gid);
//group 구조체의 gr_mem 항목이 배열이므로 반복문을 이용해서 출력
n = 0;
printf("Members : ");
while (grp->gr_mem[n] != NULL)
printf("%s ", grp->gr_mem[n++]);
printf("\n");
return 0;
}
view raw ex4_13.c hosted with ❤ by GitHub

결과

 

#./etc/group 파일을 순차적으로 읽기 

 

예제

#include <grp.h>
#include <stdio.h>
/*
etc/group 파일을 순차적으로 읽기
getgrent : etc/group 파일에서 사용자 정보를 순차적으로 읽어온다. 파일의 끝을 만나면 null point를 리턴한다.
setgrent : etc/group 파일의 오프셋을 파일의 처음에 놓는다.
endgrent : etc/group 파일을 닫는다.
fgetgrent : 인자로 파일 포인터를 받는다. etc/group 파일이 아닌 파일 포인터가 가리키는 파일에서 사용자 정보를 읽어온다.
따라서, 파일 포인터가 가리키는 파일의 내부 구조는 /etc/group 와 동일해야 한다.
*/
int main(void) {
struct group *grp;
int n,m;
for (n = 0; n < 3; n++) {
//getgrent : etc/group 파일에서 사용자 정보를 순차적으로 읽어온다. 파일의 끝을 만나면 null point를 리턴한다.
grp = getgrent();
printf("GroupName: %s, GID: %d ", grp->gr_name, (int)grp->gr_gid);
m = 0;
printf("Members : ");
while (grp->gr_mem[m] != NULL)
//그룹에 해당하는 맴버 출력
printf("%s ", grp->gr_mem[m++]);
printf("\n");
}
return 0;
}
view raw ex4_14.c hosted with ❤ by GitHub

결과

 

 

#.로그인 기록 검색

 

who 명령으로 현재 시스템에 로그인하고 있는 사용자에 관한 정보를 검색할 수 있다. last 명령으로는 시스템의 부팅 시각 정보나 사용자 로그인 기록 등을 검색할 수 있다. 이러한 정보는 /var/adm/wtmpx 파일에 저장된다. 이 파일은 바이너리 형태로 저장되기 때문에 vi로 확인할 수 없다. 이 파일의 정보를 읽어 오려면, 파일의 구조와 관련된 구조체와 함수가 필요하다.

 

 

#.var/adm/utmpx/ 파일을 순차적으로 읽기

 

예제

#include <sys/types.h>
#include <utmpx.h>
#include <stdio.h>
/*
var/adm/utmpx/ 파일을 순차적으로 읽기
utmpx : var/adm/utmpx/ 파일에서 사용자 정보를 순차적으로 읽어온다. 파일의 끝을 만나면 null point를 리턴한다.
setutxent : var/adm/utmpx/ 파일의 오프셋을 파일의 처음에 놓는다.
endutxent : var/adm/utmpx/ 파일을 닫는다.
utmpxname : 로그인 정보 파일을 file로 지정한 다른 파일로 변경한다. 예를 들어, last 명령에서 사용하는
/var/adm/wtmpx 파일로 변경할 때 사용한다.
*/
int main(void) {
struct utmpx *utx;
printf("LoginName Line\n");
printf("---------------\n");
while ((utx=getutxent()) != NULL) {
if (utx->ut_type != USER_PROCESS)
continue;
//로그이명과 터미널 번호 출력
printf("%s %s\n", utx->ut_user, utx->ut_line);
}
return 0;
}
view raw ex4_15.c hosted with ❤ by GitHub

결과

/var/adm/utmpx 파일의 내용을 한행씩 읽어서 로그인명과 터미널 번호를 출력한다.

 

#.기본시간정보 얻기 - time 함수 사용하기

 

예제

#include <sys/types.h>
#include <time.h>
#include <stdio.h>
/*
유닉스 시스템은 1970년 1월 1일 0시 0분 0초 부터 현재까지 경과한 시간을 초 단위로 저장하고,
이를 기준으로 시간정보를 관리한다.
*/
int main(void) {
time_t tt;
//time 함수는 1970년 1월 1일 0시 0분 0초 부터 현재까지 경과한 시간을 초 단위로 알려준다.
//실패하면 -1 리턴
time(&tt);
printf("Time(sec) : %d\n", (int)tt);
return 0;
}
view raw ex4_16.c hosted with ❤ by GitHub

 

결과

1970년 1월 1일 0시 0분 0초부터 현재까지 위의 시간만큼 경과했다.

 

 

#.gettimeofday 함수 사용하기

 

예제

#include <sys/time.h>
#include <stdio.h>
int main(void) {
//bsd 계열 유닉스에서 도입한 gettimeofday 함수는 시간 정보를 timeval 구조체에
//저장해서 리턴한다.
//timeval 구조체
struct timeval tv;
//시간
gettimeofday(&tv, NULL);
//초
printf("Time(sec) : %d\n", (int)tv.tv_sec);
//마이크로초
printf("Time(micro-sec) : %d\n", (int)tv.tv_usec);
return 0;
}
view raw ex4_16.c hosted with ❤ by GitHub

결과

 

현재시간은  1593240775. 689731초 이다.

 

#.시간대 정보 - tzset 함수 이용하기

 

예제

#include <time.h>
#include <stdio.h>
int main(void) {
/*
svr4 계열의 유닉스는 기본 시간대 정보를 환경 변수 tz에 설정한다.
시스템의 기본 시간대 정보는 /etc/default/init 파일에 TZ=ROK 와 같은 형태로 지정되어 있다.
*/
//tzset 함수는 현재 지역의 시간대로 시간대를 지정한다.
tzset();
//utc와 지역시간대와의 시차를 초 단위로 저장한다.
printf("Timezone : %d\n", (int)timezone);
//printf("Altzone : %d\n", (int)altzone);
//일광 절약제를 시행하면 0이 아니고, 그렇지 않으면 0이다.
printf("Daylight : %d\n", daylight);
//지역 시간대와 보정된 시간대명을 약어로 저장한다.
printf("TZname[0] : %s\n", tzname[0]);
printf("TZname[1] : %s\n", tzname[1]);
return 0;
}
//실행결과를 보면 우리나라의 표준시는 utc와 32,400초(9시간) 차이가 난다.
//표준 시간대의 이름은 KST 이다.
view raw ex4_18.c hosted with ❤ by GitHub

 

결과

실행결과를 보면 우리나라의 표준시는 utc와 32,400초(9시간) 차이가 난다.  표준 시간대의 이름은 KST 이다.

 

 

#.시간의 형태 변환 - gmtime, localtime 함수 사용하기

 

예제

#include <time.h>
#include <stdio.h>
//tm 구조체 : 초 단위 시간정보를 년, 월, 일로 분해해 저장할 때 tm 구조체를 사용한다.
// struct tm
// {
// int tm_sec; /* 초 */
// int tm_min; /* 분 */
// int tm_hour; /* 시간 */
// int tm_mday; /* 일/월 */
// int tm_mon; /* 월 */
// int tm_year; /* 년 */
// int tm_wday; /* 일/주 */
// int tm_yday; /* 일/년 */
// int tm_isdst; /* 섬마타임 */
// };
// 월은 0부터 시작한다. 그러므로 프로그램상에서 제대로 표현하려면 +1을 해주어야 한다. 또한 년의 경우에는 +1900 해주어야 한다.
int main(void) {
struct tm *tm;
time_t t;
time(&t);
printf("Time(sec) : %d\n", (int)t);
//초단위 시간 정보를 인자로 받아 tm 구조체 형태로 리턴한다.
//utc 시간대를 기준으로 시간을 분해한다.
tm = gmtime(&t);
printf("GMTIME=Y:%d ", tm->tm_year);
printf("M:%d ", tm->tm_mon);
printf("D:%d ", tm->tm_mday);
printf("H:%d ", tm->tm_hour);
printf("M:%d ", tm->tm_min);
printf("S:%d\n", tm->tm_sec);
//초단위 시간 정보를 인자로 받아 tm 구조체 형태로 리턴한다.
//지역 시간대를 기준으로 시간을 분해한다.
tm = localtime(&t);
printf("LOCALTIME=Y:%d ", tm->tm_year);
printf("M:%d ", tm->tm_mon);
printf("D:%d ", tm->tm_mday);
printf("H:%d ", tm->tm_hour);
printf("M:%d ", tm->tm_min);
printf("S:%d\n", tm->tm_sec);
return 0;
}
view raw ex4_19.c hosted with ❤ by GitHub

결과

년도는 리턴값에 +1900을 더해야 실제 년도를 출력할 수 있다. 요일은 0은 일요일, 6은 토요일을 의미한다. 

 

 

#.초 단위 시간으로 역산 - mktime 함수 사용하기

 

예제

#include <time.h>
#include <stdio.h>
/*
mktime 함수는 gmtime 이나 localtime 함수와 반대 역할을 수행한다.
mktime 함수는 tm 구조체 형태의 시간을 인자로 받아 이를 1970년 1월 1일 0:0:0 부터
얼마나 지났는지 초 단위로 계산해 리턴한다.
*/
int main(void) {
//시간정보 구조체
struct tm tm;
//이 값은 1970 년 1 월 1 일 자정 (UTC) 에서 부터 현재 까지 흐른 초 수를 의미한다.
time_t t;
//기본 타임 서비스에서 카운트한 time_t 값을 반환하는 함수
time(&t);
printf("Current Time(sec) : %d\n", (int)t);
//tm 구조체에 2009 년 12월 31일 12:30:00을 지정하고 , mktime 함수를 사용해 초단위로 변환하기.
tm.tm_year = 109;
tm.tm_mon = 11;
tm.tm_mday = 31;
tm.tm_hour = 12;
tm.tm_min = 30;
tm.tm_sec = 0;
//struct tm 형식을 time_t 형식으로 변환하는 mktime
//인자는 시간 정보를 저장한 tm 구조체 주소
t = mktime(&tm);
printf("2009/12/31 12:30:00 Time(sec) : %d\n", (int)t);
return 0;
}
view raw ex4_20.c hosted with ❤ by GitHub

결과

실행결과는 time 구조체에 설정한 시각이 초로 변환되었다.

 

 

#.형식 지정 시간 출력 - ctime 함수 사용하기

 

예제

#include <time.h>
#include <stdio.h>
int main(void) {
time_t t;
//초단위 시간을 검색한다.
time(&t);
//초단위 시간을 출력한다.
printf("Time(sec) : %d\n", (int)t);
//초단위 시간을 ctime 함수로 변환해 출력한다.
printf("Time(date) : %s\n", ctime(&t));
return 0;
}
view raw ex4_21.c hosted with ❤ by GitHub

결과

 

 

#.tm 구조체 시간을 변환해서 출력 - asctime 함수 사용하기

 

예제

#include <time.h>
#include <stdio.h>
//asctime 함수는 tm 구조체로 분해된 시간을 인자로 받고, 사람이 보기 편한 형태로 변경해
//문자열로 리턴한다. 출력형태는 ctime 함수와 동일하다.
int main(void) {
//시간 정보 구조체
struct tm *tm;
time_t t;
//시간정보 검색
time(&t);
//현재 지역대의 시간 검색해서 tm 구조체에 저장
tm = localtime(&t);
//초단위
printf("Time(sec) : %d\n", (int)t);
//문자 형태
printf("Time(date) : %s\n", asctime(tm));
return 0;
}
view raw ex4_22.c hosted with ❤ by GitHub

결과

 

 

#.strftime 함수 사용하기

 

예제

#include <time.h>
#include <stdio.h>
//strftime 함수를 사용하면 printf 문처럼 형식 지정자를 사용해 시간 정보를 출력할 수 있다.
/*
인자 설명 - buf : 출력할 시간 정보를 저장할 배열 주소
- sizeof(buf) : buf 의 크기
- output[n] : 출력 형식을 지정한 문자열
- tm : 출력할 시간 정보를 저장한 구조체 주소
*/
//strftime(buf, sizeof(buf), output[n], tm);
char *output[] = {
"%x %X",
"%Gyear %mmonth %dday %Uweek %H:%M",
"%r"
};
int main(void) {
struct tm *tm;
int n;
time_t t;
char buf[257];
time(&t);
tm = localtime(&t);
for (n = 0; n < 3; n++) {
strftime(buf, sizeof(buf), output[n], tm);
printf("%s = %s\n", output[n], buf);
}
return 0;
}
view raw ex4_23.c hosted with ❤ by GitHub

결과

 

 

예제파일

ch04.zip
0.02MB

 

 

 

 

 

참고 : 유닉스시스템 프로그래밍(한빛미디어)