* Receive control message */
| 245 | * Receive control message |
| 246 | */ |
| 247 | static int |
| 248 | ngt_rcvmsg(node_p node, item_p item, hook_p lasthook) |
| 249 | { |
| 250 | struct proc *p; |
| 251 | const sc_p sc = NG_NODE_PRIVATE(node); |
| 252 | struct ng_mesg *msg, *resp = NULL; |
| 253 | int error = 0; |
| 254 | |
| 255 | NGI_GET_MSG(item, msg); |
| 256 | switch (msg->header.typecookie) { |
| 257 | case NGM_TTY_COOKIE: |
| 258 | switch (msg->header.cmd) { |
| 259 | case NGM_TTY_SET_TTY: |
| 260 | if (sc->tp != NULL) |
| 261 | return (EBUSY); |
| 262 | |
| 263 | p = pfind(((int *)msg->data)[0]); |
| 264 | if (p == NULL || (p->p_flag & P_WEXIT)) |
| 265 | return (ESRCH); |
| 266 | _PHOLD(p); |
| 267 | PROC_UNLOCK(p); |
| 268 | error = ttyhook_register(&sc->tp, p, ((int *)msg->data)[1], |
| 269 | &ngt_hook, sc); |
| 270 | PRELE(p); |
| 271 | if (error != 0) |
| 272 | return (error); |
| 273 | break; |
| 274 | case NGM_TTY_SET_HOTCHAR: |
| 275 | { |
| 276 | int hotchar; |
| 277 | |
| 278 | if (msg->header.arglen != sizeof(int)) |
| 279 | ERROUT(EINVAL); |
| 280 | hotchar = *((int *) msg->data); |
| 281 | if (hotchar != (u_char) hotchar && hotchar != -1) |
| 282 | ERROUT(EINVAL); |
| 283 | sc->hotchar = hotchar; /* race condition is OK */ |
| 284 | break; |
| 285 | } |
| 286 | case NGM_TTY_GET_HOTCHAR: |
| 287 | NG_MKRESPONSE(resp, msg, sizeof(int), M_NOWAIT); |
| 288 | if (!resp) |
| 289 | ERROUT(ENOMEM); |
| 290 | /* Race condition here is OK */ |
| 291 | *((int *) resp->data) = sc->hotchar; |
| 292 | break; |
| 293 | default: |
| 294 | ERROUT(EINVAL); |
| 295 | } |
| 296 | break; |
| 297 | default: |
| 298 | ERROUT(EINVAL); |
| 299 | } |
| 300 | done: |
| 301 | NG_RESPOND_MSG(error, node, item, resp); |
| 302 | NG_FREE_MSG(msg); |
| 303 | return (error); |
| 304 | } |
nothing calls this directly
no test coverage detected