pmap_prot2.c 4.0 KB

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