unix_msg.txt
上传用户:zkm8103
上传日期:2007-01-04
资源大小:3k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * msgop.c: Illustrate the msgsnd() and msgrcv() functions.
  3.  *
  4.  * This is a simple exerciser of the message send and receive
  5.  * routines. It allows the user to attempt to send and receive as many
  6.  * messages as wanted to or from one message queue.
  7.  */
  8. #include <stdio.h>
  9. #include <sys/types.h>
  10. #include <sys/ipc.h>
  11. #include <sys/msg.h>
  12. static int ask();
  13. extern void exit();
  14. extern char *malloc();
  15. extern void perror();
  16. char first_on_queue[] = "-> first message on queue",
  17.  full_buf[] = "Message buffer overflow. Extra message text
  18.       discarded.";
  19. main()
  20. {
  21.  register int    c;  /* message text input */
  22.  int    choice; /* user's selected operation code */
  23.  register int    i;  /* loop control for mtext */
  24.  int    msgflg; /* message flags for the operation */
  25.  struct msgbuf     *msgp;  /* pointer to the message buffer */
  26.  int    msgsz;  /* message size */
  27.  long    msgtyp;  /* desired message type */
  28.  int    msqid,  /* message queue ID to be used */
  29.      maxmsgsz, /* size of allocated message buffer */
  30.      rtrn;  /* return value from msgrcv or msgsnd */
  31.  (void) fprintf(stderr,
  32.   "All numeric input is expected to follow C conventions:n");
  33.  (void) fprintf(stderr,
  34.   "t0x... is interpreted as hexadecimal,n");
  35.  (void) fprintf(stderr, "t0... is interpreted as octal,n");
  36.  (void) fprintf(stderr, "totherwise, decimal.n");
  37.  /* Get the message queue ID and set up the message buffer. */
  38.  (void) fprintf(stderr, "Enter msqid: ");
  39.  (void) scanf("%i", &msqid);
  40.  /*
  41.   * Note that <sys/msg.h> includes a definition of struct
  42. msgbuf
  43.   * with the mtext field defined as:
  44.   *   char mtext[1];
  45.   * therefore, this definition is only a template, not a
  46. structure
  47.   * definition that you can use directly, unless you want only
  48. to
  49.   * send and receive messages of 0 or 1 byte. To handle this,
  50.   * malloc an area big enough to contain the template - the size
  51.   * of the mtext template field + the size of the mtext field
  52.   * wanted. Then you can use the pointer returned by malloc as a
  53.   * struct msgbuf with an mtext field of the size you want. Note
  54.   * also that sizeof msgp->mtext is valid even though msgp
  55. isn't
  56.   * pointing to anything yet. Sizeof doesn't dereference msgp,
  57. but
  58.   * uses its type to figure out what you are asking about.
  59.   */
  60.  (void) fprintf(stderr,
  61.   "Enter the message buffer size you want:");
  62.  (void) scanf("%i", &maxmsgsz);
  63.  if (maxmsgsz < 0) {
  64.   (void) fprintf(stderr, "msgop: %sn",
  65.     "The message buffer size must be >= 0.");
  66.   exit(1);
  67.  }
  68.  msgp = (struct msgbuf *)malloc((unsigned)(sizeof(struct
  69. msgbuf)
  70.     - sizeof msgp->mtext + maxmsgsz));
  71.  if (msgp == NULL) {
  72.   (void) fprintf(stderr, "msgop: %s %d byte messages.n",
  73.     "could not allocate message buffer for", maxmsgsz);
  74.   exit(1);
  75.  }
  76.  /* Loop through message operations until the user is ready to
  77.   quit. */
  78.  while (choice = ask()) {
  79.   switch (choice) {
  80.   case 1: /* msgsnd() requested: Get the arguments, make the
  81.     call, and report the results. */
  82.    (void) fprintf(stderr, "Valid msgsnd message %sn",
  83.     "types are positive integers.");
  84.    (void) fprintf(stderr, "Enter msgp->mtype: ");
  85.    (void) scanf("%li", &msgp->mtype);
  86.    if (maxmsgsz) {
  87.     /* Since you've been using scanf, you need the loop
  88.        below to throw away the rest of the input on the
  89.        line after the entered mtype before you start
  90.        reading the mtext. */
  91.     while ((c = getchar()) != 'n' && c != EOF);
  92.     (void) fprintf(stderr, "Enter a %s:n",
  93.         "one line message");
  94.     for (i = 0; ((c = getchar()) != 'n'); i++) {
  95.      if (i >= maxmsgsz) {
  96.       (void) fprintf(stderr, "n%sn", full_buf);
  97.       while ((c = getchar()) != 'n');
  98.       break;
  99.      }
  100.      msgp->mtext[i] = c;
  101.     }
  102.     msgsz = i;
  103.    } else
  104.     msgsz = 0;
  105.    (void) fprintf(stderr,"nMeaningful msgsnd flag is:n");
  106.    (void) fprintf(stderr, "tIPC_NOWAIT =t%#8.8on",
  107.     IPC_NOWAIT);
  108.    (void) fprintf(stderr, "Enter msgflg: ");
  109.    (void) scanf("%i", &msgflg);
  110.    (void) fprintf(stderr, "%s(%d, msgp, %d, %#o)n",
  111.     "msgop: Calling msgsnd", msqid, msgsz, msgflg);
  112.    (void) fprintf(stderr, "msgp->mtype = %ldn",
  113.        msgp->mtype);
  114.    (void) fprintf(stderr, "msgp->mtext = "");
  115.    for (i = 0; i < msgsz; i++)
  116.     (void) fputc(msgp->mtext[i], stderr);
  117.     (void) fprintf(stderr, ""n");
  118.     rtrn = msgsnd(msqid, msgp, msgsz, msgflg);
  119.     if (rtrn == -1)
  120.      perror("msgop: msgsnd failed");
  121.     else
  122.      (void) fprintf(stderr,
  123.         "msgop: msgsnd returned %dn", rtrn);
  124.     break;
  125.   case 2: /* msgrcv() requested: Get the arguments, make the
  126.        call, and report the results. */
  127.    for (msgsz = -1; msgsz < 0 || msgsz > maxmsgsz;
  128.       (void) scanf("%i", &msgsz))
  129.     (void) fprintf(stderr, "%s (0 <= msgsz <= %d): ",
  130.         "Enter msgsz", maxmsgsz);
  131.    (void) fprintf(stderr, "msgtyp meanings:n");
  132.    (void) fprintf(stderr, "t 0 %sn", first_on_queue);
  133.    (void) fprintf(stderr, "t>0 %s of given typen",
  134.     first_on_queue);
  135.    (void) fprintf(stderr, "t<0 %s with type <= |msgtyp|n",
  136.        first_on_queue);
  137.    (void) fprintf(stderr, "Enter msgtyp: ");
  138.    (void) scanf("%li", &msgtyp);
  139.    (void) fprintf(stderr,
  140.        "Meaningful msgrcv flags are:n");
  141.    (void) fprintf(stderr, "tMSG_NOERROR =t%#8.8on",
  142.        MSG_NOERROR);
  143.    (void) fprintf(stderr, "tIPC_NOWAIT =t%#8.8on",
  144.        IPC_NOWAIT);
  145.    (void) fprintf(stderr, "Enter msgflg: ");
  146.    (void) scanf("%i", &msgflg);
  147.    (void) fprintf(stderr, "%s(%d, msgp, %d, %ld, %#o);n",
  148.        "msgop: Calling msgrcv", msqid, msgsz,
  149.        msgtyp, msgflg);
  150.    rtrn = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
  151.    if (rtrn == -1)
  152.     perror("msgop: msgrcv failed");
  153.    else {
  154.     (void) fprintf(stderr, "msgop: %s %dn",
  155.         "msgrcv returned", rtrn);
  156.     (void) fprintf(stderr, "msgp->mtype = %ldn",
  157.         msgp->mtype);
  158.     (void) fprintf(stderr, "msgp->mtext is: "");
  159.     for (i = 0; i < rtrn; i++)
  160.      (void) fputc(msgp->mtext[i], stderr);
  161.     (void) fprintf(stderr, ""n");
  162.    }
  163.    break;
  164.   default:
  165.    (void) fprintf(stderr, "msgop: operation unknownn");
  166.    break;
  167.   }
  168.  }
  169.  exit(0);
  170. }
  171. /*
  172.  * Ask the user what to do next. Return the user's choice code.
  173.  * Don't return until the user selects a valid choice.
  174.  */
  175. static
  176. ask()
  177. {
  178.  int response; /* User's response. */
  179.  do {
  180.   (void) fprintf(stderr, "Your options are:n");
  181.   (void) fprintf(stderr, "tExit =t0 or Control-Dn");
  182.   (void) fprintf(stderr, "tmsgsnd =t1n");
  183.   (void) fprintf(stderr, "tmsgrcv =t2n");
  184.   (void) fprintf(stderr, "Enter your choice: ");
  185.   /* Preset response so "^D" will be interpreted as exit. */
  186.   response = 0;
  187.   (void) scanf("%i", &response);
  188.  } while (response < 0 || response > 2);
  189.  return(response);
  190. }