u. is gone, pcb is at p_addr; aston => signotify
[unix-history] / usr / src / sys / kern / uipc_mu_msg.c
CommitLineData
127f7d76 1/* uipc_mu_msg.c Melb 4.3 82/12/28 */
ce19fd2d
RE
2
3#ifdef MUSH
4#include "../h/param.h"
5#include "../h/dir.h"
6#include "../h/user.h"
7#include "../h/proc.h"
8
9/*
10 * Melbourne Trivial IPC mechanism
11 *
12 * This is intended solely to serve for the 4.1bsd MUSH implementation
13 * until a better IPC scheme arrives from somewhere
14 *
15 * If it happens to be useful for other purposes, OK, but users
16 * should be prepared to change at short (no) notice.
17 * This is purposely kept as small as possible, with the expectation
18 * than anything done using this scheme should be able to be
19 * done easily in any other, with possibly a little more legwork.
20 *
21 * NB: we don't go fooling with spl's in here, as it is deliberately
22 * not intended that interrupt level code will ever call this
23 */
24
25mu_msg()
26{
27 register struct proc *p, *pp;
28 mmsgbuf mb;
29 register struct a {
30 msg_type cmd;
31 int wait; /* bit mask - see mu_msg.h */
32 mmsgbuf * msgp;
33 } *uap;
34
35 uap = (struct a *)u.u_ap;
36 p = u.u_procp;
37
38 for (;;) { /* only loop if cmd == MSG_SNDW */
39 switch (uap->cmd) {
40
41 case MSG_ENAB:
42 p->p_msgflgs |= MSGENAB;
43 return;
44
45 case MSG_DISB:
46 p->p_msgflgs &= ~MSGENAB;
47 /*
48 * Q: what should be done with a pending msg
49 * - for now we will just leave it, proc should
50 * do a MSG_RECV w/o waiting after MSG_DISB
51 */
52 return;
53
54 case MSG_RECV:
55 while (!p->p_mb.msg_val && (uap->wait & MSG_W_RCV)) {
56 p->p_msgflgs |= MSGOK;
57 sleep((caddr_t) &p->p_mb, MSGPRI);
58 }
127f7d76
SL
59 u.u_error = copyout((caddr_t)&p->p_mb,
60 (caddr_t)uap->msgp, sizeof(mmsgbuf));
ce19fd2d
RE
61 p->p_msgflgs &= ~(MSGOK|MSGWRPLY);
62 if (p->p_mb.msg_rply)
63 p->p_msgflgs |= MSGRPLY;
64 else {
65 p->p_mb.msg_val = 0;
66 if (p->p_msgflgs & MSGWAIT) {
67 p->p_msgflgs &= ~MSGWAIT;
68 wakeup((caddr_t)&p->p_mb);
69 }
70 }
71 return;
72
73 case MSG_SEND:
74 case MSG_SNDW:
75 case MSG_RPLY:
127f7d76
SL
76 u.u_error = copyin((caddr_t)uap->msgp, (caddr_t)&mb,
77 sizeof(mmsgbuf));
78 if (u.u_error)
ce19fd2d 79 return;
ce19fd2d
RE
80 if (uap->cmd == MSG_RPLY) {
81 if (!(p->p_msgflgs & MSGRPLY) ||
82 mb.msg_pid != p->p_mb.msg_pid) {
83 u.u_error = EINVAL;
84 return;
85 }
86 p->p_mb.msg_val = 0;
87 if (!mb.msg_rply && p->p_msgflgs & MSGWAIT) {
88 p->p_msgflgs &= ~MSGWAIT;
89 wakeup((caddr_t)&p->p_mb);
90 }
91 } else {
92 if (p->p_msgflgs & MSGRPLY) {
93 while (pp = mu_send(&p->p_mb,
4f083fd7 94 (int)p->p_mb.msg_pid, 0)) {
ce19fd2d
RE
95 pp->p_msgflgs |= MSGWAIT;
96 sleep((caddr_t)&pp->p_mb,
97 MSGPRI);
98 }
99 u.u_error = 0; /* not err if exited */
100 p->p_mb.msg_val = 0;
101 if (!mb.msg_rply &&
102 p->p_msgflgs & MSGWAIT) {
103 p->p_msgflgs &= ~MSGWAIT;
104 wakeup((caddr_t)&p->p_mb);
105 }
106 }
107 }
108 p->p_msgflgs &= ~MSGRPLY;
109 if (mb.msg_rply) {
110 if (p->p_mb.msg_val) {
111 u.u_error = ENOSPC;
112 return;
113 }
114 p->p_mb = mb;
115 p->p_mb.msg_rply = 0;
116 p->p_mb.msg_val = 0;
117 p->p_msgflgs |= MSGWRPLY;
118 }
119 mb.msg_uid = u.u_uid;
4f083fd7 120 while ((pp = mu_send(&mb, (int)mb.msg_pid, p->p_pid)) &&
ce19fd2d
RE
121 uap->wait & MSG_W_POST) {
122 pp->p_msgflgs |= MSGWAIT;
123 sleep((caddr_t)&pp->p_mb, MSGPRI);
124 }
125 if (pp)
126 u.u_error = EBUSY;
127 if (u.u_error) {
128 if (mb.msg_rply)
129 p->p_msgflgs &= ~MSGWRPLY;
130 return;
131 }
132 if (uap->cmd == MSG_SNDW) {
133 uap->cmd = MSG_RECV;
134 break;
135 }
136 return;
137
138 default:
139 u.u_error = EINVAL;
140 return;
141 }
142 }
143}
144
145struct proc *
146mu_send(mp, pid, from)
4f083fd7
SL
147 register mmsgbuf *mp;
148 register int pid, from;
ce19fd2d
RE
149{
150 register struct proc *p;
151
152 p = pfind(pid);
153
154 if (p == NULL || p->p_stat == SZOMB ||
155 !(p->p_msgflgs & (MSGOK|MSGENAB|MSGWRPLY))) {
156 u.u_error = ESRCH;
157 return((struct proc *)0);
158 }
159
160 if (p->p_mb.msg_val ||
161 from != 0 && p->p_msgflgs&MSGWRPLY && from != p->p_mb.msg_pid)
162 return(p);
163
164 p->p_mb = *mp;
165 p->p_mb.msg_val = 1;
166 p->p_mb.msg_pid = from;
167 if (from == 0)
168 p->p_mb.msg_rply = 0;
169 if (p->p_msgflgs & MSGOK)
170 wakeup((caddr_t)&p->p_mb);
171 else if (p->p_msgflgs & MSGENAB)
172 psignal(p, SIGMESG);
173 return((struct proc *)0);
174}
175
176msgto(pid, data)
177int pid;
178DATA_T data;
179{
180 register struct proc *p;
181 mmsgbuf mb;
182
183 mb.msg_uid = 0; /* all msgs from system are from root */
184 mb.msg_data = data;
185 mb.msg_rply = 0;
186 while (p = mu_send(&mb, pid, u.u_procp->p_pid)) {
187 p->p_msgflgs |= MSGWAIT;
188 sleep((caddr_t)&p->p_mb, MSGPRI);
189 }
190}
191#endif