지금까지, 언급된 유용한 예제들은 메세지 큐를 조종하는 wrapper 함수들이였다. 그것들은 매우 유용하지만, 어떤 의미에서는 보다 더 깊은 공부와 실험을 보장하지는 못하고 있다. 이런 점을 개선하기 위해, IPC 메세지 큐를 조종하기 위한 msgtool, 상호작용 명령어 라인 유틸리티(interative command line utility)를 사용할 수 있다. 이것은 확실히 교육 강화를 위한 적당한 도구로서의 기능을 하지만, 표준 쉘 스크립트를 경유하여 메세지 큐 기능을 제공하는 것에 의해 실 세계의 과제에 직접 적용할 수는 없다.
msgtool s (type) "text"
msgtool r (type)
msgtool m (mode)
msgtool d
msgtool s 1 test msgtool s 5 test msgtool s 1 "This is a test" msgtool r 1 msgtool d msgtool m 660
한편으로, 이 유틸리티는 어떤 동작이 요청되든지에 상관없이 메세지 큐가 존재하지 않으면 메세지 큐를 만들 것이다.
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(); /* ftok() 호출을 통해 유일한 키를 만든다 */ key = ftok(".", 'm'); /* 필요하다면 큐를 만들고 연다 */ 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) { /* 큐에 메세지를 보낸다 */ 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) { /* 큐로 부터 메세지를 읽는다. */ 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) { /* 큐를 지운다 */ msgctl(qid, IPC_RMID, 0); } void change_queue_mode(int qid, char *mode) { struct msqid_ds myqueue_ds; /* 현재 정보를 읽는다 */ msgctl(qid, IPC_STAT, &myqueue_ds); /* 모드를 읽어와 바꾼다 */ sscanf(mode, "%ho", &myqueue_ds.msg_perm.mode); /* 모드를 수정한다 */ 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); }
Copyright (c) 1996,1997 by Euibeom.Hwang & SangEun.Oh All Rights Reserved
Email To:Webmaster ,
Another address
LAST UPDATE Nov 21,1997
Created Nov 21,1997