리눅스 프로그래머를 위한 가이드
지금까지, 언급된 유용한 예제들은 메세지 큐를 조종하는 wrapper 함수들이였다. 그것들은 매우 유용하지만, 어떤 의미에서는 보다 더 깊은 공부와 실험을 보장하지는 못하고 있다. 이런 점을 개선하기 위해, IPC 메세지 큐를 조종하기 위한 msgtool, 상호작용 명령어 라인 유틸리티(interative command line utility)를 사용할 수 있다. 이것은 확실히 교육 강화를 위한 적당한 도구로서의 기능을 하지만, 표준 쉘 스크립트를 경유하여 메세지 큐 기능을 제공하는 것에 의해 실 세계의 과제에 직접 적용할 수는 없다.
msgtool s (type) "text"
메세지 조회하기 (Retrieving Messages)
msgtool r (type)
허가사항 바꾸기 (Changing the Permissions(mode))
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