11.  - - . , , . () , , , pipe: . , , , (. 13), - - : , - - . - kill, "" . . - , , , IPC: , . , , , , "", BSD. , , , ., , . 11.1  UNIX , - , - . -, - +-------------------------------------------------------+ | if ((pid = fork()) == 0) | | { | | /* - */ | | ptrace(0,0,0,0); | | exec(" "); | | } | | /* - */ | | for (;;) | | { | | wait((int *) 0); | | read( ) | | ptrace(cmd,pid,...); | | if ( ) | | break; | | } | +-------------------------------------------------------+ 11.1. 330 sdb, - ptrace, , . - , , - - . , 11.1, - . , - ptrace, - . - (exec) . , - a.out, - . exec , - , , - . exec, - , , - . , - - , - wait, - , ( , . 6.1), . - () , - . - , (wait), (read) - ptrace, -. ptrace: ptrace(cmd,pid,addr,data); cmd , , , , .., pid - - , addr - , , data - , - . ptrace - , pid , - , . , , , , cmd, addr data, -, " " . - - ( ), - () , "" . - . - , - , - . - (wait), , wait, - . 331 +------------------------------------------------------+ | int data[32]; | | main() | | { | | int i; | | for (i = 0; i < 32; i++) | | printf("data[%d] = %d\n@,i,data[i]); | | printf("ptrace data addr Ox%x\n",data); | | } | +------------------------------------------------------+ 11.2. trace ( ) , 11.2 11.3 - trace debug, . trace data ; . debug , trace, : addr, , ptrace , - trace. exec - - ( trace) SIGTRAP ( ), - +------------------------------------------------------------+ | #define TR_SETUP 0 | | #define TR_WRITE 5 | | #define TR_RESUME 7 | | int addr; | | | | main(argc,argv) | | int argc; | | char *argv[]; | | { | | int i,pid; | | | | sscanf(argv[1],"%x",&addr); | | | | if ((pid = fork() == 0) | | { | | ptrace(TR_SETUP,0,0,0); | | execl("trace","trace",0); | | exit(); | | } | | for (i = 0; i < 32, i++) | | { | | wait((int *) 0); | | /* i | | * pid , | | * addr */ | | if (ptrace(TR_WRITE,pid,addr,i) == -1) | | exit(); | | addr += sizeof(int); | | } | | /* */ | | ptrace(TR_RESUME,pid,1,0); | | } | +------------------------------------------------------------+ 11.3. debug ( ) 332 trace , debug. , debug, - , wait, "- ", wait. debug ptrace, - i trace , - addr, addr; trace addr data. - debug ptrace trace, data 0 31. - , sdb, , , ptrace. ptrace , . * , - , - : ptrace, - . , - - , . * - - -, . , , - : -- fork, - , , , . - exec, ptrace, , . * , ptrace, . , - - . * setuid-, - ( ptrace ) . , , setuid- "privatefile". - ptrace "/bin/sh", shell ( , - shell'), . exec setuid, , setuid- - . [Killian 84] , - (. 5). - "/proc"; , - "/proc". , - 333 . - (read) (write) . stat - , . , ptrace. -, , - - , ptrace. -, - , . , - ; . - setuid-, - , . 11.2 V  IPC (interprocess communication) V UNIX . , - , - - . , , . * , . * (key), - , . * "get", ; (flag). . IPC_PRIVATE - . IPC_CREAT , - , IPC_EXCL, , . - , , , - creat open. * - : = , , 100 , - , 1, , 1, 101, 201 .. , - : , - "get". , , - . . 1 - , 201, - , 301. , 201, , . , , . * , 334 , , , , "control" ( ), --- , , - . * , , , , ( , , - ..), . * "control", - , - . , , , , - . , ( ), - , ; - . , - , ( ). , - , , , - . , - , - , . , . , , , - . 11.2.1  : msgget, - ( ) , - , msgctl, , msgsnd, , msgrcv, . msgget: msgqid = msgget(key,flag); msgqid - , key flag - , "get". - (), , - msgqid . - , , - : * ; * ; * ; * , ; * , msgsnd, msgrcv msgctl. msgget , 335 , - . , - , - . - . msgsnd: msgsnd(msgqid,msg,count,flag); msgqid - , msgget, msg - , , count - - , flag - , . ( 11.4), - , , , - . , , (. 9.1), . , . - +------------------------------------------------------------+ | msgsnd /* */ | | : (1) | | (2) | | (3) | | (4) | | : | | { | | | | ; | | ( | | ) | | { | | ( ) | | ; | | ( , - | | ); | | } | | ; | | - | | ; | | : | | , | | , , , | | - | | ; | | , | | ; | | } | +------------------------------------------------------------+ 11.4. , - 336 , - ( - , , - ). , . - , , - . , ( IPC_NOWAIT), - . 11.5 , - , , - . , 11.6. msgget , - MSGKEY. 256 , , - , 1, - msgsnd . . , msgrcv - : count = msgrcv(id,msg,maxcount,type,flag); id - , msg - , - , maxcount - msg, type - , flag - , , - +------+ +->+------+ | | +------+ +------+ +------+ | | | | --+---->| +--->| +--->| | | | | | | +---+--+ +---+--+ +---+--+ | | | +------+ | | +----+ | | | | +-----------|------------------>+------+ | | | | | | | | | | +------+ | | | | | +------+ | | | | --+---->| | | | | | | +---+--+ | | | +------+ | | | | | - | | | +------+ | - | +-----------|------------------>+------+ | - | | | | | - | | | | | - | +------------------>+------+ | - | | | | - | +------+ | - | | - | | - | | - | | - | | - | +------+ +------+ 11.5. , . count . 337 ( 11.7), . , . , , - : , -, - , . - - , , - , . maxcount, - , . , , - ( flag MSG_NOERROR), , . +------------------------------------------------------------+ | #include | | #include | | #include | | | | #define MSGKEY 75 | | | | struct msgform { | | long mtype; | | char mtext[256]; | | }; | | | | main() | | { | | struct msgform msg; | | int msgid,pid,*pint; | | | | msgid = msgget(MSGKEY,0777); | | | | pid = getpid(); | | pint = (int *) msg.mtext; | | *pint = pid; /* | | * | | * */ | | msg.mtype = 1; | | | | msgsnd(msgid,&msg,sizeof(int),0); | | msgrcv(msgid,&msg,256,pid,0); /* | | * | | * */ | | printf(": pid %d\n", | | *pint); | | } | +------------------------------------------------------------+ 11.6. , - type . , , , 338 , - type, - . , , 3, 1 2, , -2, 1. , , - , flag - IPC_NOWAIT ( ). , 11.6 11.8. 11.8 (). , , , - ; () , . IPC _CREAT +------------------------------------------------------------+ | msgrcv /* */ | | : (1) | | (2) , | | | | (3) | | (4) | | (5) | | : | | { | | ; | | loop: | | ; | | /* , */ | | ( == 0) | | ; | | ( > 0) | | , | | ; | | /* < 0 */| | - | | , | | , -| | ; | | ( ) | | { | | -| | , , | | ; | | - | | ; | | ; | | ; | | } | | /* */ | | ( ) | | ; | | ( - | | ); | | loop; | | } | +------------------------------------------------------------+ 11.7. 339 msgget - 1 - -. , - - . - - , , . - , , - . , - . +------------------------------------------------------------+ | #include | | #include | | #include | | | | #define MSGKEY 75 | | struct msgform | | { | | long mtype; | | char mtext[256]; | | }msg; | | int msgid; | | | | main() | | { | | int i,pid,*pint; | | extern cleanup(); | | | | for (i = 0; i < 20; i++) | | signal(i,cleanup); | | msgid = msgget(MSGKEY,0777|IPC_CREAT); | | | | for (;;) | | { | | msgrcv(msgid,&msg,256,1,0); | | pint = (int *) msg.mtext; | | pid = *pint; | | printf(": pid %d\n",| | pid); | | msg.mtype = pid; | | *pint = getpid(); | | msgsnd(msgid,&msg,sizeof(int),0); | | } | | } | | | | cleanup() | | { | | msgctl(msgid,IPC_RMID,0);