tst-msgctl.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. struct timespec ts_init, ts_final;
  32. // Save system time
  33. if (clock_gettime(CLOCK_REALTIME, &ts_init) == -1) {
  34. perror("Error getting time");
  35. return 1;
  36. }
  37. if (clock_settime(CLOCK_REALTIME, &ts) == -1) { // Set the time to after 2038
  38. perror("Error setting time");
  39. return 1;
  40. }
  41. key_t key = ftok(".", 123);
  42. if (key == -1) {
  43. perror("ftok");
  44. return 1;
  45. }
  46. int msqid = msgget(key, 0644 | IPC_CREAT); // Set to write/read only (not full permissions)
  47. if (msqid == -1) {
  48. perror("msgget");
  49. return 1;
  50. }
  51. // Get message queue status
  52. struct msqid_ds buf;
  53. memset(&buf, 0, sizeof(buf)); // Clear the structure
  54. if (msgctl(msqid, IPC_STAT, &buf) == -1) {
  55. perror("msgctl");
  56. return 1;
  57. }
  58. // Print message queue information
  59. printf("=== Initial queue status ===\n");
  60. printf("key: %x\n", key);
  61. printf("msqid: %d\n", msqid);
  62. print_msqid_ds(&buf);
  63. // Prepare the message to be sent
  64. struct message msg = {0};
  65. msg.mtype = 1; // Set the message type to 1
  66. int i =0;
  67. for(i =0; i< 2; i++)
  68. {
  69. snprintf(msg.mtext, sizeof(msg.mtext), "Hello, Message Queue %d!", i);
  70. msg.mtext[sizeof(msg.mtext) - 1] = '\0'; // Ensure the message ends with a '\0'
  71. // Send the message
  72. if (msgsnd(msqid, &msg, strlen(msg.mtext) + 1, 0) == -1) {
  73. perror("msgsnd");
  74. return 1;
  75. }
  76. printf("Message sent: %s\n", msg.mtext);
  77. // Check the queue status again
  78. memset(&buf, 0, sizeof(buf)); // Clear the structure
  79. if (msgctl(msqid, IPC_STAT, &buf) == -1) {
  80. perror("msgctl");
  81. return 1;
  82. }
  83. printf("\n=== Queue status after the message is sent ===\n");
  84. print_msqid_ds(&buf);
  85. }
  86. // Change permissions
  87. buf.msg_perm.mode = 0600; // New permissions
  88. if (msgctl(msqid, IPC_SET, &buf) == -1) {
  89. perror("msgctl IPC_SET failed");
  90. msgctl(msqid, IPC_RMID, NULL);
  91. exit(EXIT_FAILURE);
  92. }
  93. if ((buf.msg_stime - ts.tv_sec > 60) || (ts.tv_sec - buf.msg_stime > 60)) {
  94. printf("\nMsgctl get a error time! \n");
  95. exit(EXIT_FAILURE);
  96. }
  97. msgctl(msqid, IPC_RMID, NULL);
  98. // Restore system time
  99. clock_gettime(CLOCK_REALTIME, &ts_final);
  100. ts_init.tv_sec = ts_init.tv_sec + ts_final.tv_sec - ts.tv_sec;
  101. clock_settime(CLOCK_REALTIME, &ts_init);
  102. return 0;
  103. }