tst-msgctl.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/ipc.h>
  5. #include <sys/msg.h>
  6. #include <sys/sem.h>
  7. #include <sys/shm.h>
  8. #include <sys/types.h>
  9. #include <time.h>
  10. #include <unistd.h>
  11. // Define the message structure
  12. struct message {
  13. long mtype; // Message Type
  14. char mtext[100]; // Message body
  15. };
  16. struct timespec ts = {
  17. .tv_sec = 3468960000, // 2075-12-05 Destination timestamp
  18. .tv_nsec = 0
  19. };
  20. void print_msqid_ds(struct msqid_ds *buf) {
  21. printf("perms: %o\n", buf->msg_perm.mode);
  22. printf("UID: %d\n", buf->msg_perm.uid);
  23. printf("GID: %d\n", buf->msg_perm.gid);
  24. printf("Current number of bytes in the queue: %d\n", buf->msg_cbytes);
  25. printf("Number of messages in the queue: %d\n", buf->msg_qnum);
  26. printf("Maximum number of bytes allowed in the queue: %d\n", buf->msg_qbytes);
  27. printf("Last sent time: %s", buf->msg_stime ? ctime(&buf->msg_stime) + 4 : "Not set \n");
  28. printf("Last received time: %s", buf->msg_rtime ? ctime(&buf->msg_rtime) + 4 : "Not set \n");
  29. }
  30. int main() {
  31. if (clock_settime(CLOCK_REALTIME, &ts) == -1) { // Set the time to after 2038
  32. perror("Error setting time");
  33. return 1;
  34. }
  35. key_t key = ftok(".", 123);
  36. if (key == -1) {
  37. perror("ftok");
  38. return 1;
  39. }
  40. int msqid = msgget(key, 0644 | IPC_CREAT); // Set to write/read only (not full permissions)
  41. if (msqid == -1) {
  42. perror("msgget");
  43. return 1;
  44. }
  45. // Get message queue status
  46. struct msqid_ds buf;
  47. memset(&buf, 0, sizeof(buf)); // Clear the structure
  48. if (msgctl(msqid, IPC_STAT, &buf) == -1) {
  49. perror("msgctl");
  50. return 1;
  51. }
  52. // Print message queue information
  53. printf("=== Initial queue status ===\n");
  54. printf("key: %x\n", key);
  55. printf("msqid: %d\n", msqid);
  56. print_msqid_ds(&buf);
  57. // Prepare the message to be sent
  58. struct message msg = {0};
  59. msg.mtype = 1; // Set the message type to 1
  60. int i =0;
  61. for(i =0; i< 2; i++)
  62. {
  63. snprintf(msg.mtext, sizeof(msg.mtext), "Hello, Message Queue %d!", i);
  64. msg.mtext[sizeof(msg.mtext) - 1] = '\0'; // Ensure the message ends with a '\0'
  65. // Send the message
  66. if (msgsnd(msqid, &msg, strlen(msg.mtext) + 1, 0) == -1) {
  67. perror("msgsnd");
  68. return 1;
  69. }
  70. printf("Message sent: %s\n", msg.mtext);
  71. // Check the queue status again
  72. memset(&buf, 0, sizeof(buf)); // Clear the structure
  73. if (msgctl(msqid, IPC_STAT, &buf) == -1) {
  74. perror("msgctl");
  75. return 1;
  76. }
  77. printf("\n=== Queue status after the message is sent ===\n");
  78. print_msqid_ds(&buf);
  79. }
  80. // Change permissions
  81. buf.msg_perm.mode = 0600; // New permissions
  82. if (msgctl(msqid, IPC_SET, &buf) == -1) {
  83. perror("msgctl IPC_SET failed");
  84. msgctl(msqid, IPC_RMID, NULL);
  85. exit(EXIT_FAILURE);
  86. }
  87. if ((buf.msg_stime - ts.tv_sec > 60) || (ts.tv_sec - buf.msg_stime > 60)) {
  88. printf("\nMsgctl get a error time! \n");
  89. exit(EXIT_FAILURE);
  90. }
  91. msgctl(msqid, IPC_RMID, NULL);
  92. return 0;
  93. }