#include #include #include #include #include #include #include #include #include #include "err.h" #include "mesg.h" using namespace std; #define MAX_SIZE 80 char MSGKEY[] = "MSGKEY"; struct mymsgbuf { long mtype; char mtext[MAX_SIZE]; }; void send_message(int qid, struct mymsgbuf *qbuf, long type, char *text) { cout << "Sending a message ..." << endl; qbuf->mtype = type; strncpy(qbuf->mtext, text, MAX_SIZE); qbuf->mtext[MAX_SIZE - 1] = '\0'; /* to null-terminate too long strings */ if((msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext) + 1, 0)) ==-1) { syserr("msgsnd in send_message"); exit(1); } } void read_message(int qid, struct mymsgbuf *qbuf, long type) { cout << "Reading a message ..." << endl; qbuf->mtype = type; if (msgrcv(qid, (struct msgbuf *)qbuf, MAX_SIZE, type, 0) == -1) syserr("msgrcv in read_message"); cout << "Type: " << qbuf->mtype << " Text: " << qbuf->mtext << endl; } void remove_queue(int qid) { if (msgctl(qid, IPC_RMID, 0) == -1) syserr("msgctl in remove_queue"); } void change_queue_mode(int qid, char *mode) { struct msqid_ds myq_ds; if (msgctl(qid, IPC_STAT, &myq_ds) == -1) /* Get current info */ syserr("msgctl1 in change_queue_mode"); sscanf(mode, "%ho", &myq_ds.msg_perm.mode); /* Convert and load the mode */ if (msgctl(qid, IPC_SET, &myq_ds) == -1) /* Update the mode */ syserr("msgctl2 in change_queue_mode"); } void usage(void) { cerr << "msgtool - A utility for tinkering with msg queues" << endl; cerr << "USAGE: msgtool (s)end " << endl; cerr << " (r)ecv " << endl; cerr << " (d)elete" << endl; cerr << " (m)ode " << endl; exit(1); } int main(int argc, char *argv[]) { key_t key; int msgq_id; struct mymsgbuf qbuf; char *key_s; if (argc == 1) usage(); if ((key_s = getenv(MSGKEY)) == 0) fatal("Environtment variable MSGKEY undefined"); if ((key = atoi(key_s)) == 0) fatal("Incorrect key"); if ((msgq_id = msgget(key, IPC_CREAT | 0660)) == -1) syserr("msgget"); switch(tolower(argv[1][0])) { case 's': send_message(msgq_id, &qbuf, atol(argv[2]), argv[3]); break; case 'r': read_message(msgq_id, &qbuf, atol(argv[2])); break; case 'd': remove_queue(msgq_id); break; case 'm': change_queue_mode(msgq_id, argv[2]); break; default : usage(); } return 0 ; }