msgq.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. if (arg.__pad != NULL) {
  29. arg.buff->msg_stime = (__time_t)arg.buff->msg_stime_internal_1 | (__time_t)(arg.buff->msg_stime_internal_2) << 32;
  30. arg.buff->msg_rtime = (__time_t)arg.buff->msg_rtime_internal_1 | (__time_t)(arg.buff->msg_rtime_internal_2) << 32;
  31. arg.buff->msg_ctime = (__time_t)arg.buff->msg_ctime_internal_1 | (__time_t)(arg.buff->msg_ctime_internal_2) << 32;
  32. }
  33. #endif
  34. return __ret;
  35. #else
  36. return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0);
  37. #endif
  38. }
  39. #endif
  40. #ifdef L_msgget
  41. #ifdef __NR_msgget
  42. _syscall2(int, msgget, key_t, key, int, msgflg)
  43. #else
  44. /* Get messages queue. */
  45. int msgget (key_t key, int msgflg)
  46. {
  47. return __syscall_ipc(IPCOP_msgget ,key ,msgflg ,0 ,0, 0);
  48. }
  49. #endif
  50. #endif
  51. struct new_msg_buf{
  52. struct msgbuf * oldmsg;
  53. long int r_msgtyp; /* the fifth arg of __syscall_ipc */
  54. };
  55. /* Receive message from message queue. */
  56. #ifdef L_msgrcv
  57. #ifdef __NR_msgrcv
  58. #define __NR___syscall_msgrcv __NR_msgrcv
  59. static inline _syscall5(ssize_t, __syscall_msgrcv, int, msqid, void *, msgp,
  60. size_t, msgsz, long int, msgtyp, int, msgflg)
  61. #endif
  62. static inline ssize_t do_msgrcv (int msqid, void *msgp, size_t msgsz,
  63. long int msgtyp, int msgflg)
  64. {
  65. #ifdef __NR_msgrcv
  66. return __syscall_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
  67. #else
  68. struct new_msg_buf temp;
  69. temp.r_msgtyp = msgtyp;
  70. temp.oldmsg = msgp;
  71. return __syscall_ipc(IPCOP_msgrcv ,msqid ,msgsz ,msgflg ,&temp, 0);
  72. #endif
  73. }
  74. ssize_t msgrcv (int msqid, void *msgp, size_t msgsz,
  75. long int msgtyp, int msgflg)
  76. {
  77. if (SINGLE_THREAD_P)
  78. return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
  79. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  80. int oldtype = LIBC_CANCEL_ASYNC ();
  81. int result = do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
  82. LIBC_CANCEL_RESET (oldtype);
  83. return result;
  84. #endif
  85. }
  86. #endif
  87. #ifdef L_msgsnd
  88. #ifdef __NR_msgsnd
  89. #define __NR___syscall_msgsnd __NR_msgsnd
  90. static inline _syscall4(int, __syscall_msgsnd, int, msqid, const void *, msgp,
  91. size_t, msgsz, int, msgflg)
  92. #endif
  93. /* Send message to message queue. */
  94. static inline int do_msgsnd (int msqid, const void *msgp, size_t msgsz,
  95. int msgflg)
  96. {
  97. #ifdef __NR_msgsnd
  98. return __syscall_msgsnd(msqid, msgp, msgsz, msgflg);
  99. #else
  100. return __syscall_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg, (void *)msgp, 0);
  101. #endif
  102. }
  103. int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
  104. {
  105. if (SINGLE_THREAD_P)
  106. return do_msgsnd(msqid, msgp, msgsz, msgflg);
  107. #ifdef __UCLIBC_HAS_THREADS_NATIVE__
  108. int oldtype = LIBC_CANCEL_ASYNC ();
  109. int result = do_msgsnd(msqid, msgp, msgsz, msgflg);
  110. LIBC_CANCEL_RESET (oldtype);
  111. return result;
  112. #endif
  113. }
  114. #endif