next up previous contents
Next: Semafory Up: msgtool: Interaktywny manipulator kolejką Previous: Przykłady   Contents

Źródło

msgtool

Następujący kod źródłowy to msgtool. Powinien skompilować się bez problemu na nowszych ( przyzwoitych ) wersjach jądra, które wspierają System V IPC. Pamiętaj o włączeniu IPC Systemu V podczas rekompilacji jądra!

Program utowrzy kolejkę wiadomości jeżeli jeszcze nie istnieje, bez względu na rodzaj żądanego działania.

UWAGA: Ponieważ narzędzie to używa funkcji ftok() do wygenerowania klucza IPC możesz zaobserwować konflikty katalogów. Jeżeli gdziekolwiek w swoim skrypcie zmienisz katalog prawdopodobnie program nie zadziała. Rozwiązaniem mogłoby być zakodowanie ścieżki wewnątrz programu ( np.: "/tmp/msgtool" ), lub przekazywanie ścieżki jako parametru wywołania.


   /*****************************************************************************
    Zaczerpnięto z "Linux Programmer's Guide - Rozdział 6"
    (C)opyright 1994-1995, Scott Burkett
    ***************************************************************************** 
    MODUŁ: msgtool.c
    *****************************************************************************
    Narzędzie linii poleceń do majstrowania z kolejkami wiadomości stylu SysV
    *****************************************************************************/
   
   #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();
   
           /* utwórz unikalny klucz poprzez wywołanie ftok() */
           key = ftok(".", 'm');
   
           /* otwórz kolejkę - utwórz jeżeli trzeba */
           if((msgqueue_id = msgget(key, IPC_CREAT|0660)) == -1) {
                   perror("msgget");
                   exit(1);
           }
           
           switch(tolower(argv[1][0]))
           {
                   case 'w': send_message(msgqueue_id, (struct mymsgbuf *)&qbuf,
                                          atol(argv[2]), argv[3]); 
                             break;
                   case 'o': read_message(msgqueue_id, &qbuf, atol(argv[2])); 
                             break;
                   case 'u': remove_queue(msgqueue_id); 
                             break;        
                   case 't': change_queue_mode(msgqueue_id, argv[2]); 
                             break;
   
                    default: usage();
   
           }
           
           return(0);
   }
   
   void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text)
   {
           /* wyślij wiadomość do kolejki */
           printf("Wysyłanie wiadomości ...\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)
   {
           /* odczytaj wiadomość z kolejki */
           printf("Odczytywanie wiadomości ...\n");
           qbuf->mtype = type;
           msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0);
           
           printf("Typ: %ld Tekst: %s\n", qbuf->mtype, qbuf->mtext);
   }
   
   void remove_queue(int qid)
   {
           /* Remove the queue */
           msgctl(qid, IPC_RMID, 0);
   }
   
   void change_queue_mode(int qid, char *mode)
   {
           struct msqid_ds myqueue_ds;
   
           /* pobierz informacje */
           msgctl(qid, IPC_STAT, &myqueue_ds);
   
           /* konwertuj i załaduj tryb */
           sscanf(mode, "%ho", &myqueue_ds.msg_perm.mode);
   
           /* uaktualnij tryb */
           msgctl(qid, IPC_SET, &myqueue_ds);
   }
   
   void usage(void)
   {
           fprintf(stderr, "msgtool - Narzędzie do majstrowania przy kolejkach msg\n");
           fprintf(stderr, "\nUŻYCIE: msgtool (w)yślij <typ> <tekst>\n");
           fprintf(stderr, "                (o)dbierz <typ>\n");
           fprintf(stderr, "                (u)suń\n");
           fprintf(stderr, "                (t)ryb <ósemkowy tryb>\n");
           exit(1);
   }
   




2000-03-01


Poltronic