190 likes | 353 Views
[Unix Programming] Process3. Young-Ju, Han Email: yjhan@imtl.skku.ac.kr. Contents. inherited data and file descriptors synchronizing processes process attributes Process id Process ownership Changing of Process ownership Process Time. inherited data and file descriptors.
E N D
[Unix Programming]Process3 Young-Ju, Han Email: yjhan@imtl.skku.ac.kr
Contents • inherited data and file descriptors • synchronizing processes • process attributes • Process id • Process ownership • Changing of Process ownership • Process Time 2007 UNIX Programming
inherited data and file descriptors Before fork : 10 Child before read : 10 Child after read : 20 Parent after wait : 20 • ex) pro_file #include <unistd.h> #include <fcntl.h> int fatal(char *s) {perror(s); exit(1);} void printfos(char *s, int fd){ printf(“%s : %d\n”, lseek(fd,0, SEEK_CUR)); main(){ int fd, pid_t pid; char buf[10]; fd = open(“data”, O_RDONLY); read(fd, buf, 10); printpos(“Before fork”, fd); switch(pid = fork()) { case -1 : fatal(); break; case 0 : printpos(“Child before read”, fd); read(fd, buf, 10); printpos(“Child after read”, fd); break; default : wait((int *)0); printpos(“Parent after wait”, fd); } } 2007 UNIX Programming
res = fcntl(fd, F_GETFD, 0); if res == 1 then on else off inherited data and file descriptors • exec and open files • close-on-exec flag (FD_CLOEXEC- default : off(0)) • If FD_CLOEXEC == 1, exec를 호출할 때 개방된 file descriptors를 close시킴 • If FD_CLOEXEC == 0, exec를 호출할 때 개방된 file descriptors 계속 유지 #include <fcntl.h> main(){ int fd; . fd = open(“data”, O_RDONLY); . fcntl(fd, F_SETFD, 1); execl(“/bin/ls”,”ls”, (char*) 0); . } 2007 UNIX Programming
synchronizing processes • Child terminates • Kernel sends SIGCHLD signal to parent • an asynchronous event • Default action for SIGCHLD signal: • ignore it • Signal handlers can be defined by users • call wait() to fetch the termination status of child 2007 UNIX Programming
PID of the exiting child -1 = no child exists (ECHILD) NULL : ignore valid pointer : status info. when wait return synchronizing processes • wait • block until any child has finished • return immediately with the termination status of a child, or • return immediately with an error (if it doesn’t have any child processes) • often called just after a fork call #include <sys/types.h> #include <sys/wait.h> pid_t wait (int *status); WIFEXITED(status) = 1 : normally exit 0 : stopped by signal WEXITSTATUS(status) = value stored in the high-order bits of status 2007 UNIX Programming
child PID 0 = if WNOHANG is setting and no use child-1 = error 0 : no use WNOHANG : return 0 if the child has running WUNTRACED : the status of any stopped child <sys/wait.h> synchronizing processes • waitpid • waiting for a particular child, supporting for non-blocking • pid == -1; waits for any child process ( =wait) • pid > 0; waits for the child whose process ID equals pid • pid == 0; waits for any child whose process group ID equal that of the calling process • pid < -1 waits for any child whose process group ID equals the absolute value of pid #include <sys/types.h> #include <sys/wait.h> pid_t waitpid (pid_t pid, int *status, int options); 2007 UNIX Programming
synchronizing processes • Macros to examine the termination status 2007 UNIX Programming
synchronizing processes • ex) status #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> main(){ pid_t child_pid; int status; if ( (child_pid = fork()) < 0 ) exit(1); if (child_pid == 0) {sleep(4); exit(5);} if ( (child_pid = wait(&status)) == -1 ) exit(2); if (WIFEXITED(status)) printf(“%d child: Nomal termination, exit status = %d\n” , child_pid, WEXITSTATUS(status)); else if (WIFSIGNALED(status)) printf(“%d child: Abnomal Termination, signal number = %d\n” ,child_pid, WTERMSIG(status)); else if (WIFSTOPPED(status) printf(“%d child: stopped,signal number = %d\n” , child_pid, WSTOPSIG(status)); exit(0); } 2007 UNIX Programming
process attributes • Process-id • a non-negative number • unique number • getpid(): to get own process id • getppid(): to get parent process id • reserved PID • PID 0-sched, PID 1-init, PID 2-pageout • Process ownership • Real user id & group id for calling process • uid_t getuid() : to get real user id • uid_t getgid() : to get real group id • Effective user id & group id for calling process • uid_t geteuid(): to get effective user id • uid_t getegid(): to get effective group id 2007 UNIX Programming
0 : ok -1 : error process attributes • Change ownership #include <sys/types.h> #include <unistd.h> // for real user id and real group id int setuid (uid_t uid); Int setgid(gid_t gid); // for effective user id and group id int seteuid(uid_t uid); int setegid(gid_t gid); // for both real user id(group id) and effective user id(groupid) int setreuid(uid_t ruid, uid_t euid); // if don’t want to change, int setregid(gid_t rgid, gid_t egid); // ruid or egid = -1 2007 UNIX Programming
process attributes • A processhas three user ID that the kernel maintains • Real User ID(ruid) • Only superuser process can change ruid • Normally ruid is set login program (superuser process : using setuid) • Effective User ID (euid) • Set by the exec function only if the set-user-ID bit is set for the program file • If the set-user-ID is not set, the exec function leave the euid as its current value • By calling setuid, euid is set to ether the ruid or saved set-user-ID 2007 UNIX Programming
process attributes • Saved set-user-ID • Is copied from the euid by exec • This is saved after exec stores the euid from the file’s user id (if the file’s set_user_ID bit is set) • But, 4.3BSD is not supported 2007 UNIX Programming
process attributes • Example of setuid • Caber-toss game program • Game user에 의해서만 game의 점수 파일 접근 가능 -rwsr-xr-x 1 games games 184422 Jul 30 15:17 caber-toss -rw------- games games 1435 Jul 30 15:17 /tmp/score #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> /* euid와 ruid를 저장하라. */ static uid_t euid, ruid; /* 원래의 값으로 euid를 반환하라. */ void do_setuid() { int status; #ifdef _POSIX_SAVED_IDS status = setuid (euid); // [myid, games, games] #else status = setreuid (ruid, euid); // [myid, games] #endif if(status < 0){ fprintf (stderr,"Couldn't set uid.\n"); exit (status); }} 2007 UNIX Programming
process attributes • Example of setuid [real uid, effective uid, saved-set-uid] /* ruid로 euid를 설정하라. */ void undo_setuid(){ int status; #ifdef _POSIX_SAVED_IDS status = setuid (ruid); // [myid, myid, games] #else status = setreuid (euid, ruid); // [games, myid] #endif if(status < 0) { fprintf(stderr,"Couldn't set uid.\n"); exit(status);}} /* main 프로그램 */ int main(void){ /* ruid와 euid 들을 저장하라. */ ruid = getuid (); // [myid, games] euid = geteuid (); // [myid, games] undo_setuid(); /* 게임을 하고 점수를 기록하라. */ record_score(300); } 2007 UNIX Programming
process attributes • Example of setuid #define SCORES_FILE “/tmp/score” /* 점수를 기록하라. */ int record_score (int score){ FILE *stream; char *myname = “myname”; /* 점수파일을 개방하라. */ do_setuid (); // [myid, games] stream = fopen (SCORES_FILE, "a"); undo_setuid (); /* 파일에 그 점수를 기록하라. */ if(stream){ fprintf (stream, "%10s: %d feet.\n", myname, score); fclose (stream); return 0; } else return -1; } 2007 UNIX Programming
process attributes • Summary of all the functions that set the different usr IDs superuser setreuid(ruid, euid) superuser setuid(uid) superuser seteuid(uid) uid uid uid euid ruid uid unpriviliged setreuid real user ID effective user ID unpriviliged setreuid saved set-user-ID exec of set-user-ID unpriviliged setuid or seteuid unpriviliged setuid or seteuid 2007 UNIX Programming
process attributes • I want to know how much time has been taken by my process and/or my child process • Use command time • Use times() function in your program • times() functions • Returns : elapsed wall clock time in clock ticks if OK, -1 on error • Function sysconf(_SC_CLK_TCK) returns # of clock ticks per second #include <sys/times.h> clock_t times(struct tms *buf); 2007 UNIX Programming
process attributes • Parameters • struct tms *buf : 현재 process와 그것의 child process가 사용한 user CPU time, system CPU time 값을 가져올 구조체 • tms_utime: times()가 호출될때까지 process가 사용한 user CPU time (the time spent for user instructions) • tms_stime: times()가 호출될때까지 process가 사용한 system CPU time (the time spent for system calls) • tms_cutime: times()가 호출되기전에, 수행을 마친 child process들의 (tms_utime + tms_cutime) 값 • tms_cstime: times()가 호출되기전에, 수행을 마친 child process들의 (tms_stime + tms_cstime) 값 struct tms { clock_t tms_utime; /* user CPU time */ clock_t tms_stime; /* system CPU time */ clock_t tms_cutime; /* user CPU time, terminated child*/ clock_t tms_cstime; /* system CPU time, terminated child */ } 2007 UNIX Programming