File: | src/lib/libc/rpc/pmap_prot2.c |
Warning: | line 95, column 28 Dereference of null pointer (loaded from variable 'rp') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: pmap_prot2.c,v 1.8 2015/09/13 15:36:56 guenther Exp $ */ | |||
2 | ||||
3 | /* | |||
4 | * Copyright (c) 2010, Oracle America, Inc. | |||
5 | * | |||
6 | * Redistribution and use in source and binary forms, with or without | |||
7 | * modification, are permitted provided that the following conditions are | |||
8 | * met: | |||
9 | * | |||
10 | * * Redistributions of source code must retain the above copyright | |||
11 | * notice, this list of conditions and the following disclaimer. | |||
12 | * * Redistributions in binary form must reproduce the above | |||
13 | * copyright notice, this list of conditions and the following | |||
14 | * disclaimer in the documentation and/or other materials | |||
15 | * provided with the distribution. | |||
16 | * * Neither the name of the "Oracle America, Inc." nor the names of its | |||
17 | * contributors may be used to endorse or promote products derived | |||
18 | * from this software without specific prior written permission. | |||
19 | * | |||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |||
23 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |||
24 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | |||
25 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |||
27 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |||
29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
32 | */ | |||
33 | ||||
34 | /* | |||
35 | * pmap_prot2.c | |||
36 | * Protocol for the local binder service, or pmap. | |||
37 | */ | |||
38 | ||||
39 | #include <rpc/types.h> | |||
40 | #include <rpc/xdr.h> | |||
41 | #include <rpc/pmap_prot.h> | |||
42 | ||||
43 | ||||
44 | /* | |||
45 | * What is going on with linked lists? (!) | |||
46 | * First recall the link list declaration from pmap_prot.h: | |||
47 | * | |||
48 | * struct pmaplist { | |||
49 | * struct pmap pml_map; | |||
50 | * struct pmaplist *pml_map; | |||
51 | * }; | |||
52 | * | |||
53 | * Compare that declaration with a corresponding xdr declaration that | |||
54 | * is (a) pointer-less, and (b) recursive: | |||
55 | * | |||
56 | * typedef union switch (bool_t) { | |||
57 | * | |||
58 | * case TRUE: struct { | |||
59 | * struct pmap; | |||
60 | * pmaplist_t foo; | |||
61 | * }; | |||
62 | * | |||
63 | * case FALSE: struct {}; | |||
64 | * } pmaplist_t; | |||
65 | * | |||
66 | * Notice that the xdr declaration has no nxt pointer while | |||
67 | * the C declaration has no bool_t variable. The bool_t can be | |||
68 | * interpreted as ``more data follows me''; if FALSE then nothing | |||
69 | * follows this bool_t; if TRUE then the bool_t is followed by | |||
70 | * an actual struct pmap, and then (recursively) by the | |||
71 | * xdr union, pamplist_t. | |||
72 | * | |||
73 | * This could be implemented via the xdr_union primitive, though this | |||
74 | * would cause a one recursive call per element in the list. Rather than do | |||
75 | * that we can ``unwind'' the recursion | |||
76 | * into a while loop and do the union arms in-place. | |||
77 | * | |||
78 | * The head of the list is what the C programmer wishes to past around | |||
79 | * the net, yet is the data that the pointer points to which is interesting; | |||
80 | * this sounds like a job for xdr_reference! | |||
81 | */ | |||
82 | bool_tint32_t | |||
83 | xdr_pmaplist(XDR *xdrs, struct pmaplist **rp) | |||
84 | { | |||
85 | /* | |||
86 | * more_elements is pre-computed in case the direction is | |||
87 | * XDR_ENCODE or XDR_FREE. more_elements is overwritten by | |||
88 | * xdr_bool when the direction is XDR_DECODE. | |||
89 | */ | |||
90 | bool_tint32_t more_elements; | |||
91 | int freeing = (xdrs->x_op == XDR_FREE); | |||
| ||||
92 | struct pmaplist **next; | |||
93 | ||||
94 | while (TRUE(1)) { | |||
95 | more_elements = (bool_tint32_t)(*rp != NULL0); | |||
| ||||
96 | if (! xdr_bool(xdrs, &more_elements)) | |||
97 | return (FALSE(0)); | |||
98 | if (! more_elements) | |||
99 | return (TRUE(1)); /* we are done */ | |||
100 | /* | |||
101 | * the unfortunate side effect of non-recursion is that in | |||
102 | * the case of freeing we must remember the next object | |||
103 | * before we free the current object ... | |||
104 | */ | |||
105 | if (freeing
| |||
106 | next = &((*rp)->pml_next); | |||
107 | if (! xdr_reference(xdrs, (caddr_t *)rp, | |||
108 | (u_int)sizeof(struct pmaplist), xdr_pmap)) | |||
109 | return (FALSE(0)); | |||
110 | rp = (freeing
| |||
111 | } | |||
112 | } | |||
113 | DEF_WEAK(xdr_pmaplist)__asm__(".weak " "xdr_pmaplist" " ; " "xdr_pmaplist" " = " "_libc_xdr_pmaplist" ); |