다음 위로 이전 목차 리눅스 프로그래머를 위한 가이드

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();

	/* 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);
}


이전:시스템 호출:msgctl() 다음:6.4.3 세마퍼 (Semaphores)

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