Chapter 6: System Data Files and Information UNIX System S.W. Tak
Chapter6: System Data Files and Information Introduction Numerous data files required fro normal operation Example: /etc/password and /etc/group The password file is used every time a user logins in to a UNIX system Historically, these data files have been ASCII text files and were read with the standard I/O library For larger systems a sequential scan is time consuming Solution Store these data files in format other than ASCII text Provide an interface for an application program that works with any file format Chapter6: System Data Files and Information
Chapter6: System Data Files and Information /etc/passwd file See Fig 6.1shows struct passwd member Fields in /etc/passwd file Description struct passwd member POSIX.1 User name char *pw_nam Encrypted password char *pw_passwd Numerical user ID uid_t pw_uid Numerical group ID gid_t pw_gid Comment field char *pw_gecos Initial working directory char *pw_dir Initial shell (user program) char *pw_shell Chapter6: System Data Files and Information
User’s login name and numerical user ID #include <sys/types.h> #include <pwd.h> struct passwd *getpwuid(uid_t uid); struct passwd *getpwnam(const char *name); getpwuid is used by the ls(1) program It maps the numerical user ID contained in an i-node into a user’s login name getpwnam is used by the login(1) program, when we enter our login name Chapter6: System Data Files and Information
User’s login name and numerical user ID (Cont’d) #include <sys/types.h> #include <pwd.h> struct passwd *getpwent(void); Return: pointer if OK, NULL on error or end of file void setpwent(void); void endpwent(void); getpwent It returns the next entry in the password file If this is the first call to this function, it opens whatever files it uses Otherwise, this structure is normally overwritten each time we call this function There is no order implied when we use this function – the entries can be in any order (This is because some systems use a hashed version of the file /etc/passwd) setpwent rewinds whatever files it uses, and endpwent closes files Chapter6: System Data Files and Information
User’s login name and numerical user ID (Cont’d) #include <unistd.h> char *getlogin(void); getlogin It returns a pointer to a string containing the name of the user logged in on the controlling terminal of the process, or a null pointer if this information cannot be determined. Chapter6: System Data Files and Information
User’s login name and numerical user ID (Cont’d) #include <unistd.h> char *cuserid(char *string); cuserid It returns a pointer to a string containing a user name associated with the effective user ID of the process. If string is not a null pointer, it should be an array that can hold at least L_cuserid characters, the string is returned in this array. The macro L_cuserid is an integer constant that indicates how long an array you might need to store a user name. L_cuserid is declared in stdio.h. Otherwise, a pointer to a string in a static area is returned. This string is statically allocated and might be overwritten on subsequent calls to this function or to getlogin. These functions let your program identify positively the user who is running (cuserid) or the user who logged in this session (getlogin). (These can differ when setuid programs are involved.) Chapter6: System Data Files and Information
Chapter6: System Data Files and Information Shadow Passwords Make it harder to obtain the new materials (the encrypted passwords) Some systems store the encrypted password in another file, called the shadow password file Minimally this file has to contain the user name and the encrypted password Chapter6: System Data Files and Information
Chapter6: System Data Files and Information Login Accounting struct utmp { char ut_line[8]; /* tty line: “ttyh0”, “ttyd0”, … */ char ut_name[8]; /* login name */ long ut_time; /* seconds since Epoch */ } /* a binary record */ The wtmp file keeps track of all logins and logouts On login, one of these structures was filled in and written to the /var/run/utmp file by the login program, and the same structure was appended to the /var/log/wtmp file On logout, the entry in the utmp file was erased (filled with 0 bytes) by the init process This logout entry in the wtmp file had the ut_name field zeroed out. The who(1) program read the utmp file and printed its contents in a readable form The last (1) command read through the wtmp file and printed selected entries Chapter6: System Data Files and Information
System Identification #include <sys/utsname.h> int uname(struct utsname *uname); 현재 사용 중인 호스트와 운영체제에 관한 정보를 알아낸다. utsname 자료구조 ‘uname -a’ 명령 struct utsname { char sysname[_SYS_NMLN]; /* name of the operating system */ char nodename[_SYS_NMLN]; /* name of this node */ char release[_SYS_NMLN]; /* current release of operating system */ char version[_SYS_NMLN]; /* current version of this release */ char machine[_SYS_NMLN]; /* name of hardware type */ } Chapter6: System Data Files and Information
System Identification (Cont’d) 버클리(Berkeley) 시스템에서 도입 호스트 이름만 리턴하며, 이 이름은 보통 TCP/IP 네트워크 상의 이름이다. 호스트 이름의 길이는 <sys/param.h>에 정의된 MAXNAMELEN 상수에 의해 제한된다. ‘hostname’ 명령 #include <unistd.h> int gethostname(char *name, int namelen); Chapter6: System Data Files and Information
System Identification (Cont’d) #include <sys/utsname.h> #include <sys/param.h> #include <unistd.h> int main() { struct utsname name; char hostname[MAXNAMELEN]; uname(&name); printf("sysname : %s\n", name.sysname); printf("nodename : %s\n", name.nodename); printf("release : %s\n", name.release); printf("version : %s\n", name.version); printf("machine : %s\n", name.machine); gethostname(hostname, MAXNAMELEN); printf("hostname : %s\n", hostname); } [lab]src 77 > system_id sysname : SunOS nodename : lab release : 5.6 version : Generic machine : sun4u hostname : lab [lab]src 78 > uname -a SunOS lab 5.6 Generic sun4u sparc SUNW,Ultra-1 [lab]src 79 > hostname lab Chapter6: System Data Files and Information
Chapter6: System Data Files and Information 유닉스 시간 정보 달력 시간 (calendar time) UTC (Coordinated Universal Time) 1970년 1월 1일 00:00:00 이후부터 현재까지 흐른 시간을 초(seconds)로 환산한 값을 제공 (time_t 데이터 형) 지역 시간(local time)이 아닌 UTC 기준의 시간 일광 절약 시간 (daylight saving time, summer time) 의 자동 변환 시간과 날짜 정보가 한꺼번에 유지 프로세스 시간 (process time) 프로세스가 사용한 CPU 시간 (clock_t 데이터 형) 클럭 틱 (clock tick) 단위로 측정 보통 1초당 50, 60, 100 tick CLK_TCK 상수로 결정 clock time, user CPU time, system CPU time Chapter6: System Data Files and Information
Chapter6: System Data Files and Information 달력 시간 (calendar times) 현재 시간과 날짜를 리턴한다. calptr 인자가 NULL이 아니면 calptr가 가리키는 곳에도 시간 값을 저장한다. time 함수의 리턴 값은 부가 함수들을 이용하여 사람이 읽을 수 있는 시간과 날짜 정보로 변환된다. (그림 참조) 그림에서 (빨강) 점선으로 표시되는 함수들은 TZ 환경 변수 (Environment Variable)의 영향을 받는다. #include <time.h> time_t time(time_t *calptr); Chapter6: System Data Files and Information
Relationship of the Various Time Functions 문자열 형식화된 문자열 ctime asctime strftime (분해된 시간, broken-down time) struct tm localtime mktime gmtime (달력 시간, calendar time) time_t time Chapter6: System Data Files and Information kernel
Chapter6: System Data Files and Information Broken-down time struct tm { /* a broken-down time */ int tm_sec; /* seconds after the minute - [0, 61] */ /* for leap seconds */ int tm_min; /* minutes after the hour - [0, 59] */ int tm_hour; /* hour since midnight - [0, 23] */ int tm_mday; /* day of the month - [1, 31] */ int tm_mon; /* months since January - [0, 11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday - [0, 6] */ int tm_yday; /* days since January 1 - [0, 365] */ int tm_isdst; /* flag for alternate daylight savings time */ } 초(tm_sec) 값이 59보다 클 수 있다. 윤초의 수용 일광 절약 시간이 적용되는 경우에 tm_isdst은 양의 값을 가진다. Chapter6: System Data Files and Information
Chapter6: System Data Files and Information 원자시와 윤초 (쉬어가는 페이지) 원자시계 (원자 주파수 표준기)가 개발됨으로써 짧은 시간동안에 정확하게 결정되는 새로운 초의 시대가 열렸다. 1967년에, 일초는 세슘원자에서 발생하는 복사선의 주파수로 정의되었다. 구체적으로 말하면, 국제적인 합의에 의해, 표준 일초는 외부에서 아무 방해를 받지 않는 세슘원자가 9,192,631,770 번 진동하는 시간으로 정의되었다. 마치 추시계에서 추가 흔들린 횟수를 세듯이 원자시계에 딸린 전자장비가 이 진동수를 세어서 표시한다. 원자시계 덕분에 일초의 길이는 일분 이내에 10억분의 1초 까지 정확히 결정될 수 있었다. 그러나 이 새로운 초의 정의는 지구의 운동과는 전혀 무관하기 때문에 지구자전의 불규칙성에 기인한 원자시와 세계시가 서로 어긋나는 문제는 여전히 남아있었다. 원자시와 세계시가 서로 어긋나는 문제를 해결하기 위해 1972년에 "윤초"가 발명되었다. 윤초는 윤년과 비슷한 개념이다. 즉, 태양 주위를 도는 지구의 위치와 달력의 날짜를 일치시킬 목적으로 매 4년마다 2월 마지막 날에 하루를 더하는 것이 윤년이다. 이에 비해 윤초는 지구자전의 불규칙성 때문에 발생하는 시간차를 보정하기 위해 일초를 더하거나 빼는 것을 말한다. 좀더 자세히 말하면, UTC는 UT1과 0.9초 이내에서 항상 일치하도록 만든다. 그리고 12월이나 6월의 마지막 날 마지막 분에 일초를 더하거나 빼는데, 이때는 일분이 61초가 되거나 59초가 된다. 언제 윤초를 적용해야 하는지에 관한 정보는 프랑스 파리에 있는 국제도량형국 (BIPM)에서 세계 각국에 있는 시간주파수 표준연구실로 알려준다. 1972년 -윤년-에는 두 번의 윤초가 더해져서 현대에 들어 가장 긴 일년이 되었다. 지금까지 빼기 윤초를 적용한 경우는 없고 모두 더해지기만 했는데, 1999년 현재 총 32초가 더해졌다. Chapter6: System Data Files and Information
Chapter6: System Data Files and Information 달력 시간 변환 함수들 #include <time.h> struct tm *gmtime(const time_t *calptr); struct tm *localtime(const time_t *calptr); 달력 시간을 분해된 시간으로 변환한다. localtime은 지역 시간과 일광 절약 시간을 고려하여 변환한다. gmtime은 UTC로 표시되는 시간으로 변환한다. Chapter6: System Data Files and Information
Chapter6: System Data Files and Information 달력 시간 변환 함수들 (Cont’d) #include <time.h> time_t mktime(struct tm *tmptr); 지역 시간으로 표시되는 분해된 시간을 time_t 값으로 변환한다. Chapter6: System Data Files and Information
Chapter6: System Data Files and Information 시간 값의 문자열 변환 함수들 #include <time.h> char *asctime(const struct tm *tmptr); char *ctime(const time_t *calptr); 사람이 읽을 수 있는 26 바이트 문자열 형태의 시간 정보로 변환한다. asctime은 분해된 시간 값을 ctime은 달력 시간 값을 인자로 갖는다. Chapter6: System Data Files and Information
시간 값의 문자열 변환 함수들 (Cont’d) #include <time.h> size_t strftime(char *buf, size_t maxsize, const char *format, const struct tm *tmptr); printf 함수와 비슷한 방식으로 시간 정보를 변환한다. 변환되어 저장된 문자열의 크기를 리턴한다. 인자 buf : 변환된 문자열을 저장할 메모리 maxsize : buf의 크기 format : 변환 방식을 지정하는 문자열 tmptr : 분해된 시간 값 ‘date’ 명령의 예 [root@UNC-LAB unix]# date 2004. 10. 06. (수) 02:31:37 KST Chapter6: System Data Files and Information
Conversion specifying for strftime 형식 설명 예 (Sun Feb 7 19:20:28 1999) %a %A %b %B %c %d %H %I %j %m %M %p %S %U %w %W %x %X %y %Y %Z 간략한 요일 이름 완전한 요일 이름 간략한 월 이름 완전한 월 이름 날짜와 시간 월 중의 일: [01, 31] 24 시간으로 표시한 시간: [00,23] 12 시간으로 표시한 시간: [01,12] 년 중의 일: [001, 365] 월: [01, 12] 분: [00, 59] AM / PM 초: [00, 61] 일요일 주 수: [00, 53] 요일: [0=일요일, 6] 월요일 주 수: [00, 53] 날짜 시간 세기 없는 년도 세기 있는 년도 시간 대 이름 Sun Sunday Feb February Sun Feb 07 19:20:28 1999 07 19 038 02 20 PM 28 06 05 02/07/99 19:20:28 99 1999 KST Chapter6: System Data Files and Information
프로세스 시간 (process times) #include <sys/times.h> clock_t times(struct tms *buf); 클럭 시간 (clock time, clock_t 형) 과거 임의의 시점으로부터 측정되어 times 함수에 의해 리턴된다. 상대적인 값으로써 사용해야 한다. 즉, times 함수를 호출하고 그 리턴 값을 저장한 후, 다음 번 times 함수의 리턴 값과 미리 저장한 리턴 값 사이의 차를 계산하여 두 호출 사이의 기간을 측정한다. 클럭 tick (clock_t)은 1 초당 클럭 tick의 수(sysconf(_SC_CLK_TCK))를 이용하여 초 단위로 환산한다. Chapter6: System Data Files and Information
Chapter6: System Data Files and Information tms Data Structure struct tms { clock_t tms_utime; /* user CPU time */ clock_t tms_stime; /* system CPU time */ clock_t tms_cutime; /* user CPU time, terminated children */ clock_t tms_cstime; /* system CPU time, terminated children */ } 자신과 종료된 자식 프로세스들의 사용자 CPU 시간, 시스템 CPU 시간 정보를 저장한다. 부모가 wait를 수행한 자식 프로세스의 시간 정보만 포함된다. Chapter6: System Data Files and Information
Process Time Measurement #include <sys/times.h> #include <stdio.h> #include <unistd.h> static void pr_times(clock_t, struct tms *, struct tms *); static void do_cmd(char *); int main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) do_cmd(argv[i]); /* once for each command-line arg */ exit(0); } static void do_cmd(char *cmd) /* execute and time the "cmd" */ struct tms tmsstart, tmsend; clock_t start, end; int status; fprintf(stderr, "\ncommand: %s\n", cmd); if ((start = times(&tmsstart)) == -1) /* starting values */ err_sys("times error"); if ((status = system(cmd)) < 0) /* execute command */ err_sys("system() error"); if ((end = times(&tmsend)) == -1) /* ending values */ err_sys("times error"); pr_times(end-start, &tmsstart, &tmsend); pr_exit(status); } static void pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend) { static long clktck = 0; if (clktck == 0) /* fetch clock ticks per second first time */ if ((clktck = sysconf(_SC_CLK_TCK)) < 0) err_sys("sysconf error"); fprintf(stderr, " real: %7.2f\n", real / (double) clktck); fprintf(stderr, " user: %7.2f\n", (tmsend->tms_utime - tmsstart->tms_utime) / (double) clktck); fprintf(stderr, " sys: %7.2f\n", (tmsend->tms_stime - tmsstart->tms_stime) / (double) clktck); fprintf(stderr, " child user: %7.2f\n", (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck); fprintf(stderr, " child sys: %7.2f\n", (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck); Chapter6: System Data Files and Information
Process Time Measurement (Cont’d) if ((status = system(cmd)) < 0) /* execute command */ err_sys("system() error"); if ((end = times(&tmsend)) == -1) /* ending values */ err_sys("times error"); pr_times(end-start, &tmsstart, &tmsend); pr_exit(status); } static void pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend) { static long clktck = 0; if (clktck == 0) /* fetch clock ticks per second first time */ if ((clktck = sysconf(_SC_CLK_TCK)) < 0) err_sys("sysconf error"); fprintf(stderr, " real: %7.2f\n", real / (double) clktck); fprintf(stderr, " user: %7.2f\n", (tmsend->tms_utime - tmsstart->tms_utime) / (double) clktck); fprintf(stderr, " sys: %7.2f\n", (tmsend->tms_stime - tmsstart->tms_stime) / (double) clktck); fprintf(stderr, " child user: %7.2f\n", (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck); fprintf(stderr, " child sys: %7.2f\n", (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck); [lab]src 48 > times1 "sleep 5" "date" command: sleep 5 real: 5.04 user: 0.00 sys: 0.00 child user: 0.01 child sys: 0.02 normal termination, exit status = 0 command: date Sun Feb 7 19:58:32 KST 1999 real: 0.05 child user: 0.03 child sys: 0.01 Chapter6: System Data Files and Information