αӸѰ̵
http://www.tldp.org/LDP/lpg/lpg.html
Contents
1 ü (The Linux operating system) ¶1991 3 Linus Benedict Torvalds ڽ AT 386 ǻͿ Ƽ½ŷ ý Minix ߴ. ״ װ ȰϿ θ ڽŸ Ƽ½ŷ ý Ͽ. 1991 9 ״ ͳ Minix ڵ鿡 E- ù° Ÿ(Prototype) ǥߴ. ̰ Ʈ ̴. αӵ ϱ ߴ. ̽ ̹ ߰ϰ, α ϰ POSIX ǥ ߴ. ó ſ ū ¥(FREE) ̴. ٸ ÷ ̽ϴ ۾ ̴.
2 Ŀ (The Linux Kernel) ¶ ⺻ Ŀ̴. ̺귯 ٲ, Ŀ ִ ̴. Ŀ ̽ ̹, , μ Ѵ. Ŀ Ŀ α Ե ưԵ POSIX ̵ . α ο Ŀ ٸ Ѵٸ, ȭ ο POSIX ̵ Ǿ Ȯ ũ. Ŀο α Ѵٸ, Ŀ Ŀ ̵(The Linux Kernel Hacker's Guide) о.
3 libc Ű (The Linux libc Package) ¶libc: ISO 8859.1, , YP Լ, crypt Լ, ⺻ Shadow ƾ (⺻δ Ե ), ... libcompat ִ ȣȯ ƾ (⺻ ),,Ҿ Ǵ , libcourses ִ bsd 4.4 lite ȣȯ ִ ȭ ڵ鸵 ƾ, libbsd ִ bsd ȣȯǴ ƾ, libtermcap ִ ȭ ڵ鸵 ƾ, libdbm ִ Ÿ̽ ƾ, libm ִ а ƾ, crt0.o??? ִ α , libieee??? ִ Ʈ sex (콺 ??? ּ.), libgmon ִ ϸ(Profiling). libc ڵ ֱ⸦ ٶϴ. ִ ִ a.out ̺귯 ȭ ǹϴ elf(executable and linkable format) ٲ ̶ ͻ̴. (a.out elf) ȴ.
crt0.o Ư ۱ ޱ , libc Ű κ ̺귯 GNU Public ̼(License) ´. ũ ִ. ũ Ư ̰ FSF Richard Stallman Ʒ ߴ.
Section 5 ۵ ƹ Ʈ Ǵ ̺귯 ÷ ʴ ũ Ǿ Ѵٰ . װ ϵ ̴. LGPL Ȯ ٷ߸ ̴.
4 ý ȣ (System Calls) ¶ý ȣ Ϲ ü(Ŀ) ϵ/ýۿ Ǵ Ư ־ ϴ ۵ ûϴ ̴. 1.2 140 ý ȣ ǵǾ ִ. close() ý ȣ libc Ǿ ִ. ᱹ syscall() ȣϴ ũ ȣ Ѵ. syscall() Ѱ Ķʹ ʿ ƱԸƮ Ǵ ý ȣ ȣ̴. ý ȣ ȣ <sys/syscall.h> ο libc ƮǴ <linux/unistd.h> ã ִ. libc ٰ ʴ ο ȣ Ÿ ʴ syscall() ִ. , Ʒ syscall() Ͽ ִ.( ) :
#include <syscall.h> extern int syscall(int, ...); int my_close(int filedescriptor) { return syscall(SYS_close, filedescriptor); } i386 ϵ ý ȣ ȣ̿ܿ 5 ƱԸƮ ý ȣ ѵȴ. ٸ Ѵٸ _syscall ũθ ϵ ƱԸƮ ϴ Ǵ Ǵ ˾ <asm/unistd.h> üũ ִ. ̷ _syscall ũε syscall() ſ , ̷ ũδ ̺귯 ̹ ҷ Full Function ȮǹǷ õҸ ϴ.
#include <linux/unistd.h> _syscall1(int, close, int, filedescriptor); _syscall1 ũδ close() Լ Ȯȴ. Ƿ libc ȿ close() ,ι α ȿ ѹ . ý ȣ ϸ syscall() ̳ _syscall ũ ȯ -1̰ ϸ 0 ̳ 0 ū ´. ý ȣ ߴٸ Ͼ ˱ errno .
BSD SYS V ִ ý ȣ . :
audit(),auditon(),auditsvc(),fchroot(),getauid(),getdents(),getmsg(),mincore(), poll(),putmsg(),setaudit(),setauid().
5 " Į" ioctl (The "swiss army knife" ioctl) ¶ioctl input/output control ǹϸ ϵũ(filedescriptor) ij ̽(character device) ϴµ ȴ. ioctl ´ ioctl(unsigned int fd, unsigned intrequest, unsigned long argument)̴.
ȯ -1̰ ٸ ý ȣ û ϸ 0 ũų ´. Ŀ Ư (special file)̳ Ϲ ϵ(regular files) еȴ. Ư (special file) ַ /dev /proc 丮 ã ִ. ϵ ̹ ̽ ְ ؽƮ Ÿ ϴ (Ϲ) ƴ϶ Ϲ (regular file) ٸ. ̷ н ö̰ Ͽ б/ Ѵ. Ư ̳ Ϲ ̻ ϰ Ѵٸ ioctl ִ. Ϲ Ϻٴ Ư Ͽ ioctl ʿ Ϲ Ͽ ؼ ioctl ϴ.
6.1 Ұ (Introduction) ¶ IPC(Inter-process communication) μ ٸ μ ִ Ѵ. C αӵ ̿ ִ IPC Ʒ ִ.
6.2.1 ⺻ (Basic Concepts) ¶ ؼ, (Pipe) μ ǥ (Standard output) ٸ μ ǥ Է(Standard input) ϴ ̴. IPC н ü ʱ ܰ Ǿ Դ. μ ܹ(,half-duplex) Ѵ.
̷ Ư¡ н ɾ (н ) а ȴ.
ls | sort | lp
ls sort Է ϰ sort lp Է ϱ (pipe) ̿Ͽ. ڷ ʿ ̵ϵ, δ.
츮 ũƮ αֿ ϰ Ѵص, Ŀ Ͼ Ͽ ؼ ʰ Ѵ.
μ , Ŀ ΰ ĺ(descriptor) غѴ. Ѱ ĺ(descriptor) (Write) Է η ǰ ٸ ϳ (Read) ڷḦ µ ȴ. ̷ ϴ μ ڱڽŰ ſ ʴ´. μ Ŀ ۿ뿡 ϶.
- ּϰԵ ̾
̾ ĺڵ Ǵ ִ. μ (fd0) ڷḦ ٸ, fd1 ڷḦ ( ) ִ ɷ ִ. 繰 ſ ũ. ó μ ڽ ϴ , ڷ Ŀ δ. Ư ȿ inode ǹѴ. , inode Ŀξȿ ϰ ýۿ ƹ ġ ʴ´. ̷ Ư¡ 츮 I/O (handy I/O doors) ְ Ѵ.
̷ . ᱹ, 츮 츮 ڽſ ̾߱ϰ Ѵٸ ߸ ϴ°? ϴ(creating) μ ڽ μ(child process) (fork)Ѵ. ڽ μ θ ĺڵ ӹǷ 츮 θ ڽİ Ƽμ ʸ ִ. 츮 ϶.
츮 μ ϴ ĺڿ ִ. ̹ ߿ Ѵ. ڷᰡ ̵ϱ⸦ ϴ°? ڽ μ θ ΰ ƴϸ ݴΰ? μ ̷ ȣ ϰ ְ Ǿ ݴ´. , ڽ μ ۾ ϰ θ ϴ 캸. 츮 Ӱ ȵ Ÿ.:
Ϻϴ! ִ ̴. ϱ , I/O Ǵ ý ȣ ִ. ( ȿ inode ǥ ϶)
ڷḦ , 츮 write() ý ȣ ϰ ڷḦ ȸϱ read() ý ȣ Ѵ. I/O ý ȣ ĺڸ ۾ ϶! ·, ĺڸ ۾ ʴ lseek() ý ȣ ϶.
6.2.2 C (Creating Pipes in C) ¶C α ٴ Ѵ. C pipe() ý ȣ Ѵ. ̰ 迭 Ѱ ƱԸƮ(argument) , ϸ 迭 Ǵ ο ΰ ĺڸ ´. , μ ο μ ´. (ڽ ĺڸ ӹ´ٴ ϶)
SYSTEM CALL: pipe();
PROTOTYPE: int pipe(int fd[2]);
RETURNS: 0
-1 on error: errno = EMFILE (ο ĺڰ )
EMFILE (ý ̺ á)
EFAULT (fd 迭 ȿ ʴ)
NOTES: fd[0] б⸦ غǰ, fd[1] ⸦ غȴ.
迭 ù° (element 0) б⸦ غǰ ݸ, ι° (element 1) ⸦ غǰ . ð ϸ, fd1 fd0 Է ȴ. ̵ϴ ڷ Ŀ ̵ ٽ صд.
#include <stdio.h> #include <unistd.h> #include <sys/types.h> main() { int fd[2]; pipe(fd); . . } C 迭 ̸ ù° ϶. , fd &fd[0] . , ο ڽ μ (fork)Ѵ.:
#include <stdio.h> #include <unistd.h> #include <sys/types.h> main() { int fd[2]; pipe(fd); if((childpid = fork()) == -1) { perror("fork"); exit(1); } . . } θ ڽ ڷḦ ȸϱ⸦ Ѵٸ, fd1 ݾƾ ϰ ڽ fd0 ݾƾ Ѵ. θ ڽĿ ڷḦ Ѵٸ, fd0 ݾƾ ϰ ڽ fd1 ݾƾ Ѵ. θ ڽİ ĺڸ ϰ Ƿ, ϰ ʴ ߸ Ѵ. ǻ ʿ ϰ EOF ƿ ʴ´ٴ ̴.
#include <stdio.h> #include <unistd.h> #include <sys/types.h> main() { int^Ifd[2]; pid_t^Ichildpid; pipe(fd); if((childpid = fork()) == -1) { perror("fork"); exit(1); } if(childpid == 0) { /*ÀÚ½Ä ÇÁ·Î¼¼½º´Â ÆÄÀÌÇÁÀÇ ÀÔ·Â ÂÊÀ» ´Ý´Â´Ù*/ close(fd[0]); } else { /*ºÎ¸ð ÇÁ·Î¼¼½º´Â ÆÄÀÌÇÁÀÇ Ãâ·Â ÂÊÀ» ´Ý´Â´Ù*/ close(fd[1]); } . . } տ ߴ ó, Ŀ ĺڴ Ϲ ĺó ȴ.
/***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: pipe.c *****************************************************************************/ #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main(void) { int fd[2], nbytes; pid_t childpid; char string[] = "Hello, world!\n"; char readbuffer[80]; pipe(fd); if((childpid = fork()) == -1) { perror("fork"); exit(1); } if(childpid == 0) { ^I^I/*ÀÚ½Ä ÇÁ·Î¼¼½º´Â ÆÄÀÌÇÁÀÇ ÀÔ·Â ÂÊÀ» ´Ý´Â´Ù*/ close(fd[0]); ^I^I/*ÆÄÀÌÇÁÀÇ Ãâ·Â ÂÊÀ¸·Î "string"À» º¸³½´Ù*/ write(fd[1], string, strlen(string)); exit(0); } else { ^I^I/*ºÎ¸ð ÇÁ·Î¼¼½º´Â ÆÄÀÌÇÁÀÇ Ãâ·Â ÂÊÀ» ´Ý´Â´Ù*/ close(fd[1]); ^I^I/*ÆÄÀÌÇÁ·Î ºÎÅÍ ¹®ÀÚ¿À» Àд´Ù*/ nbytes = read(fd[0], readbuffer, sizeof(readbuffer)); printf("Received string: %s", readbuffer); } return(0); } ڽ ĺڴ ǥ Է Ǵ ° øȴ. ڽ ǥ stream ϴ ٸ α exec() ִ. dup() ý ȣ 캸.:
SYSTEM CALL: dup();
PROTOTYPE: int dup( int oldfd );
RETURNS: ο ĺ
-1 on error: errno = EBADF (oldfd ȿ ĺڰ ƴϴ)
EBADF (newfd )
EMFILE (μ ĺڰ ʹ )
NOTES: ĺڴ ʴ´. ΰ ȣ ȯǾ ִ.
ĺڿ ĺڰ ȣ ȯǾ ִ, ǥ stream ݴ´. dup() ý ȣ ο ĺڿ ȣ οѴ.
ؼ :
. . childpid = fork(); if(childpid == 0) { ^I^I/*ÀÚ½ÄÀÇ Ç¥ÁØ ÀÔ·ÂÀ» ´Ý´Â´Ù*/ close(0); ^I^I/*ÆÄÀÌÇÁÀÇ ÀÔ·Â ÂÊÀ» Ç¥ÁØÀÔ·ÂÀ¸·Î ÇÑ´Ù*/ dup(fd[0]); execlp("sort", "sort", NULL); . } ĺ 0 , dup() ȣϿ Է ĺ(fd0) ǥ Է Ѵ. (sort) α ڽ ؽƮ Ʈ(text segment) øŰ execlp() ȣ Ѵ. Ӱ exec α θ ǥ stream ӹǷ, Է ǥ Էó ӹ´. θ μ sort ȴ.
dup2() ٸ ý ȣ ִ. ̷ Ư ȣ н 7 ۵Ǿ, BSD Ǹ POSIX ǥؿ ʿϴ.
SYSTEM CALL: dup2();
PROTOTYPE: int dup2( int oldfd, int newfd );
RETURNS: ĺ
-1 on error: errno = EBADF (oldfd ȿ ĺڰ ƴϴ)
EBADF (newfd )
EMFILE (μ ĺڰ ʹ )
NOTES: ĺڴ dup2() !
̷ Ư ȣ Ͽ Ѱ ý ȣ Ǿ ִ close ۾ ĺ ۾ Ѵ. Դٰ, ۾ ȭ(atomic) Ǵµ ̴ ⺻ ȣ ۾ ߴܵ ǹѴ. ü ȣ Ŀο ֱ Ͼ. αӴ ȣϱ dup() ý ȣ close() ۾ ؾ߸ Ѵ. װ ̿ Ǵ ð 翡 ټ ΰ ý ȣ . ª ̿ ȣ Ѵٸ, ú Ѵ. , dup2() ̷ ذߴ.
캸:
. . childpid = fork(); if(childpid == 0) { /* Close stdin, duplicate the input side of pipe to stdin */ dup2(0, fd[0]); execlp("sort", "sort", NULL); . . } 6.2.3 ! (pipes the Easy Way!) ¶ μ ۵ ϴ ſ ó ٸ, ٸ ִ.
LIBRARY FUNCTION: popen();
PROTOTYPE: FILE *popen ( char *command, char *type);
RETURNS: ο Ʈ(stream)
fork(),pipe()ȣ (NULL)
NOTES: ɾ("command") Ͽ fork/exec Ѵ.
ǥ ̺귯 Լ pipe() ȣϿ . ڽ μ (fork)ϰ, (Bourne ahell) execϰ "command" ƱԸƮ Ѵ. ڷ 帧 ι° ƹ¸Ʈ "type" ȴ. "read"̳ "write" "r"̳ "w" ִ. ΰ . , "type" ù° ڿ . , "rw" ѱٸ б("read") .
̺귯 Լ ٷο ϴ , ߿ (tradeoff) Ͼ. pipe() ý ȣ ϰ fork/exec ϴ Ϳ Ҿ. ǹǷ, "command" ƱԸƮ ϵ ī(wildcard) Ÿ Ȯ(shell metacharacter expansion) ϴ.
popen() pclose() ݾƾ߸ Ѵ. popen/pclose ǥ Ʈ I/O Լ fopen(),fclose() ſ ϴٴ ˾ ̴.
LIBRARY FUNCTION: pclose();
PROTOTYPE: int pclose( FILE *stream );
RETURNS: wait4() ȣ Ż (exit status)
-1 Ʈ("stream") ȿ ʰų wait4()
NOTES: μ DZ⸦ ٷȴٰ Ʈ ݴ´.
pclose() Լ popen() (fork) μ wait4() Ѵ. wait4()κ ȯ , Ʈ ıѴ. Ϲ Ʈ I/O fclose() Լ Ǿ ִ.
sortɾ ڿ 迭 óϴ 캸:
/***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¥¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: popen1.c *****************************************************************************/ #include <stdio.h> #define MAXSTRS 5 int main(void) { int cntr; FILE *pipe_fp; char *strings[MAXSTRS] = { "echo", "bravo", "alpha", "charlie", "delta"}; ^I/*popen() È£ÃâÀ» »ç¿ëÇÏ¿© ´Ü¹æÇâ ÆÄÀÌÇÁ¸¦ ¸¸µç´Ù*/ if (( pipe_fp = popen("sort", "w")) == NULL) { perror("popen"); exit(1); } ^I/*¹Ýº¹ ó¸®*/ for(cntr=0; cntr<MAXSTRS; cntr++) { fputs(strings[cntr], pipe_fp); fputc('\n', pipe_fp); } ^I/*ÆÄÀÌÇÁ¸¦ ´Ý´Â´Ù*/ pclose(pipe_fp); return(0); } popen() ڽ ϴµ , Ȯ ڵ Ÿ ϴ. ٳ redirection popen() ִ. ȣ 캸:
popen("ls ~scottb", "r"); popen("sort > /tmp/foo", "w"); popen("sort | uniq | more", "w"); popen() ٸ , ΰ (ϳ ls, ٸ ϳ sort) α 캸:
/***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¥¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: popen2.c *****************************************************************************/ #include <stdio.h> int main(void) { FILE *pipein_fp, *pipeout_fp; char readbuf[80]; ^I/*popen() È£ÃâÀ» »ç¿ëÇÏ¿© ´Ü¹æÇâ ÆÄÀÌÇÁ¸¦ ¸¸µç´Ù*/ if (( pipein_fp = popen("ls", "r")) == NULL) { perror("popen"); exit(1); } ^I/*popen() È£ÃâÀ» »ç¿ëÇÏ¿© ´Ü¹æÇâ ÆÄÀÌÇÁ¸¦ ¸¸µç´Ù*/ if (( pipeout_fp = popen("sort", "w")) == NULL) { perror("popen"); exit(1); } ^I/*¹Ýº¹ ó¸®*/ while(fgets(readbuf, 80, pipein_fp)) fputs(readbuf, pipeout_fp); ^I/*ÆÄÀÌÇÁ¸¦ ´Ý´Â´Ù*/ pclose(pipein_fp); pclose(pipeout_fp); return(0); } popen() , Ѱܹ ɾ ϸ Ϲ α ۼ :
/***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: popen3.c *****************************************************************************/ #include <stdio.h> int main(int argc, char *argv[]) { FILE *pipe_fp, *infile; char readbuf[80]; if( argc != 3) { fprintf(stderr, "USAGE: popen3 [command] [filename]\n"); exit(1); } ^I/*ÀÔ·Â ÆÄÀÏÀ» ¿¬´Ù*/ if (( infile = fopen(argv[2], "rt")) == NULL) { perror("fopen"); exit(1); } ^I/*popen() È£ÃâÀ» »ç¿ëÇÏ¿© ´Ü¹æÇâ ÆÄÀÌÇÁ¸¦ ¸¸µç´Ù*/ if (( pipe_fp = popen(argv[1], "w")) == NULL) { perror("popen"); exit(1); } ^I/*¹Ýº¹ ó¸®*/ do { fgets(readbuf, 80, infile); if(feof(infile)) break; fputs(readbuf, pipe_fp); } while(!feof(infile)); fclose(infile); pclose(pipe_fp); return(0); } α Ѻ:
popen3 sort popen3.c
popen3 cat popen3.c
popen3 more popen3.c
popen3 cat popen3.c | grep main
6.2.4 Atomic (Atomic Operations with Pipes) ¶ȭ(Atomic) Ǿ ϴ ۵ ϴµ ظ Ƽ ʵȴ. ü ѹ Ͼ. POSIX ǥ /usr/include/posix1_lim.h Ͽ (Atomic) ִ ũ⸦ ϰ ִ.:
#define _POSIX_PIPE_BUF 512
ڵ 512Ʈ ų ִ. ̿ ɰ ̸, ȭ(Atomic) ʴ´. ȭ(Atomic)Ǵ Ѱ "linux/limits.h" Ͽ ǵǾ ִ.:
#define PIPE_BUF 4096
ٽ, POSIX ʿ ϴ ּ Ʈ Ѵ. ȭ(Atomicity) Ѱ ̻ μ(FIFOS) Ե ߿ϰ ȴ. Ʈ Ѱ Ѱ(Atomic Limit) ʰϰų μ ִ , ڷ ̿ ־ų(interleaved) ̴(chunked). ٲ ϸ, μ ⸦ ϴ ٸ μ ο ڷḦ ִٴ ̴.
6.2.5 (Note on half-duplex pipes) ¶
6.3.1 ⺻ (Basic Concepts) ¶̸ ֺ Ϲ ۾, ָҸ ִ.
6.3.2 FIFO (Creating a FIFO) ¶̸ (named pipe) ִ. ó ΰ ̴.
mknod MYFIFO p mkfifo a=rw MYFIFO ɾ ѱ ܸ ϰ Ѵ. mkfifo ɾ FIFO Ͽ 㰡(permission)
ٱ Ѵ. mknod chmod ɾ ȣ ʿ ̴.
FIFO 丮 Ʈ(long directory listing) "p" ڿ ýۿ 绡 ˷.
$ ls -l MYFIFO
prw-r--r-- 1 root root 0 Dec 14 22:15 MYFIFO|
ϸ ִ ("pipe sign") ָ϶.
C FIFO , mknod() ý ȣ ִ.:
LIBRARY FUNCTION: mknod();
PROTOTYPE: int mknod( char *pathname, mode_t mode, dev_t dev);
RETURNS: 0 on success,
-1 on error: errno = EFAULT (pathname invalid)
EACCES (permission denied)
ENAMETOOLONG (pathname too long)
ENOENT (invalid pathname)
ENOTDIR (invalid pathname)
(see man page for mknod for others)
NOTES: Creates a filesystem node (file, device file, or FIFO)
man mknod() ڼ , C FIFO 캸.:
mknod("/tmp/MYFIFO", S_IFIFO|0666, 0);
, "/tmp/MYFIFO" FIFO ó . ó umask ´ ϴ û 㰡(permission) "0666"̴.:
final_umask = requested_permissions & ~original_umask
Ϲ Ͻ umask ϱ umask() ý ȣ ϴ ̴.:
umask(0); mknod("/tmp/MYFIFO", S_IFIFO|0666, 0); Դٰ, ̽ ʴٸ mknod() ° ƱԸƮ õȴ. ̷ 쿡 ̽ ūʰ ȣ ־߸ Ѵ.
6.3.3 FIFO (FIFO Operations) ¶FIFO I/O Ѱ ֿ ϰ Ϲ . "open" ý ȣ̳ ̺귯 Լ ä µ Ǿ Ѵ. ý ƴ, Ŀο ʿϴ. 츮 fopen() , fclose() ݴ Ʈ(stream)ó ٷ ̴.
μ 캸:
/***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: fifoserver.c *****************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <linux/stat.h> #define FIFO_FILE "MYFIFO" int main(void) { FILE *fp; char readbuf[80]; ^I/*ÆÄÀÌÇÁ°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é ¸¸µç´Ù*/ umask(0); mknod(FIFO_FILE, S_IFIFO|0666, 0); while(1) { fp = fopen(FIFO_FILE, "r"); fgets(readbuf, 80, fp); printf("Received string: %s\n", readbuf); fclose(fp); } return(0); } Ʈ FIFO ܵ, Ŀ server Ѷ:
$ fifoserver& FIFO ۿ ϰڴ. , Ŭ̾Ʈ ȯ(frontend) 캸:
/***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: fifoclient.c *****************************************************************************/ #include <stdio.h> #include <stdlib.h> #define FIFO_FILE "MYFIFO" int main(int argc, char *argv[]) { FILE *fp; if ( argc != 2 ) { printf("USAGE: fifoclient [string]\n"); exit(1); } if((fp = fopen(FIFO_FILE, "w")) == NULL) { perror("fopen"); exit(1); } fputs(argv[1], fp); fclose(fp); return(0); } 6.3.4 FIFO (Blocking Actions on a FIFO) ¶Ϲ FIFO Ѵ. ٲپ ϸ, FIFO б⸦ ִٸ, μ ٸ μ ⸦ (block)ų ̴. ̷ ݴε ȴ. ̷ ۵ ʴ´ٸ, Ʈ ʵ open() ȣÿ O_NONBLOCK ÷ ִ.
, о, ű⼭ ܵ ä ܵд. ٸ ٸ ַܼ پ Ŭ̾Ʈ Ű ,ڷ ȯŰ ̴.
6.3.5 ˷ SIGPIPE ȣ (The Infamous SIGPIPE Signal) ¶ , б ⸦ ִ. μ бⰡ ȵǴ Ѵٸ, Ŀη SIGPIPE ȣ ް ȴ. ̰ ΰ ̻ μ ο ԵǾ ʼ̴.
6.4.1 ⺻ (Fundamental Concepts) ¶ý V AT&T IPC ο ( ť(message queue), (semaphores), (shared memory)) Ұߴ. POSIX ȸ ǥȭ ġ ϰ , κ ̵ ϰ ִ. ٳ Ŭ(BSD) ý V Һٴ IPC · Ѵ. 忡 Ͽ ϰ, IPC ΰ (BSD System V) ִ.
ý V IPC Krishna balasubramanian(balasub@cis.ohio-state.edu) Ǿ.
6.4.1.1 IPC Ȯ (IPC Identifiers) ¶ IPC ü(Object) װͰ IPC Ȯ(Identifier) ´. "IPC ü(object)" ť(single message queue), (semaphore set), Ǵ Ʈ(shared memory segment) Ѵ. IPC ü Ȯڴ Ŀ ȿ ȴ. , Ư Ʈ ϱ Ʈ Ҵ ID ʿϴ.
Ȯ ϼ ü Ÿ(type) ִ. ̸ ϱ , "12345" ġ Ȯڸ . Ȯڸ ΰ ť Ƿ, ġ Ȯڸ Ʈ ť ִ ɼ Ѵ.
6.4.1.2 IPC Ű (IPC Keys) ¶ ID , Ű(key) Ǿ Ѵ. Ű(key) Ŭ̾Ʈ μ ǵǾ Ѵ. ̰ α Ŭ̾Ʈ/ ü ϴ ù° ܰ踦 ǹѴ.
ȭ ϰ ȭȣ ˰ ־ Ѵ. Դٰ ȭ ȸ ſԼ ȭ ߰ ˰ ־ Ѵ. ݴ ȭ ؾ ̷ .
ý V IPC , ȭ Ǵ ü Ÿ ִ. ȭ ȸ糪 (routing method) IPC Ű(key) Ǿ .
Ű α Ű ϵڵν ִ. ̰ Ű ̹ ִٴ ִ. ftok() Լ Ŭ̾Ʈ ο Ű Űµ ȴ.
LIBRARY FUNCTION: ftok();
PROTOTYPE: key_t ftok ( char *pathname, char proj );
RETURNS: new IPC key value if successful
-1 if unsuccessful, errno set to return of stat() call
ftok() ȯ Ű ù° ƱԸƮ Ϸ inode ȣ, minor ġȣ ι° ƱԸƮ ѱ Ʈ Ȯ տ Ѵ. ̰ ϼ , α 浹 üũϿ Ű ٽ ų ִ.
key_t mykey; mykey = ftok("/tmp/myapp",'a'); , 丮 "/tmp/myapp" 'a' ѱڿ յȴ. ٸ Ϲ 丮 ϴ ̴.
key_t mykey; mykey = ftok(".",'a'); Ǵ Ű ˰ α α ִ. (deadlocks), ִ , ̵ Ÿ ִ. ftok() 뿡 ִ. Ŭ̾Ʈ μ Ȩ 丮 ̶ Ѵٸ, Ǵ Ű 츮 ʿ並 Ѿ Ѵ.
Ű IPC ü ϱ Ϸ IPC ý ȣ ȴ.
6.4.1.3 ipcs ɾ (The ipcs Command) ¶ipcs ɾ ý V IPC ü ¸ µ ִ. Krishna Balasubramanian ۵Ǿ.
ipcs -q: ť(message queues) ش. ipcs -s: (semaphore) ش. ipcs -m: (shared memory) ش ipcs --help: ΰ ƱԸƮ(arguments) Ʈ ü . ipcs 캸:
--- Shared Memory Segments --- shmid owner perms bytes nattch status --- Semaphore Arrays --- semid owner perms nsems status --- Message Queues --- msqid owner perms used-bytes messages 0 root 660 5 1 ⼭ 츮 "0"̶ Ȯ(Identifier) ť(single message queue) ִ. װ root ̰, 660(-rw-rw--) 8 㰡 ִ. ť Ѱ ְ, ũ 5Ʈ̴.
ipcs ɾ IPC ü Ŀ ִ ̴.
6.4.1.4 ipcrm ɾ (The ipcrm Command) ¶ipcrm ɾ Ŀη IPC ü ϴµ ȴ. IPC ü ڵ峻 ý ȣ Ͽ ŵ , Ư ȯϿ IPC ü ؾ ʿ䰡 Ѵ. ϴ.:
ipcrm <msg | sem | shm> <IPC ID> ü ť(msg) (sem) (shm) Ѵ. IPC ID ipcs ɾ ִ. Ȯڴ ŸԾȿ ü Ÿ ־߸ Ѵ. ( ϶)
6.4.2.1 ⺻ (Basic Concepts) ¶ ť Ŀ ּ Ű (kernel's addressing space) (Internal linked list)̶ ִ. ʴ ť ٸ ť ȸȴ. () ť IPC Ȯ(identifier) ϰ Ȯεȴ.
6.4.2.2 ο ڷ (Internal and User Data Structures) ¶ý V IPC ϱ Ŀ ȿ ϴ پ ڷ ģ ̴. ܰ ϰ ִ , ̷ ⺻ ۿ ʿϴ.
(Message buffer)
ó msgbuf ̴. Ư ڷ ڷḦ ø(template) ִ. αӰ ̷ Ÿ Ͽ ʴ , msgbuf Ÿ ϴ ʼ̴. linux/msg.h Ǿ ִ.:
/* message buffer for msgsnd and msgrcv calls */ /* msgsnd¿Í msgrcv È£ÃâÀ» À§ÇÑ ¸Þ¼¼Áö ¹öÆÛ */ struct msgbuf { long mtype; /* type of message ¸Þ¼¼Áö ŸÀÔ */ char mtext[1]; /* message text ¸Þ¼¼Áö ³»¿ë */ }; msgbuf ΰ ִ.:
mtype
ǥǴ Ÿ. ݵ Ѵ.
mtext
ڷ ü.
־ Ÿ οϴ ɷ ť (multiplex) ɷ οѴ. , Ŭ̾Ʈ μ ȣ (magic number) Ҵ ְ ̰ μ 鿡 Ÿó ִ. ü ٸ ȣ ְ, Ŭ̾Ʈ ȣ ִ. ٸ ó α Ÿ '1' û (request message) Ÿ '2' ǥ ִ. ̷ ɼ .
ٸ 밳 ڷ (mtext) ſ ̸ οϿ Ȥ ʵ ϴ ̴. ʵ ڵ 迭̿ ʿ . ڷ̵ . α αӿ ǵ Ƿ, ʵ üε ̴.
struct my_msgbuf { long mtype; /* Message type ¸Þ¼¼Áö ŸÀÔ */ long request_id; /* Request identifier ¿äû È®ÀÎÀÚ */ struct client info; /* Client information structure Ŭ¶óÀÌ¾ðÆ® Á¤º¸ ±¸Á¶ */ }; Ÿ , ΰ ٸ ҷ ٲ. ϳ ٸ ü(structure)̴! ̰ ť ̴. Ŀ ڷᰡ ̵ ڷ ȯ Ű ʴ´. ִ.
־ ִ ũ . linux/msg.h ǵǾ ִ.:
#define^IMSGMAX^I4056^I/* <= 4056 */^I/* max size if message (bytes) ¸Þ¼¼ÁöÀÇ ÃÖ´ë Å©±â */
̰ 4Ʈ(long) mtype Ͽ ũ 4,056Ʈ Ŭ .
Ŀ msg (Kernel msg structure)
Ŀ msg ü ťȿ Ѵ. ̰ linux/msg.h ǵǾ ִ.
/* °¢ ¸Þ¼¼Áö¿¡ ´ëÇÑ ÇѰ³ÀÇ ¸Þ¼¼Áö ±¸Á¶Ã¼ */ struct msg { struct^Imsg *msg_next;^I/* Å¥¿¡¼ÀÇ ´ÙÀ½ ¸Þ¼¼Áö */ long msg_type; char *msg_spot; /* ¸Þ¼¼Áö ³»¿ë ÁÖ¼Ò */ short msg_ts; /* ¸Þ¼¼Áö ³»¿ë Å©±â */ }; msg_next
̰ ťȿ ̴. ̰ Ŀ ּҸŰ (kernel addressing space)ȿ ٷ (singly linked list)ó Ǿ ִ.
msg_type
̰ ü msgbuf Ҵ Ÿ̴.
msg_spot
ü Ű
msg_ts
Ǵ ü
Ŀ msqid ds (Kernel msqid ds structure)
IPC ü Ÿ Ŀο Ǵ ڷ . ť msq_id ̴. Ŀ ý Ǵ ť ̷ ϳ ϰ Ѵ. linux/msg.h ǵǾ ִ.:
/* ½Ã½ºÅÛ»ó¿¡¼ °¢ Å¥¿¡ ´ëÇÑ msqid ±¸Á¶ */ struct msqid_ds { struct ipc_perm msg_perm; struct msg *msg_first; /* first message on queue Å¥ÀÇ Ã³À½ ¸Þ¼¼Áö*/ struct msg *msg_last; /* last message in queue Å¥ÀÇ ¸¶Áö¸· ¸Þ¼¼Áö*/ time_t msg_stime; /* last msgsnd time ¸¶Áö¸·À¸·Î msgsnd°¡ ¼öÇàµÈ ½Ã°£*/ time_t msg_rtime; /* last msgrcv time ¸¶Áö¸·À¸·Î msgrcv°¡ ¼öÇàµÈ ½Ã°£*/ time_t msg_ctime; /* last change time ¸¶Áö¸·À¸·Î change°¡ ¼öÇàµÈ ½Ã°£*/ struct wait_queue *wwait; struct wait_queue *rwait; ushort msg_cbytes; ushort msg_qnum; ushort msg_qbytes; /* max number of bytes on queue Å¥ÀÇ ÃÖ´ë ¹ÙÀÌÆ® ¼ö*/ ushort msg_lspid; /* pid of last msgsnd ¸¶Áö¸·À¸·Î msgsnd¸¦ ¼öÇàÇÑ pid*/ ushort msg_lrpid; /* last receive pid ¸¶Áö¸·À¸·Î ¹ÞÀº pid*/ }; ü κ 鿡 , 츮 ϼŰ ϰڴ.
msg_perm
ipc_perm ü ϳ linux/ipc.h ǵǾ ִ. ̰ 㰡(access permissions) ť (creator) (uid, etc) ϴ ť 㰡 ִ.
msg_first
ť ù° Ǿ ִ.(the head of the list)
msg_last
ť Ǿ ִ.(the tail of the list)
msg_stime
ť ð (Timestamp)
msg_rtime
ť ȸ ð (Timestamp)
msg_ctime
ť Ͼ ȭ(change) ð (Timestamp) (more on this later)
wwait
and
rwait
Ŀ ť(wait queue) Ű . ť ִ μ sleep · ȴ. (i.e. ť μ (opening) ٸ ִ )
msg_qnum
ť ִ
msg_qbytes
ť ִ Ʈ
msg_lspid
μ PID
msg_lrpid
ȸ μ PID
Ŀ ipc perm (Kernel ipc perm structure)
Ŀ ipc_perm Ÿ ü ȿ IPC ü 㰡(permission) Ѵ. , տ ť msg_perm ̷ Ÿ̴. linux/ipc.h ȿ Ǿ ִ.:
struct ipc_perm { key_t key; ushort uid; /* owner euid and egid */ ushort gid; ushort cuid; /* creator euid and egid */ ushort cgid; ushort mode; /* access modes see mode flags below */ ushort seq; /* slot usage sequence number */ }; ڱ ؼ̴. ü IPC Ű Ǿ ִ ü (creator) (owner) ̴. (creator owner ٸ ) 8 (the octal access mode) usigned short· Ǿ ִ. slot usage sequence ȣ Ǿ ִ. Ź IPC ü ý ȣ (destroyed) Ͽ . ý ȿ ִ IPC ü ִ ȴ. 츮 ϴ°? ƴϴ.
NOTE:Richard Stevens UNIX Network Programming 125ʿ ڼ ̰ Ǿ ִ.
6.4.2.3 ý ȣ:msgget() (SYSTEM CALL:msgget()) ¶ο ť Ͽ Ǵ ϴ ť ϱ Ͽ, msgget() ý ȣ ȴ.
SYSTEM CALL: msgget();
PROTOTYPE: int msgget ( key_t key, int msgflg );
RETURNS: ť Ȯ(message queue identifier)
-1 on error: errno = EACCESS (ٱ )
EEXIST (ť ̹ Ͽ )
EIDRM (ť ǥð Ǿ )
ENOENT (ť )
ENOMEM (ť )
ENOSPC (ִ ť ʰ)
NOTES:
msgget() ù° ƱԸƮ Ű̴.(ftok() ȣϿ Ѱܹ ) Ű Ŀξȿ ִ ٸ ť鿡 Ű ϴ Ѵ. ̶, (open) (access) msgflg ƱԸƮ 뿡 .
IPC_CREAT
Ŀξȿ ϴ Ȯ ť .
IPC_EXCL
IPC_CREAT , ť ̹ ϸ óѴ.
IPC_CREAT ȥ Ǹ, msgget() Ӱ ť ť Ȯ (the message queue identifier) ȯϰų, Ű ̹ ϴ ť Ȯڸ ȯѴ. IPC_EXCL IPC_CREAT Բ Ǹ, ο ť ų ť ϸ -1 ȣ Ѵ. IPC_EXCL üδ , IPC_CREAT Բ յǾ ϱ ʴ ť (open) ϴµ ִ.
IPC ü н ýۻ 㰡 ɰ 㰡 Ƿ, ΰ 8 ũ ȿ OR ̴!
ť ų wrapper Լ :
int open_queue(key_t keyval) { int qid; if((qid = msgget( keyval, IPC_CREAT | 0660 )) == -1) { return(-1); } return(qid); } 0660 㰡(permission) ָ϶. Լ ť Ȯ (int) ȯϰų -1 ȯѴ. Ű ƱԸƮ Ѱ߸ Ѵ.
6.4.2.4 ý ȣ:msgsnd() (SYSTEM CALL:msgsnd()) ¶ť Ȯڸ , ť ִ. ť ϱ msgsnd ý ȣ Ѵ.:
SYSTEM CALL: msgsnd();
PROTOTYPE: int msgsnd ( int msqid, struct msgbuf *msgp, int msgsz, int msgflg );
RETURNS: 0 on success
-1 on error: errno = EAGAIN (queue is full, and IPC_NOWAIT was asserted)
EACCES (permission denied, no write permission)
EFAULT (msgp address isn't accessable - invalid)
EIDRM (The message queue has been removed)
EINTR (Received a signal while waiting to write)
EINVAL (Invalid message queue identifier, nonpositive
message type, or invalid message size)
ENOMEM (Not enough memory to copy message buffer)
NOTES:
msgsnd ù° ƱԸƮ msgget ȣ ȯ ť Ȯ̴. ι° ƱԸƮ msgp 缱ǰ ̴. msgsz ƱԸƮ Ÿ (4Ʈ) Ʈ ũ⸦ Ѵ.
msgflg ƱԸƮ 0 ִ.(ignored), or:
IPC_NOWAIT
ť á, ť , (control) ȣ μ ư. ʾ, ȣ μ ٸ ̴.
ٸ wrapper Լ :
int send_message( int qid, struct mymsgbuf *qbuf ) { int result, length; /* ±æÀÌ´Â ±âº»ÀûÀ¸·Î ±¸Á¶Ã¼ÀÇ Å©±â - mtypeÀÇ Å©±â ÀÌ´Ù. */ length = sizeof(struct mymsgbuf) - sizeof(long); if((result = msgsnd( qid, qbuf, length, 0)) == -1) { return(-1); } return(result); } Լ Ѱ ť Ȯ(qid) ȵ ť Ѱ ּ(qbuf) ִ Ѵ. 츮 ݱ ΰ wrapper Լ Ȱ ڵ尡 ִ.:
#include <stdio.h> #include <stdlib.h> #include <linux/ipc.h> #include <linux/msg.h> main() { int qid; key_t msgkey; struct mymsgbuf { long mtype; /* ¸Þ¼¼Áö ŸÀÔ */ int request; /* ÀÛ¾÷ ¿äû ¹øÈ£ */ double salary; /* Á÷¿øÀÇ ±Þ¿© */ } msg; /* IPC Ű °ªÀ» ¹ß»ý½ÃŲ´Ù */ if(( qid = open_queue( mdgkey)) == -1) { perror("open_queue"); exit(1); } /* ÀÓÀÇÀÇ Å×½ºÆ® ÀڷḦ ¸Þ¼¼Áö¿¡ ÀûÀçÇÑ´Ù */ msg.mtype = 1; /* ¸Þ¼¼Áö ŸÀÔÀº ¾ç¼ö¿©¾ß ÇÑ´Ù */ msg.request = 1; /* ÀÚ·á ¿ä¼Ò #1 */ msg.salary = 1000.00; /* ÀÚ·á ¿ä¼Ò #2 (³ªÀÇ ¿¬°£ ±Þ¿©) */ /* »½ ³¯·Áº¸³½´Ù */ if((send_message( qid, &msg )) == -1) { perror("send_message"); exit(1); } } ť Ŀ, ۿ Ʈ ڷḦ ϴµ ߴ. ( Ϳ 츮 ϱ ڷᰡ ָ϶) send_message ȣ ܼ ť йѴ.
츮 ť , ť ¸ ipcs ɾ ض. ť ȸϱ п . ϱ msgrcv() ý ȣ Ѵ.:
SYSTEM CALL: msgrcv();
PROTOTYPE: int msgrcv ( int msqid, struct msgbuf *msgp, int msgsz, long mtype, int msgflg );
RETURNS: Number of bytes copied into message buffer
-1 on error: errno = E2BIG (Message length is greater than msgsz, no MSG_NOERROR)
EACCES (No read permission)
EFAULT (Address pointed to by msgp is invalid)
EIDRM (Queue was removed during retrieval)
EINTR (Interrupted by arriving signal)
EINVAL (msgqid invalid, or msgsz less than 0)
ENOMSG (IPC_NOWAIT asserted, and no message exists
in the queue to satisfy the request)
NOTES:
ϰ, ù° ƱԸƮ ȸ ó ϴ ť ϴµ ȴ. ( msgget ȣϿ ȯ ̿ ) ι° ƱԸƮ(msgp) ȸ ּҸ Ÿ. ° ƱԸƮ(msgsz) mtype ̸ ü ũ⸦ Ÿ. ٽ ѹ ó ִ.:
msgsz = sizeof(struct mymsgbif) - sizeof(long);
° ƱԸƮ(mtype) ť ȸ Ÿ Ѵ. Ŀ Ÿ ĪǴ ť ã ̰ msgp ƱԸƮ ּҿ װ Ͽ ȯ ̴. Ѱ Ư 찡 Ѵ. mtype ƱԸƮ 0 Ѿ, Ÿ ϰ ť ȯѴ.
IPC_NOWAIT flagó Ѱ ̿밡 , ȣ μ ENOMSG ȯѴ. , ȣ μ msgrcv() ĸ Ű ť ٸ. Ŭ̾Ʈ ٸ ִ ť , EIDRM ȯȴ. μ ¿ ְų ϱ⸦ ٸ ȣ , EINTR ȯȴ.
ť ȸϴ wrapper Լ .:
int read_message( int qid, long type, struct mymsgbuf *qbuf ) { int result, length; /* Å©±â´Â ±âº»ÀûÀ¸·Î ±¸Á¶Ã¼ÀÇ Å©±â - mtypeÀÇ Å©±â ÀÌ´Ù. */ length = sizeof(struct mymsgbuf) - sizeof(long); if((result = msgrcv( qid, qbuf, length, type, 0)) == -1) { return(-1); } return(result); } ť ȸ ̷, ť ȿ ִ ıȴ.
msgflg ƱԸƮ MSG_NOERROR Ʈ ΰ ɷ Ѵ. ڷ ũⰡ msgsz ũ MSG_NOERROR Ǹ, ߷ msgsz Ʈŭ ȯȴ. Ϲ msgrcv() ý ȣ -1(E2BIG) ȯϰ ȸ ť ´. ̷ 츮 û ϴ ߴ ˾ƺ 츮 ť (peek) ִ ٸ wrapper Լ ִ.
int peek_message( int qid, long type ) { int result, length; if((result = msgrcv( qid, NULL, 0, type, IPC_NOWAIT)) == -1) { if(errno == E2BIG) return(TRUE); } return(FALSE); } ּҿ ̰ ̴. ̷ Ư 쿡 ־, 츮 ȣ ϱ⸦ Ѵ. 츮 츮 û Ÿ ġǴ ϴ Ÿ E2BIG ȯ ȮѴ. wrapper Լ ϸ TRUE, FALSE ȯѴ. ߴ (Blocking behavior) IPC_NOWAIT flag 뿡 ָ϶.
6.4.2.5 ý ȣ:msgctl() (SYSTEM CALL:msgctl()) ¶ wrapper Լ Ǿ, α ť , Ȱϱ ϰ ٹ ִ. ־ ť ü ϱ п .
ť ϱ , msgctl() ý ȣ Ѵ.
SYSTEM CALL: msgctl();
PROTOTYPE: int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
RETURNS: 0 on success
-1 on error: errno = EACCES (No read permission and cmd is IPC_STAT)
EFAULT (Address pointed to by buf is invalid with IPC_SET and
IPC_STAT commands)
EIDRM (Queue was removed during retrieval)
EINVAL (msgqid invalid, or msgsz less than 0)
EPERM (IPC_SET or IPC_RMID command was issued, but
calling process does not have write (alter)
access to the queue)
NOTES:
Ŀ ڷ ʵ ̸ ִ. ེԵ, αӵ Ϻο ӹ ⵿ IPC subsystem Ѵٸ ̷ зǾ ִ. õ ɾ msgctl() Ͽ, 糭 ų ɼ ִ ɷ ´.
IPC_STAT
ť msqid_ds ü ȸϿ ƱԸƮ ּ Ѵ.
IPC_SET
ť msqid_ds ü ipc_perm Ѵ. ƱԸƮ Ѵ.
IPC_RMID
Ŀη ť Ѵ.
ť ڷ (msqid_ds) ߴ . Ŀ ýۿ ϴ ť ̷ ü ϳ ִ. IPC_STAT ɾ Ͽ ˻縦 ü 纻 ȸ ִ. ȸϿ Ѱ ּҷ ϴ wrapper Լ 캸.:
int get_queue_ds( int qid, struct msgqid_ds *qbuf ) { if( msgctl( qid, IPC_STAT, qbuf) == -1) { return(-1); } return(0); } ۷ ٸ ȣ Լ -1 ȯȴ. Ǹ, 0 ȯǰ Ѱ ۴ Ѱܹ ť Ȯ(queue identifier,qid) ǥǴ ť ڷ 纻 ´.
ť ڷ ü 纻 , Ư ְ, װ͵ ų ִ°? ڷ ȿ ִ ipc_perm ̴. ̰ (owner) (creator) , ť 㰡 Ѵ. ִ ipc_perm ü mode,uid,gid ̴. (owner) user id, (owner) group id, ť 㰡(access permission) ٲ ִ.
ť (mode) ٲٵ ȵ wrapper Լ . (mode) 迭 Ѱ Ѵ (i.e. "660").
int change_queue_mode( int qid, char *mode ) { struct msqid_ds tmpbuf; /* ³»ºÎ ÀÚ·á ±¸Á¶ÀÇ ÇöÀç º¹»çº»À» Á¶È¸ÇÑ´Ù */ get_queue_ds( qid, &tmpbuf); /* ¿¾³¯ÀÇ ±â±³¸¦ »ç¿ëÇÏ¿© Çã°¡»çÇ×(permission)À» ¼öÁ¤ÇÑ´Ù */ sscanf(mode, "%ho", &tmpbuf.msg_perm.mode); /* ³»ºÎ ÀÚ·á ±¸Á¶¸¦ ¼öÁ¤ÇÑ´Ù */ if( msgctl( qid, IPC_SET, &tmpbuf) == -1) { return(-1); } return(0); } get_queue_ds wrapper Լ ȣϿ ڷ 纻 ȸѴ. msg_perm mode ϱ sscanf() ȣѴ. 纻 Ʈϱ ƹ ȭ Ͼ ʴ´. ̷ IPC_SET ɾ Ͽ msgctl() ȣϿ ִ.
! ť 㰡 ְ, ؼ Ǿƴϰ θ ܽų ִ. ϶, ̷ IPC ü ϰų ý ʴ´. ipcs ť ٰ Ͽ ʴ´ٴ ǹ ʴ´.
ϱ , ټ ִ ȭ Ұϰڴ. South Florida п н θ ġ , Ȳ (Blocking) ߴ. 㿡 ϰ ھ Ʈϰ ϱ ߴ. Ʈ ϴ ȿ ڵȿ ť 㰡(permission) ϴ Ÿ ٴ Ҵ. ť , ƹ ְ ִ Ʈ ߴ. , ť 带 "660" "600" Ϸ , ڽ ť ڽ ƹ ʷߴ. ҽ 丮 ť ۾ Ʈ . IPC Ű ftok() Լ ߱, ť Ϸ 㰡(permission) ߴ. ִ ħ ᱹ ý ڿ ť װ ipcrm ɾ Ѿ ϴ ѽð ϰ ´.
ťκ , ŵȴ. տ ߴ ó, IPC ü ŵǰų ý ʴ ýۿ ִ´. Ƿ, 츮 ť Ŀξȿ ϰ Ŀ ִ. ť ֱ(life cycle) ϼϱ IPC_RMID ɾ Ͽ msgctl() ȣ ŵǾ Ѵ.:
int remove_queue( int qid ) { if( msgctl( qid, IPC_RMID, 0) == -1) { return(-1); } return(0); } wrapper Լ ť ŵǸ 0 ȯϰ ƴϸ -1 ȯѴ. ť Ŵ ڿ atomicϰ ť Ϸ ٵ ̴.
6.4.2.6 msgtool:ȣۿ ť (An interactive message queue manipulator) ¶ ̿ ִ Ȯ Ҽ ٴ . ҵ ο Ž ⱳ(mechanism) Ѵ. ƶ, Ǽ μ ϰ ȭų ̴.
ݱ, ť ϴ wrapper Լ̿. װ͵ ſ , ǹ̿ ο ϰ ִ. ̷ ϱ , IPC ť ϱ msgtool, ȣۿ ɾ ƿƼ(interative command line utility) ִ. ̰ Ȯ ȭ μ , ǥ ũƮ Ͽ ť ϴ Ϳ .
(Background)
msgtool α ɾ ƱԸƮ ȴ. ̰ ũƮ ȣǾ , ſ ϰ ̴. ť ȸϰ ť 㰡 ٲٰ ϴ ɷ ȴ. , µ Ǵ Ÿδ 迭 Ѵ. ΰ ڷ Ÿ ϰ ٲٴ ڵ ִ.
ɾ (Command Line Syntax)
(Sending Messages)
msgtool s (type) "text" ȸϱ (Retrieving Messages)
msgtool r (type) 㰡 ٲٱ (Changing the Permissions(mode))
msgtool m (mode) ť (Deleting a Queue)
msgtool d (Examples)
msgtool s 1 test msgtool s 5 test msgtool s 1 "This is a test" msgtool r 1 msgtool d msgtool m 660 ҽ (The Source)
msgtool ҽ ڵ̴. ý V IPC ϴ ֽ Ŀ ǿ ϵǾ Ѵ. ۼ(rebuild) Ŀο ý V IPC ִ Ȯ϶.
, ƿƼ ûǵ ť ť ̴.
NOTE: IPC Ű Ű ftok()Լ , 丮 浹 . ũƮ 丮 ٲ۴ٸ, Ƹ ̴. ٸ ذå msgtoolȿ "/tmp/msgtool/" (path) ϵڵϰų ۻ(operational) ƱԸƮ , ɾ λ Ѱ (path) ϴ ̴.
/***************************************************************************** ¸®´ª½º ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ °¡À̵å - 6Àå ¿¡¼ ¹ßÃé (C)opyright 1994-1995, Scott Burkett ***************************************************************************** MODULE: msgtool.c ***************************************************************************** ½Ã½ºÅÛ V ½ºÅ¸ÀÏÀÇ ¸Þ¼¼Áö Å¥¸¦ »ç¿ëÇϱâ À§ÇÑ ¸í·É¾î ¶óÀÎ Åø *****************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_SEND_SIZE 80 struct mymsgbuf { long mtype; char mtext[MAX_SEND_SIZE]; }; void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text); void read_message(int qid, struct mymsgbuf *qbuf, long type); void remove_queue(int qid); void change_queue_mode(int qid, char *mode); void usage(void); int main(int argc, char *argv[]) { key_t key; int msgqueue_id; struct mymsgbuf qbuf; if(argc == 1) usage(); ^I/* ftok() È£ÃâÀ» ÅëÇØ À¯ÀÏÇÑ Å°¸¦ ¸¸µç´Ù */ key = ftok(".", 'm'); ^I/* ÇÊ¿äÇÏ´Ù¸é Å¥¸¦ ¸¸µé°í ¿¬´Ù */ if((msgqueue_id = msgget(key, IPC_CREAT|0660)) == -1) { perror("msgget"); exit(1); } switch(tolower(argv[1][0])) { case 's': send_message(msgqueue_id, (struct mymsgbuf *)&qbuf, atol(argv[2]), argv[3]); break; case 'r': read_message(msgqueue_id, &qbuf, atol(argv[2])); break; case 'd': remove_queue(msgqueue_id); break; case 'm': change_queue_mode(msgqueue_id, argv[2]); break; default: usage(); } return(0); } void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text) { ^I/* Å¥¿¡ ¸Þ¼¼Áö¸¦ º¸³½´Ù */ printf("Sending a message ...\n"); qbuf->mtype = type; strcpy(qbuf->mtext, text); if((msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext)+1, 0)) ==-1) { perror("msgsnd"); exit(1); } } void read_message(int qid, struct mymsgbuf *qbuf, long type) { ^I/* Å¥·Î ºÎÅÍ ¸Þ¼¼Áö¸¦ Àд´Ù. */ printf("Reading a message ...\n"); qbuf->mtype = type; msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0); printf("Type: %ld Text: %s\n", qbuf->mtype, qbuf->mtext); } void remove_queue(int qid) { ^I/* Å¥¸¦ Áö¿î´Ù */ msgctl(qid, IPC_RMID, 0); } void change_queue_mode(int qid, char *mode) { struct msqid_ds myqueue_ds; ^I/* ÇöÀç Á¤º¸¸¦ Àд´٠*/ msgctl(qid, IPC_STAT, &myqueue_ds); ^I/* ¸ðµå¸¦ Àоî¿Í ¹Ù²Û´Ù */ sscanf(mode, "%ho", &myqueue_ds.msg_perm.mode); ^I/* ¸ðµå¸¦ ¼öÁ¤ÇÑ´Ù */ msgctl(qid, IPC_SET, &myqueue_ds); } void usage(void) { fprintf(stderr, "msgtool - A utility for tinkering with msg queues\n"); fprintf(stderr, "\nUSAGE: msgtool (s)end \n"); fprintf(stderr, " (r)ecv \n"); fprintf(stderr, " (d)elete\n"); fprintf(stderr, " (m)ode \n"); exit(1); } It's seems that this document is rather too old... Ex) poll() system call has been supported in Linux for long time.
|
Even the boldest zebra fears the hungry lion. |









![[http]](/imgs/http.png)