4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * This module implements the PICL Interface used by PICL clients
31 * to access services of the PICL daemon
34 * A single reader/writer lock (icl_lock) protects the access to the interface
35 * to the picl daemon, and the reference count, refcnt, variable.
36 * A reader lock is obtained to send a request to the daemon.
37 * A writer lock is obtained to initialize, reinitialize, or shutdown
57 #include "picl2door.h"
62 static int door_handle
= -1;
63 static uint32_t refcnt
= 0;
64 static rwlock_t picl_lock
= DEFAULTRWLOCK
;
66 static char *picl_errmsg
[] = {
68 "General system failure",
69 "Daemon not responding",
70 "Unknown PICL service",
71 "Session not initialized",
75 "Not a table property handle",
77 "Not a property handle",
78 "End of property list",
79 "Property already exists",
80 "Property not writable",
81 "Insufficient permissions",
84 "Unsupported version",
86 "Attempting to destroy before delete",
88 "Already has a parent",
89 "Property name is reserved",
90 "Invalid reference value",
92 "Terminate tree walk",
94 "Not enough space available",
95 "Property not readable",
96 "Property value unavailable"
99 #define N_ERRORS (sizeof (picl_errmsg)/sizeof (picl_errmsg[0]))
100 #define SEND_REQ_TRYCOUNT 1
103 * This function sends the client request to the daemon using a door call.
104 * If door_handle is -1, it returns PICL_NOTINITIALIZED.
105 * If the door_call fails, it returns PICL_NORESPONSE. Otherwise, it
106 * checks the response from the daemon for error. If an error is returned
107 * this function returns the error code returned and unmaps any
108 * memory mapped by the door call. For successful results, the caller is
109 * responsible to unmap the mapped memory after retrieving the results.
111 * This function does not attempt to reinitialize the interface if the
112 * initial door_call fails. It is called from handshake() , shutdown()
113 * and trysend_req() routines.
116 post_req(door_arg_t
*dargp
, void *data_ptr
, size_t data_size
,
117 door_desc_t
*desc_ptr
, uint_t desc_num
, void *rbuf
, size_t rsize
)
123 req_cnum
= ((picl_service_t
*)data_ptr
)->in
.cnum
;
124 dargp
->data_ptr
= data_ptr
;
125 dargp
->data_size
= data_size
;
126 dargp
->desc_ptr
= desc_ptr
;
127 dargp
->desc_num
= desc_num
;
129 dargp
->rsize
= rsize
;
131 if (door_call(door_handle
, dargp
) < 0)
132 return (PICL_NORESPONSE
);
135 ret
= (picl_service_t
*)dargp
->rbuf
;
136 if (ret
->in
.cnum
== req_cnum
)
137 return (PICL_SUCCESS
);
138 else if ((ret
->in
.cnum
== PICL_CNUM_ERROR
) &&
139 (ret
->ret_error
.in_cnum
== req_cnum
))
140 err
= ret
->ret_error
.errnum
;
142 err
= PICL_UNKNOWNSERVICE
;
143 if (dargp
->rbuf
!= rbuf
)
144 (void) munmap(dargp
->rbuf
, dargp
->rsize
);
149 * This function posts an INIT message to the daemon to
150 * verify communication channel.
158 picl_retinit_t outargs
;
160 req
.cnum
= PICL_CNUM_INIT
;
161 req
.clrev
= PICL_VERSION_1
;
163 if ((err
= post_req(&darg
, &req
, sizeof (picl_reqinit_t
), NULL
,
164 0, &outargs
, sizeof (picl_retinit_t
))) != PICL_SUCCESS
)
167 if (darg
.rbuf
!= (char *)&outargs
)
168 (void) munmap(darg
.rbuf
, darg
.rsize
);
169 return (PICL_SUCCESS
);
173 * This function calls post_req() to make door_call and reinitializes
174 * the interface is post_req() fails.
177 trysend_req(door_arg_t
*dargp
, void *data_ptr
, size_t data_size
,
178 door_desc_t
*desc_ptr
, uint_t desc_num
, void *rbuf
, size_t rsize
,
179 unsigned int trycount
)
185 (void) rw_rdlock(&picl_lock
);
187 (void) rw_unlock(&picl_lock
); /* read unlock */
188 return (PICL_NOTINITIALIZED
);
191 while ((err
= post_req(dargp
, data_ptr
, data_size
, desc_ptr
, desc_num
,
192 rbuf
, rsize
)) == PICL_NORESPONSE
) {
193 if (trycount
== 0) /* no more retry */
196 if (write_locked
== 1) { /* close and open door */
197 (void) close(door_handle
);
198 if ((door_handle
= open(PICLD_DOOR
, O_RDONLY
)) < 0) {
199 err
= PICL_NORESPONSE
;
206 * Upgrade read to a write lock
208 (void) rw_unlock(&picl_lock
);
209 (void) rw_wrlock(&picl_lock
);
212 * if picl_shutdown happens during lock upgrade
215 err
= PICL_NOTINITIALIZED
;
221 (void) rw_unlock(&picl_lock
); /* read or write unlock */
226 * Initialize the PICL interface
227 * Increment the reference count.
230 picl_initialize(void)
234 (void) rw_wrlock(&picl_lock
);
235 if (refcnt
> 0) { /* previously initialized */
237 if (err
== PICL_SUCCESS
) {
239 (void) rw_unlock(&picl_lock
); /* write unlock */
242 if (err
!= PICL_NORESPONSE
) {
243 (void) rw_unlock(&picl_lock
); /* write unlock */
246 (void) close(door_handle
); /* close bad door */
250 * Open picld door and initialize door_handle
252 if ((door_handle
= open(PICLD_DOOR
, O_RDONLY
)) < 0) {
253 (void) rw_unlock(&picl_lock
); /* write unlock */
254 return (PICL_NORESPONSE
);
258 if (err
!= PICL_SUCCESS
)
259 (void) close(door_handle
);
262 (void) rw_unlock(&picl_lock
); /* write unlock */
267 * Shutdown the PICL interface
268 * Decrement the reference count and close the door_handle if refcnt is zero
275 picl_reqfini_t req_fini
;
276 picl_retfini_t outargs
;
278 (void) rw_wrlock(&picl_lock
); /* write lock */
280 (void) rw_unlock(&picl_lock
); /* write unlock */
281 return (PICL_NOTINITIALIZED
);
283 req_fini
.cnum
= PICL_CNUM_FINI
;
284 err
= post_req(&darg
, &req_fini
, sizeof (picl_reqfini_t
),
285 NULL
, 0, &outargs
, sizeof (picl_retfini_t
));
288 (void) close(door_handle
);
289 (void) rw_unlock(&picl_lock
); /* write unlock */
290 if (err
!= PICL_SUCCESS
)
292 if (darg
.rbuf
!= (char *)&outargs
)
293 (void) munmap(darg
.rbuf
, darg
.rsize
);
294 return (PICL_SUCCESS
);
298 * This function waits for the specified number of seconds for a PICL
302 picl_wait(unsigned int secs
)
305 picl_reqwait_t req_wait
;
306 picl_retwait_t outargs
;
310 req_wait
.cnum
= PICL_CNUM_WAIT
;
311 req_wait
.secs
= secs
;
312 err
= trysend_req(&darg
, &req_wait
, sizeof (picl_reqwait_t
),
313 NULL
, 0, &outargs
, sizeof (picl_retwait_t
), SEND_REQ_TRYCOUNT
);
314 if (err
!= PICL_SUCCESS
)
318 ret
= (picl_service_t
*)darg
.rbuf
;
319 err
= ret
->ret_wait
.retcode
;
320 if (darg
.rbuf
!= (char *)&outargs
)
321 (void) munmap(darg
.rbuf
, darg
.rsize
);
326 * This function copies the handle of the root node of the PICL tree into
330 picl_get_root(picl_nodehdl_t
*rooth
)
333 picl_reqroot_t req_root
;
334 picl_retroot_t outargs
;
338 req_root
.cnum
= PICL_CNUM_GETROOT
;
339 err
= trysend_req(&darg
, &req_root
, sizeof (picl_reqroot_t
), NULL
,
340 0, &outargs
, sizeof (picl_retroot_t
), SEND_REQ_TRYCOUNT
);
341 if (err
!= PICL_SUCCESS
)
344 ret
= (picl_service_t
*)darg
.rbuf
;
345 *rooth
= ret
->ret_root
.rnode
;
346 if (darg
.rbuf
!= (char *)&outargs
)
347 (void) munmap(darg
.rbuf
, darg
.rsize
);
348 return (PICL_SUCCESS
);
352 * This function copies the value of the property specified by its handle
353 * into the buffer <valbuf>.
356 picl_get_propval(picl_prophdl_t proph
, void *valbuf
, size_t nbytes
)
359 picl_reqattrval_t req_attrval
;
361 picl_retattrval_t
*outargs
;
364 req_attrval
.cnum
= PICL_CNUM_GETATTRVAL
;
365 req_attrval
.attr
= proph
;
366 req_attrval
.bufsize
= (uint32_t)nbytes
;
367 if ((size_t)req_attrval
.bufsize
!= nbytes
)
368 return (PICL_VALUETOOBIG
);
369 outargs
= alloca(sizeof (picl_retattrval_t
) + nbytes
);
371 err
= trysend_req(&darg
, &req_attrval
, sizeof (picl_reqattrval_t
),
372 NULL
, 0, outargs
, sizeof (picl_retattrval_t
) + nbytes
,
374 if (err
!= PICL_SUCCESS
)
378 ret
= (picl_service_t
*)darg
.rbuf
;
379 if (ret
->ret_attrval
.nbytes
> (uint32_t)nbytes
)
380 err
= PICL_VALUETOOBIG
;
382 (void) memcpy(valbuf
, ret
->ret_attrval
.ret_buf
,
383 (size_t)ret
->ret_attrval
.nbytes
);
384 if (darg
.rbuf
!= (char *)outargs
)
385 (void) munmap(darg
.rbuf
, darg
.rsize
);
390 * This function copies the value of the property specified by its
391 * name into the buffer <valbuf>
394 picl_get_propval_by_name(picl_nodehdl_t nodeh
, const char *propname
,
395 void *valbuf
, size_t nbytes
)
398 picl_reqattrvalbyname_t req_attrvalbyname
;
400 picl_retattrvalbyname_t
*outargs
;
403 req_attrvalbyname
.cnum
= PICL_CNUM_GETATTRVALBYNAME
;
404 req_attrvalbyname
.nodeh
= nodeh
;
405 (void) strcpy(req_attrvalbyname
.propname
, propname
);
406 req_attrvalbyname
.bufsize
= (uint32_t)nbytes
;
407 if ((size_t)req_attrvalbyname
.bufsize
!= nbytes
)
408 return (PICL_VALUETOOBIG
);
409 outargs
= alloca(sizeof (picl_retattrvalbyname_t
) + nbytes
);
411 err
= trysend_req(&darg
, &req_attrvalbyname
,
412 sizeof (picl_reqattrvalbyname_t
), NULL
, 0, outargs
,
413 sizeof (picl_retattrvalbyname_t
) + nbytes
, SEND_REQ_TRYCOUNT
);
414 if (err
!= PICL_SUCCESS
)
418 ret
= (picl_service_t
*)darg
.rbuf
;
419 if (ret
->ret_attrvalbyname
.nbytes
> (uint32_t)nbytes
)
420 err
= PICL_VALUETOOBIG
;
422 (void) memcpy(valbuf
, ret
->ret_attrvalbyname
.ret_buf
,
423 (size_t)ret
->ret_attrvalbyname
.nbytes
);
424 if (darg
.rbuf
!= (char *)outargs
)
425 (void) munmap(darg
.rbuf
, darg
.rsize
);
430 * This function sets the value of the property specified by its
431 * handle with the value specified in <valbuf>.
434 picl_set_propval(picl_prophdl_t proph
, void *valbuf
, size_t nbytes
)
437 picl_reqsetattrval_t ret_setattrval
;
438 picl_reqsetattrval_t
*inargs
;
441 if (nbytes
>= (size_t)PICL_PROPSIZE_MAX
)
442 return (PICL_VALUETOOBIG
);
444 inargs
= alloca(sizeof (picl_reqsetattrval_t
) + nbytes
);
445 inargs
->cnum
= PICL_CNUM_SETATTRVAL
;
446 inargs
->attr
= proph
;
447 inargs
->bufsize
= (uint32_t)nbytes
;
448 if ((size_t)inargs
->bufsize
!= nbytes
)
449 return (PICL_VALUETOOBIG
);
450 (void) memcpy(inargs
->valbuf
, valbuf
, nbytes
);
452 err
= trysend_req(&darg
, inargs
, sizeof (picl_reqsetattrval_t
) +
453 nbytes
, NULL
, 0, &ret_setattrval
,
454 sizeof (picl_retsetattrval_t
), SEND_REQ_TRYCOUNT
);
455 if (err
!= PICL_SUCCESS
)
458 if (darg
.rbuf
!= (char *)&ret_setattrval
)
459 (void) munmap(darg
.rbuf
, darg
.rsize
);
460 return (PICL_SUCCESS
);
464 * This function sets the value of the property specified by its
465 * name with the value given in <valbuf>
468 picl_set_propval_by_name(picl_nodehdl_t nodeh
, const char *propname
,
469 void *valbuf
, size_t nbytes
)
472 picl_retsetattrvalbyname_t ret_setattrvalbyname
;
473 picl_reqsetattrvalbyname_t
*inargs
;
476 if (nbytes
>= (size_t)PICL_PROPSIZE_MAX
)
477 return (PICL_VALUETOOBIG
);
479 inargs
= alloca(sizeof (picl_reqsetattrvalbyname_t
) + nbytes
);
480 inargs
->cnum
= PICL_CNUM_SETATTRVALBYNAME
;
481 inargs
->nodeh
= nodeh
;
482 (void) strcpy(inargs
->propname
, propname
);
483 inargs
->bufsize
= (uint32_t)nbytes
;
484 if ((size_t)inargs
->bufsize
!= nbytes
)
485 return (PICL_VALUETOOBIG
);
486 (void) memcpy(inargs
->valbuf
, valbuf
, nbytes
);
488 err
= trysend_req(&darg
, inargs
,
489 sizeof (picl_reqsetattrvalbyname_t
) + nbytes
, NULL
, 0,
490 &ret_setattrvalbyname
, sizeof (picl_retsetattrvalbyname_t
),
492 if (err
!= PICL_SUCCESS
)
495 if (darg
.rbuf
!= (char *)&ret_setattrvalbyname
)
496 (void) munmap(darg
.rbuf
, darg
.rsize
);
497 return (PICL_SUCCESS
);
501 * This function copies the information of the specified property
505 picl_get_propinfo(picl_prophdl_t proph
, picl_propinfo_t
*pinfo
)
508 picl_reqattrinfo_t req_attrinfo
;
510 picl_retattrinfo_t outargs
;
513 req_attrinfo
.cnum
= PICL_CNUM_GETATTRINFO
;
514 req_attrinfo
.attr
= proph
;
516 err
= trysend_req(&darg
, &req_attrinfo
,
517 sizeof (picl_reqattrinfo_t
), NULL
, 0, &outargs
,
518 sizeof (picl_retattrinfo_t
), SEND_REQ_TRYCOUNT
);
519 if (err
!= PICL_SUCCESS
)
523 ret
= (picl_service_t
*)darg
.rbuf
;
524 pinfo
->type
= ret
->ret_attrinfo
.type
;
525 pinfo
->accessmode
= ret
->ret_attrinfo
.accessmode
;
526 pinfo
->size
= (size_t)ret
->ret_attrinfo
.size
;
527 (void) strcpy(pinfo
->name
, ret
->ret_attrinfo
.name
);
528 if (darg
.rbuf
!= (char *)&outargs
)
529 (void) munmap(darg
.rbuf
, darg
.rsize
);
530 return (PICL_SUCCESS
);
534 * This function copies the handle of the first property of a node into
538 picl_get_first_prop(picl_nodehdl_t nodeh
, picl_prophdl_t
*proph
)
541 picl_reqfirstattr_t req_firstattr
;
543 picl_retfirstattr_t outargs
;
546 req_firstattr
.cnum
= PICL_CNUM_GETFIRSTATTR
;
547 req_firstattr
.nodeh
= nodeh
;
549 err
= trysend_req(&darg
, &req_firstattr
,
550 sizeof (picl_reqfirstattr_t
), NULL
, 0, &outargs
,
551 sizeof (picl_retfirstattr_t
), SEND_REQ_TRYCOUNT
);
552 if (err
!= PICL_SUCCESS
)
556 ret
= (picl_service_t
*)darg
.rbuf
;
557 *proph
= ret
->ret_firstattr
.attr
;
558 if (darg
.rbuf
!= (char *)&outargs
)
559 (void) munmap(darg
.rbuf
, darg
.rsize
);
560 return (PICL_SUCCESS
);
564 * This function copies the handle of the next property in list
568 picl_get_next_prop(picl_prophdl_t proph
, picl_prophdl_t
*nextprop
)
571 picl_reqnextattr_t req_nextattr
;
573 picl_retnextattr_t outargs
;
577 req_nextattr
.cnum
= PICL_CNUM_GETNEXTATTR
;
578 req_nextattr
.attr
= proph
;
580 err
= trysend_req(&darg
, &req_nextattr
,
581 sizeof (picl_reqnextattr_t
), NULL
, 0, &outargs
,
582 sizeof (picl_retnextattr_t
), SEND_REQ_TRYCOUNT
);
583 if (err
!= PICL_SUCCESS
)
587 ret
= (picl_service_t
*)darg
.rbuf
;
588 *nextprop
= ret
->ret_nextattr
.nextattr
;
589 if (darg
.rbuf
!= (char *)&outargs
)
590 (void) munmap(darg
.rbuf
, darg
.rsize
);
591 return (PICL_SUCCESS
);
595 * This function copies the handle of the property specified by its
599 picl_get_prop_by_name(picl_nodehdl_t nodeh
, const char *name
,
600 picl_prophdl_t
*proph
)
603 picl_reqattrbyname_t req_attrbyname
;
605 picl_retattrbyname_t outargs
;
608 req_attrbyname
.cnum
= PICL_CNUM_GETATTRBYNAME
;
609 req_attrbyname
.nodeh
= nodeh
;
610 (void) strcpy(req_attrbyname
.propname
, name
);
612 err
= trysend_req(&darg
, &req_attrbyname
,
613 sizeof (picl_reqattrbyname_t
), NULL
, 0, &outargs
,
614 sizeof (picl_retattrbyname_t
), SEND_REQ_TRYCOUNT
);
615 if (err
!= PICL_SUCCESS
)
619 ret
= (picl_service_t
*)darg
.rbuf
;
620 *proph
= ret
->ret_attrbyname
.attr
;
621 if (darg
.rbuf
!= (char *)&outargs
)
622 (void) munmap(darg
.rbuf
, darg
.rsize
);
623 return (PICL_SUCCESS
);
627 * This function copies the handle of the next property on the same
628 * row of the table into <rowproph>.
629 * When proph is the table handle, the handle of the property that is
630 * in first row and first column is copied.
633 picl_get_next_by_row(picl_prophdl_t proph
, picl_prophdl_t
*rowproph
)
636 picl_reqattrbyrow_t req_attrbyrow
;
638 picl_retattrbyrow_t outargs
;
641 req_attrbyrow
.cnum
= PICL_CNUM_GETATTRBYROW
;
642 req_attrbyrow
.attr
= proph
;
644 err
= trysend_req(&darg
, &req_attrbyrow
,
645 sizeof (picl_reqattrbyrow_t
), NULL
, 0, &outargs
,
646 sizeof (picl_retattrbyrow_t
), SEND_REQ_TRYCOUNT
);
647 if (err
!= PICL_SUCCESS
)
651 ret
= (picl_service_t
*)darg
.rbuf
;
652 *rowproph
= ret
->ret_attrbyrow
.rowattr
;
653 if (darg
.rbuf
!= (char *)&outargs
)
654 (void) munmap(darg
.rbuf
, darg
.rsize
);
655 return (PICL_SUCCESS
);
659 * This function copies the handle of the next property on the same
660 * column of the table into <colproph>.
661 * When proph is the table handle, the handle of the property that is
662 * in the first row and first column is copied.
665 picl_get_next_by_col(picl_prophdl_t proph
, picl_prophdl_t
*colproph
)
668 picl_reqattrbycol_t req_attrbycol
;
670 picl_retattrbycol_t outargs
;
673 req_attrbycol
.cnum
= PICL_CNUM_GETATTRBYCOL
;
674 req_attrbycol
.attr
= proph
;
676 err
= trysend_req(&darg
, (char *)&req_attrbycol
,
677 sizeof (picl_reqattrbycol_t
), NULL
, 0, (char *)&outargs
,
678 sizeof (picl_retattrbycol_t
), SEND_REQ_TRYCOUNT
);
679 if (err
!= PICL_SUCCESS
)
683 ret
= (picl_service_t
*)darg
.rbuf
;
684 *colproph
= ret
->ret_attrbycol
.colattr
;
685 if (darg
.rbuf
!= (char *)&outargs
)
686 (void) munmap(darg
.rbuf
, darg
.rsize
);
687 return (PICL_SUCCESS
);
691 * This function returns the picl error messages corresponding to the
695 picl_strerror(int err
)
697 if ((err
< N_ERRORS
) && (err
>= 0)) {
698 return (gettext(picl_errmsg
[err
]));
704 * recursively visit all nodes
707 do_walk(picl_nodehdl_t rooth
, const char *classname
,
708 void *c_args
, int (*callback_fn
)(picl_nodehdl_t hdl
, void *args
))
712 char classval
[PICL_CLASSNAMELEN_MAX
];
714 err
= picl_get_propval_by_name(rooth
, PICL_PROP_CHILD
, &chdh
,
716 while (err
== PICL_SUCCESS
) {
717 err
= picl_get_propval_by_name(chdh
, PICL_PROP_CLASSNAME
,
718 classval
, sizeof (classval
));
719 if (err
!= PICL_SUCCESS
)
722 if ((classname
== NULL
) || (strcmp(classname
, classval
) == 0)) {
723 err
= callback_fn(chdh
, c_args
);
724 if (err
!= PICL_WALK_CONTINUE
)
728 if ((err
= do_walk(chdh
, classname
, c_args
, callback_fn
)) !=
732 err
= picl_get_propval_by_name(chdh
, PICL_PROP_PEER
, &chdh
,
735 if (err
== PICL_PROPNOTFOUND
) /* end of a branch */
736 return (PICL_WALK_CONTINUE
);
742 * This function walks the tree by class and invokes the callback
743 * function on class name matches.
746 picl_walk_tree_by_class(picl_nodehdl_t rooth
, const char *classname
,
747 void *c_args
, int (*callback_fn
)(picl_nodehdl_t hdl
, void *args
))
751 if (callback_fn
== NULL
)
752 return (PICL_INVALIDARG
);
753 err
= do_walk(rooth
, classname
, c_args
, callback_fn
);
754 if ((err
== PICL_WALK_CONTINUE
) || (err
== PICL_WALK_TERMINATE
))
755 return (PICL_SUCCESS
);
760 * This function gets propinfo and prop handle of the named property
763 picl_get_propinfo_by_name(picl_nodehdl_t nodeh
, const char *prop_name
,
764 picl_propinfo_t
*pinfo
, picl_prophdl_t
*proph
)
767 picl_prophdl_t tmpproph
;
768 picl_propinfo_t tmppinfo
;
770 err
= picl_get_prop_by_name(nodeh
, prop_name
, &tmpproph
);
771 if (err
!= PICL_SUCCESS
)
774 err
= picl_get_propinfo(tmpproph
, &tmppinfo
);
775 if (err
!= PICL_SUCCESS
)
780 return (PICL_SUCCESS
);
784 picl_get_node_by_path(const char *piclpath
, picl_nodehdl_t
*nodeh
)
787 picl_reqnodebypath_t req
;
788 picl_retnodebypath_t out
;
792 req
.cnum
= PICL_CNUM_NODEBYPATH
;
793 req
.psize
= PATH_MAX
;
794 if (strlen(piclpath
) >= PATH_MAX
)
795 return (PICL_VALUETOOBIG
);
796 (void) strncpy(req
.pathbuf
, piclpath
, PATH_MAX
);
798 err
= trysend_req(&darg
, &req
, sizeof (req
), NULL
, 0, &out
,
799 sizeof (out
), SEND_REQ_TRYCOUNT
);
800 if (err
!= PICL_SUCCESS
)
804 ret
= (picl_service_t
*)darg
.rbuf
;
805 *nodeh
= ret
->ret_nodebypath
.nodeh
;
806 if (darg
.rbuf
!= (char *)&out
)
807 (void) munmap(darg
.rbuf
, darg
.rsize
);
812 picl_find_node(picl_nodehdl_t rooth
, char *pname
, picl_prop_type_t ptype
,
813 void *pval
, size_t valsize
, picl_nodehdl_t
*retnodeh
)
816 picl_reqfindnode_t
*req
;
818 picl_retfindnode_t out
;
821 req
= alloca(sizeof (picl_reqfindnode_t
) + valsize
);
822 req
->cnum
= PICL_CNUM_FINDNODE
;
824 if (strlen(pname
) >= PICL_PROPNAMELEN_MAX
)
825 return (PICL_VALUETOOBIG
);
826 (void) strncpy(req
->propname
, pname
, PICL_PROPNAMELEN_MAX
);
828 req
->valsize
= (uint32_t)valsize
;
829 if ((size_t)req
->valsize
!= valsize
)
830 return (PICL_VALUETOOBIG
);
831 (void) memcpy(req
->valbuf
, pval
, valsize
);
833 err
= trysend_req(&darg
, req
, sizeof (picl_reqfindnode_t
) + valsize
,
834 NULL
, 0, &out
, sizeof (out
), SEND_REQ_TRYCOUNT
);
835 if (err
!= PICL_SUCCESS
)
839 ret
= (picl_service_t
*)darg
.rbuf
;
840 *retnodeh
= ret
->ret_findnode
.rnodeh
;
841 if (darg
.rbuf
!= (char *)&out
)
842 (void) munmap(darg
.rbuf
, darg
.rsize
);
847 picl_get_frutree_parent(picl_nodehdl_t devh
, picl_nodehdl_t
*fruh
)
850 picl_reqfruparent_t req
;
851 picl_retfruparent_t out
;
855 req
.cnum
= PICL_CNUM_FRUTREEPARENT
;
858 err
= trysend_req(&darg
, &req
, sizeof (req
), NULL
, 0, &out
,
859 sizeof (out
), SEND_REQ_TRYCOUNT
);
860 if (err
!= PICL_SUCCESS
)
864 ret
= (picl_service_t
*)darg
.rbuf
;
865 *fruh
= ret
->ret_fruparent
.fruh
;
866 if (darg
.rbuf
!= (char *)&out
)
867 (void) munmap(darg
.rbuf
, darg
.rsize
);