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