[Unix Programming][Unix Programming]Process3Process3
Young-Ju, HanYoung-Ju, Han
Email: Email: [email protected]
2007 UNIX Programming2007 UNIX Programming 22
ContentsContents
inherited data and file descriptors synchronizing processes process attributes
Process id Process ownership Changing of Process ownership Process Time
2007 UNIX Programming2007 UNIX Programming 33
inherited data and file descriptorsinherited data and file descriptors
#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);} }
ex) pro_fileBefore fork : 10Child before read : 10Child after read : 20Parent after wait : 20
2007 UNIX Programming2007 UNIX Programming 44
inherited data and file descriptorsinherited data and file descriptors
#include <fcntl.h> main(){ int fd; . fd = open(“data”, O_RDONLY); . fcntl(fd, F_SETFD, 1);
execl(“/bin/ls”,”ls”, (char*) 0); . }
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
계속 유지
res = fcntl(fd, F_GETFD, 0);if res == 1 then on else off
2007 UNIX Programming2007 UNIX Programming 55
synchronizing processessynchronizing 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 Programming2007 UNIX Programming 66
synchronizing processessynchronizing 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);
PID of the exiting child-1 = no child exists (ECHILD)
WIFEXITED(status) = 1 : normally exit 0 : stopped by signalWEXITSTATUS(status) = value stored in the high-order bits of status
NULL : ignorevalid pointer : status info. when wait return
2007 UNIX Programming2007 UNIX Programming 77
synchronizing processessynchronizing 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);
child PID0 = if WNOHANG is setting and no use child
-1 = error
0 : no useWNOHANG : return 0 if the child has runningWUNTRACED : the status of any stopped child <sys/wait.h>
2007 UNIX Programming2007 UNIX Programming 88
synchronizing processessynchronizing processes
Macro Description
WIFEXITED(status) True if child is terminated normally (exit or _exit)
WEXITSTATUS(status) : to get exit status (high-order 8 bits)
WIFSIGNALED(status) True if child is terminated abnormally (by receipt of a signal)
WTERMSIG(status) : to fetch the signal number that caused the termination
WCOREDUMP(status) : true if a core file was generated
WIFSTOPPED(status) True if child is currently stopped,
WSTOPSIG(status) : to fetch the signal number that caused the stop
o Macros to examine the termination status
2007 UNIX Programming2007 UNIX Programming 99
synchronizing processessynchronizing 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 Programming2007 UNIX Programming 1010
process attributesprocess 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 Programming2007 UNIX Programming 1111
process attributesprocess attributes
Change ownership
#include <sys/types.h>#include <unistd.h>// for real user id and real group idint setuid (uid_t uid); Int setgid(gid_t gid);
// for effective user id and group idint 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
0 : ok-1 : error
2007 UNIX Programming2007 UNIX Programming 1212
process attributesprocess attributes
A process has 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 Programming2007 UNIX Programming 1313
process attributesprocess 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
ID
exec setuid(uid) seteuid(uid)
Set-user-id bit off
Set-user-id bit on superuserUnprivilege
d usersuperuer
Unprivileged user
ruid Unchanged UnchangedSet to uid
( 임의의 uid)Unchanged Unchanged Unchaged
euid UnchangedSet from user ID of program file
Set to uid
( 임의의 uid)
Set to uid
(ruid or saved-set-user-id 만 )
Set to uid
( 임의의 uid)
Set to uid
(ruid or saved-set-user-id 만 )
Saved
set-user-id
Copied by effective user
id
Copied from effective user id
Set to uid
( 임의의 uid)Unchanged unchanged unchagned
2007 UNIX Programming2007 UNIX Programming 1414
process attributesprocess 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 Programming2007 UNIX Programming 1515
process attributesprocess 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 Programming2007 UNIX Programming 1616
process attributesprocess 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 Programming2007 UNIX Programming 1717
process attributesprocess attributes
Summary of all the functions that set the different usr IDs
realuser ID
effectiveuser ID
savedset-user-ID
superusersetreuid(ruid, euid)
superusersetuid(uid)
superuserseteuid(uid)
exec ofset-user-ID
unpriviligedsetuid or seteuid unpriviliged
setuid or seteuid
unpriviligedsetreuid
unpriviligedsetreuid
ruideuid uid uid
uid
uid
2007 UNIX Programming2007 UNIX Programming 1818
process attributesprocess 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 Programming2007 UNIX Programming 1919
process attributesprocess 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 */
}
Top Related