main, ,
.
exec , path ,
( ),
( ),
(), - (
). .
- exec ( -
).
argv[0] path. , -
( ), .
/bin/ls lr, lf, lx, ll. -
, argv[0] .
envp - "" (. ).
- ( ,
environ); (, -
- -
) - . , -
char **environ, -
main (. ), getenv().
. , 1992-95 - 224 - UNIX
fork exec , fork
exec - ,
- : ,
/, ... " " . MS DOS,
, fork, exec wait spawn.
-
spawn, - .
6.5.4.
void exit( unsigned char retcode );
. : stack, data, text,
user ( ); , -
, .
- proc
. !
"" - .
retcode.
- (, fork). , 0
, 1..255
. :
- -
. exit(-1); -
; -1 255.
exit(errno);
exit, -
:
- main(), .. -
exit() , retcode;
- .
-, " ".
6.5.5. exit() - ,
. _exit(). -
exit() , :
void exit(unsigned code){
/* : */
printf(" , "
" =%u\n", code);
/* : */
_cleanup(); /* .
* |= */
_exit(code); /* */
}
int f(){ return 17; }
void main(){
printf("aaaa\n"); printf("bbbb\n"); f();
/* : exit(77); */
}
exit main,
. , exec-, -
"",
/lib/crt0.o. ( ):
... // argc, .
main(argc, argv, envp);
exit();
. , 1992-95 - 225 - UNIX
( GNU|-|-):
int errno = 0;
char **environ;
_start(int argc, int arga)
{
/* OS and Compiler dependent!!!! */
char **argv = (char **) &arga;
char **envp = environ = argv + argc + 1;
/* ... - ,
* setlocale( LC_ALL, "" ); SCO UNIX */
exit (main(argc, argv, envp));
}
int main(int argc, char *argv[], char *envp[]){
...
return 0; /* exit(0); */
}
_start() a.out
,
( ).
exit() (
exit return) - . IBM PC
17, , .
- , ( ,
).
6.5.6. - . -
wait : - .
,
- ,
. - -
! : "" ,
:
int pid; unsigned short status;
...
if((pid = fork()) == 0 ){
/* */
... // -.
... // .
exec(....);
perror("exec "); exit(1);
}
/* */
while((pid = wait(&status)) > 0 )
printf(" pid=%d %d\n",
pid, status >> 8);
printf( " \n");
____________________
|= _cleanup() , fopen(), "" , -
, . -
, , ( _exit). -
.
____________________
|-|- GNU - , Free Software Founda-
. , 1992-95 - 226 - UNIX
wait |-
( !).
- - wait (pid)
. "" - (-1). ,
, .
status ,
, .
#include <sys/types.h>
#include <sys/wait.h>
...
int status, pid;
...
while((pid = wait(&status)) > 0){
if( WIFEXITED(status)){
printf( " %d %d\n",
pid, WEXITSTATUS(status));
} else if( WIFSIGNALED(status)){
printf( " %d %d\n",
pid, WTERMSIG(status));
if(WCOREDUMP(status)) printf( " core\n" );
/* core - adb */
} else if( WIFSTOPPED(status)){
printf( " %d %d\n",
pid, WSTOPSIG(status));
} else if( WIFCONTINUED(status)){
printf( " %d \n",
pid);
}
}
...
, wait(NULL).
- wait
, (-1). while -
.
, - ,
. , -
"zombie" - " ". , -
.
- , wait
? 1: /etc/init.
-, 1 "" .
init , wait(),
____________________
tion (FSF). - C++ g++ emacs. GNU - "gen-
erally not UNIX" -
UNIX . " UNIX, ".
|- "" :
- (""), ,
.. ; -
( ); -
. -
( text) (
, ).
- (.. "" ). -
("" )
.
. , 1992-95 - 227 - UNIX
( , -
). init ,
.
, :
|pid=719,csh
|
if(!fork())------->--------* pid=723,csh
| |
wait(&status) exec("a.out",...) <-- a.out
: main(...){
: |
:pid=719,csh | pid=723,a.out
()
: |
: exit(status)
: }
<---!--RIP
|
|pid=719,csh
, -
, . ,
, fork.
6.5.7. , wait .
SIGSTOP, SIGTTIN, SIGTTOU,
SIGTSTP.
, SIGTSTP - CTRL/Z.
SIGCONT.
, , ,
. , -
- SIGCLD
. - wait
- .
:
void pchild(){
int pid, status;
sighold(SIGCLD);
while((pid = waitpid((pid_t) -1, &status, WNOHANG|WUNTRACED)) > 0){
dorecord:
___;
}
sigrelse(SIGCLD);
/* Reset */
signal(SIGCLD, pchild);
}
...
main(){
...
/* SIGCLD pchild */
signal(SIGCLD, pchild);
...
_;
}
waitpid ( wait),
sighold-sigrelse, SIGCLD .
. , 1992-95 - 228 - UNIX
:
dorecord:, , pchild
,
, , .
.
, pchild
, . sighold
( ), sigrelse - (
- . -
waitpid).
WNOHANG - " wait",
; (-1)".
pchild : . WUNTRACED -
" ".
6.5.8. , exec
( , fork exec dup2
, ).
, , ? (
, -
fd 0, 1 2;
). -, close
fork- exec-.
. :
for(f = 3; f < NOFILE; f++)
close(f);
. ,
, exec
( file-close-on-exec - fclex):
#include <fcntl.h>
int fd = open(.....);
fcntl (fd, F_SETFD, 1);
:
fcntl (fd, F_SETFD, 0);
: file - "
", (
: char u_pofile[NOFILE]). ,
:
... fcntl (fd, F_SETFD, 1); ... close(fd);
...
int fd1 = open( ... );
fd1 fd, fd1 exec- ,
! close(fd) fclex.
6.5.9. (short *u_ttyp). -
( fork exec) ,
.
(int p_pgrp),
. pgrp:
kill( -pgrp, sig );
kill( 0, sig );
sig ,
. , 1992-95 - 229 - UNIX
. :
int pgrp = getpgrp();
"" .
setpgrp();
:
/* . : */
if(p_pgrp != p_pid) u_ttyp = NULL;
/* -: */
p_pgrp = p_pid; /* new group */
, (t_pgrp). -
, :
/* */
if( p_pid == p_pgrp //
&& u_ttyp == NULL // ..
&& t_pgrp == 0 ){ //
u_ttyp = &t_pgrp;
t_pgrp = p_pgrp;
}
(
). (
) : t_pgrp=0;
:
c_cc[ VINTR ] DEL CTRL/C
c_cc[ VQUIT ] CTRL/\
SIGINT SIGQUIT
, ..
kill( -t_pgrp, sig );
DEL. ,
setpgrp(), (..
!= ).
(
setpgrp), ( ) -
. -, -
, , .
0, 1, 2 , -
( ).
- /etc/getty (
"get tty" - ) - 1 - /etc/init- -
, ,
- ;
- - (
).
getty :
void main(ac, av) char *av[];
{ int f; struct termio tmodes;
for(f=0; f < NOFILE; f++) close(f);
/* ,
* .
*/
setpgrp();
/* */
. , 1992-95 - 230 - UNIX
/* av[1] . */
open( av[1], O_RDONLY ); /* fd = 0 */
open( av[1], O_RDWR ); /* fd = 1 */
f = open( av[1], O_RDWR ); /* fd = 2 */
// ...
// /etc/gettydefs.
// , av[2].
// tmodes
// ... .
ioctl (f, TCSETA, &tmodes);
// ... ...
chdir (__);
execl ("/bin/csh", "-csh", NULL);
/* . ,
* . , 0,1,2 .
*/
}
open -
( -
) - 0,1,2 -. -
0,1,2 . init -
getty ,
/etc/getty /dev/tty01 m &
/etc/getty /dev/tty02 m &
...
. -
, getty (pid
). - - init getty -
( - , - -
).
6.6. FIFO-.
.
- FIFO- (first in, first out), -
. .
- -
, - . ""
read ( ) , - FIFO-
- . - lseek() - -
FIFO-. FIFO-
#include <sys/types.h>
#include <sys/stat.h>
mknod( ߔ, S_IFIFO | 0666, 0 );
0666 - . FIFO- -
.
FIFO- FIFO-,
- -. -
"" pipe. pipe:
int conn[2]; pipe(conn);
- PIPEFILE, pipe
. , 1992-95 - 231 - UNIX
mknod("PIPEFILE", S_IFIFO | 0600, 0);
conn[0] = open("PIPEFILE", O_RDONLY);
conn[1] = open("PIPEFILE", O_WRONLY);
unlink("PIPEFILE");
fork :
pipe(conn);
fork();
conn[0]----<---- ----<-----conn[1]
FIFO
conn[1]---->---- ---->-----conn[0]
A B
A B. A :
close(conn[0]);
// ..
write(conn[1], ... );
B
close(conn[1]);
// ..
read (conn[0], ... );
:
conn[1]---->----FIFO---->-----conn[0]
A B
, A
conn[1]
dup2 (conn[1], 1); close(conn[1]);
write(1, ... ); /* printf */
B - conn[0]
dup2(conn[0], 0); close(conn[0]);
read(0, ... ); /* gets */
$ A | B
.
, pipe, (
). - , -
write, .
, -
. A B, B
wait, conn[0]. A conn[1].
, :
A , B ,
A;
B - A ,
.
B wait ,
( EOF). close(conn[0]);
. , 1992-95 - 232 - UNIX
B wait.
B close(conn[0]) , A
, write A, A
SIGPIPE - " , ".
6.6.1. FIFO (""),
FIFO . open ,
- .
, , , -
, - ?
O_NDELAY open.
int fd = open(filename, O_RDONLY|O_NDELAY);
open ,
(-1). -
>=0, .
O_NDELAY , .
, , ,
. () ,
(
open ). , -
, , "" open,
close . -
O_NDELAY.
#include <stdio.h>
#include <fcntl.h>
/* O_NDELAY */
void nondelay(int fd){
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY);
}
int main(int ac, char *av[]){
int fd;
char *port = ac > 1 ? "/dev/term/a" : "/dev/cua/a";
retry: if((fd = open(port, O_RDWR|O_NDELAY)) < 0){
perror(port);
sleep(10);
goto retry;
}
printf(" %s .\n", port);
nondelay(fd);
printf(" , !\n");
sleep(60);
printf(".\n");
return 0;
}
:
. , 1992-95 - 233 - UNIX
su# a.out & a.out xxx
[1] 22202
/dev/term/a .
, !
/dev/cua/a: Device busy
/dev/cua/a: Device busy
/dev/cua/a: Device busy
/dev/cua/a: Device busy
/dev/cua/a: Device busy
/dev/cua/a: Device busy
.
/dev/cua/a .
, !
su#
6.7. .
. setjmp
" "|-, longjmp
, (
)|=. ,
- , ,
. , ,
:
#include <signal.h>
#include <setjmp.h>
jmp_buf jmp; /* */
/* */
void onintr(nsig){ longjmp(jmp, nsig); }
main(){
int n;
n = setjmp(jmp); /* */
if( n ) printf( " %d\n", n);
signal (SIGINT, onintr); /* */
printf("\n");
...
}
setjmp 0 .
longjmp, setjmp, -
longjmp, - nsig.
(backtracking): - - , -
- -
. :
( jmp_buf
- ).
____________________
|- :
(stack pointer); ,
(instruction pointer).
|= . , -
setjmp longjmp (..
).
. , 1992-95 - 234 - UNIX
6.7.1. longjmp.
#define FOUND 1 /* */
#define NOTFOUND 0 /* */
int value; /* */
main(){ int i;
for(i=2; i < 10; i++){
printf( " i=%d\n", i);
if( test1(i) == FOUND ){
printf(" %d\n", value); break;
}
}
}
test1(i){ int j;
for(j=1; j < 10 ; j++ ){
printf( " j=%d\n", j);
if( test2(i,j) == FOUND ) return FOUND;
/* "" return */
}
return NOTFOUND;
}
test2(i, j){
printf( "(%d,%d)\n", i, j);
if( i * j == 21 ){
printf( " (%d,%d)\n", i,j);
value = j; return FOUND;
}
return NOTFOUND;
}
, return-:
#include <setjmp.h>
jmp_buf jmp;
main(){ int i;
if( i = setjmp(jmp)) /* */
printf(" %d\n", --i);
else /* */
for(i=2; i < 10; i++)
printf( " i=%d\n", i), test1(i);
}
test1(i){ int j;
for(j=1; j < 10 ; j++ )
printf( " j=%d\n", j), test2(i,j);
}
test2(i, j){
printf( "(%d,%d)\n", i, j);
if( i * j == 21 ){
printf( " (%d,%d)\n", i,j);
longjmp(jmp, j + 1);
}
}
, longjmp
1, . j==0,
setjmp 0 ( -
).
6.7.2. ?
#include <setjmp.h>
. , 1992-95 - 235 - UNIX
jmp_buf jmp;
main(){
g();
longjmp(jmp,1);
}
g(){ printf(" g\n");
f();
printf(" g\n");
}
f(){
static n;
printf( " f\n");
setjmp(jmp);
printf( " f %d- \n", ++n);
}
: longjmp f(), -
.
"" - "".
"" , . :
, , . -
f() main() - , main() ,
f(). .. ""
: f() main() g(); g() main();
-- --
| f |
| g |
| main | -
----------
: main() g() f(); g() f().
:
f(){ ...
A: setjmp(jmp);
...
longjmp(jmp, ...); ...
/* goto A; */
}
6.8. , , .
UNIX - . ,
, , (
). ,
/etc/init.
6.8.1. - , -
. UNIX :
(user id), : , -
.
/etc/passwd. , -
, passwd:
. , 1992-95 - 236 - UNIX
#include <stdio.h>
#include <pwd.h>
struct passwd *p;
int uid; /* */
char *uname; /* . */
uid = getuid();
p = getpwuid( uid );
...
p = getpwnam( uname );
, -
. :
p->pw_uid . (int uid);
p->pw_gid . ;
char[]
p->pw_name (uname);
p->pw_dir
(, );
p->pw_shell
( "", /bin/sh);
p->pw_comment ( );
p->pw_gecos ( );
p->pw_passwd
. !
p==NULL, (-
, uid). uid
getuid, uid - st_uid , -
stat ( - st_gid). :
ls,
.
6.8.2.
chown(char *ߔ, int uid, int gid);
.. "" . .
S_ISUID S_ISGID (. ) ,
" " , ,
- !
6.8.3. ( di_uid I-
i_uid I- |-).
( u_uid u_ruid u-area). , , -
. ruid " " , uid -
" ". exec() ,
:
____________________
|- , -
I- ( , ).
I- ,