msgq.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include <errno.h>
  2. #include <sys/msg.h>
  3. #include <stddef.h>
  4. #include "ipc.h"
  5. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  6. #include "sysdep-cancel.h"
  7. #else
  8. #define SINGLE_THREAD_P 1
  9. #endif
  10. #if defined(__UCLIBC_USE_TIME64__)
  11. union msqun {
  12. struct msqid_ds* buff;
  13. void *__pad;
  14. };
  15. #endif
  16. #ifdef L_msgctl
  17. #ifdef __NR_msgctl
  18. #define __NR___libc_msgctl __NR_msgctl
  19. static __inline__ _syscall3(int, __libc_msgctl, int, msqid, int, cmd, struct msqid_ds *, buf)
  20. #endif
  21. /* Message queue control operation. */
  22. int msgctl(int msqid, int cmd, struct msqid_ds *buf)
  23. {
  24. #ifdef __NR_msgctl
  25. int __ret = __libc_msgctl(msqid, cmd | __IPC_64, buf);
  26. #if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) && (defined(__mips) || defined(__riscv))
  27. union msqun arg = {.buff = buf};
  28. // When cmd is IPC_RMID, buf should be NULL.
  29. if (arg.__pad != NULL) {
  30. arg.buff->msg_stime = (__time_t)arg.buff->msg_stime_internal_1 | (__time_t)(arg.buff->msg_stime_internal_2) << 32;
  31. arg.buff->msg_rtime = (__time_t)arg.buff->msg_rtime_internal_1 | (__time_t)(arg.buff->msg_rtime_internal_2) << 32;
  32. arg.buff->msg_ctime = (__time_t)arg.buff->msg_ctime_internal_1 | (__time_t)(arg.buff->msg_ctime_internal_2) << 32;
  33. }
  34. #endif
  35. return __ret;
  36. #else
  37. return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0);
  38. #endif
  39. }
  40. #endif
  41. #ifdef L_msgget
  42. #ifdef __NR_msgget
  43. _syscall2(int, msgget, key_t, key, int, msgflg)
  44. #else
  45. /* Get messages queue. */
  46. int msgget (key_t key, int msgflg)
  47. {
  48. return __syscall_ipc(IPCOP_msgget ,key ,msgflg ,0 ,0, 0);
  49. }
  50. #endif
  51. #endif
  52. struct new_msg_buf{
  53. struct msgbuf * oldmsg;
  54. long int r_msgtyp; /* the fifth arg of __syscall_ipc */
  55. };
  56. /* Receive message from message queue. */
  57. #ifdef L_msgrcv
  58. #ifdef __NR_msgrcv
  59. #define __NR___syscall_msgrcv __NR_msgrcv
  60. static inline _syscall5(ssize_t, __syscall_msgrcv, int, msqid, void *, msgp,
  61. size_t, msgsz, long int, msgtyp, int, msgflg)
  62. #endif
  63. static inline ssize_t do_msgrcv (int msqid, void *msgp, size_t msgsz,
  64. long int msgtyp, int msgflg)
  65. {
  66. #ifdef __NR_msgrcv
  67. return __syscall_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
  68. #else
  69. struct new_msg_buf temp;
  70. temp.r_msgtyp = msgtyp;
  71. temp.oldmsg = msgp;
  72. return __syscall_ipc(IPCOP_msgrcv ,msqid ,msgsz ,msgflg ,&temp, 0);
  73. #endif
  74. }
  75. ssize_t msgrcv (int msqid, void *msgp, size_t msgsz,
  76. long int msgtyp, int msgflg)
  77. {
  78. if (SINGLE_THREAD_P)
  79. return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
  80. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  81. int oldtype = LIBC_CANCEL_ASYNC ();
  82. int result = do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
  83. LIBC_CANCEL_RESET (oldtype);
  84. return result;
  85. #endif
  86. }
  87. #endif
  88. #ifdef L_msgsnd
  89. #ifdef __NR_msgsnd
  90. #define __NR___syscall_msgsnd __NR_msgsnd
  91. static inline _syscall4(int, __syscall_msgsnd, int, msqid, const void *, msgp,
  92. size_t, msgsz, int, msgflg)
  93. #endif
  94. /* Send message to message queue. */
  95. static inline int do_msgsnd (int msqid, const void *msgp, size_t msgsz,
  96. int msgflg)
  97. {
  98. #ifdef __NR_msgsnd
  99. return __syscall_msgsnd(msqid, msgp, msgsz, msgflg);
  100. #else
  101. return __syscall_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg, (void *)msgp, 0);
  102. #endif
  103. }
  104. int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
  105. {
  106. if (SINGLE_THREAD_P)
  107. return do_msgsnd(msqid, msgp, msgsz, msgflg);
  108. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  109. int oldtype = LIBC_CANCEL_ASYNC ();
  110. int result = do_msgsnd(msqid, msgp, msgsz, msgflg);
  111. LIBC_CANCEL_RESET (oldtype);
  112. return result;
  113. #endif
  114. }
  115. #endif