lcr_ifact.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright (C) 2006 Steven Dake (sdake@mvista.com)
  3. *
  4. * This software licensed under BSD license, the text of which follows:
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * - Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * - Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  15. * contributors may be used to endorse or promote products derived from this
  16. * software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  28. * THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include <stdio.h>
  31. #include <dlfcn.h>
  32. #include <dirent.h>
  33. #include <errno.h>
  34. #include <unistd.h>
  35. #include "lcr_comp.h"
  36. #include "lcr_ifact.h"
  37. #include "../include/hdb.h"
  38. struct lcr_component_instance {
  39. struct lcr_iface *ifaces;
  40. int iface_count;
  41. void *dl_handle;
  42. int (*lcr_comp_get) (struct lcr_comp **component);
  43. int refcount;
  44. };
  45. struct lcr_iface_instance {
  46. unsigned int component_handle;
  47. void *context;
  48. void (*destructor) (void *context);
  49. };
  50. static struct hdb_handle_database lcr_component_instance_database = {
  51. .handle_count = 0,
  52. .handles = 0,
  53. .iterator = 0
  54. };
  55. static struct hdb_handle_database lcr_iface_instance_database = {
  56. .handle_count = 0,
  57. .handles = 0,
  58. .iterator = 0
  59. };
  60. static int lcr_select_so (const struct dirent *dirent)
  61. {
  62. unsigned int len;
  63. len = strlen (dirent->d_name);
  64. if (len > 6) {
  65. if (strcmp (".lcrso", dirent->d_name + len - 6) == 0) {
  66. return (1);
  67. }
  68. }
  69. return (0);
  70. }
  71. int lcr_ifact_reference (
  72. unsigned int *iface_handle,
  73. char *iface_name,
  74. int version,
  75. void **iface,
  76. void *context)
  77. {
  78. struct lcr_component_instance *instance;
  79. struct lcr_component_instance new_component;
  80. struct lcr_iface_instance *iface_instance;
  81. int found = 0;
  82. int i;
  83. int res = -1;
  84. struct lcr_comp *comp;
  85. unsigned int component_handle;
  86. struct dirent **scandir_list;
  87. int scandir_entries;
  88. unsigned int libs_to_scan;
  89. char cwd[512];
  90. char dl_name[1024];
  91. getcwd (cwd, sizeof (cwd));
  92. strcat (cwd, "/");
  93. /*
  94. * Try to find interface in already loaded component
  95. */
  96. hdb_iterator_reset (&lcr_component_instance_database);
  97. while (hdb_iterator_next (&lcr_component_instance_database,
  98. (void **)&instance, &component_handle) == 0) {
  99. for (i = 0; i < instance->iface_count; i++) {
  100. if ((strcmp (instance->ifaces[i].name, iface_name) == 0) &&
  101. instance->ifaces[i].version == version) {
  102. found = 1;
  103. goto found;
  104. }
  105. }
  106. hdb_handle_put (&lcr_component_instance_database, component_handle);
  107. }
  108. // TODO error checking in this code is weak
  109. /*
  110. * Find all *.lcrso files in the cwd
  111. */
  112. scandir_entries = scandir(".", &scandir_list, lcr_select_so, alphasort);
  113. if (scandir_entries < 0)
  114. printf ("ERROR %d\n", errno);
  115. else
  116. /*
  117. * ELSE do the job
  118. */
  119. for (libs_to_scan = 0; libs_to_scan < scandir_entries; libs_to_scan++) {
  120. /*
  121. * Load objects, scan them, unload them if they are not a match
  122. */
  123. fflush (stdout);
  124. sprintf (dl_name, "%s%s", cwd, scandir_list[libs_to_scan]->d_name);
  125. new_component.dl_handle =
  126. dlopen (dl_name, RTLD_NOW);
  127. if (new_component.dl_handle == 0) {
  128. printf ("Error loading interface %s\n", dlerror());
  129. return (-1);
  130. }
  131. new_component.lcr_comp_get =
  132. dlsym (new_component.dl_handle, "lcr_comp_get");
  133. if (new_component.lcr_comp_get == 0) {
  134. printf ("Error linking interface %s\n", dlerror());
  135. return (-1);
  136. }
  137. res = new_component.lcr_comp_get (&comp);
  138. new_component.ifaces = comp->ifaces;
  139. new_component.iface_count = comp->iface_count;
  140. /*
  141. * Search loaded component for matching interface
  142. */
  143. for (i = 0; i < new_component.iface_count; i++) {
  144. if ((strcmp (new_component.ifaces[i].name, iface_name) == 0) &&
  145. new_component.ifaces[i].version == version) {
  146. hdb_handle_create (&lcr_component_instance_database,
  147. sizeof (struct lcr_component_instance),
  148. &component_handle);
  149. hdb_handle_get (&lcr_component_instance_database,
  150. component_handle, (void *)&instance);
  151. memcpy (instance, &new_component,
  152. sizeof (struct lcr_component_instance));
  153. // printf("Found interface %s ver %d in dynamically loaded object %s\n", iface_name, version, dl_name);
  154. found = 1;
  155. free(scandir_list[libs_to_scan]);
  156. goto found;
  157. }
  158. }
  159. /*
  160. * No matching interfaces found, try next shared object
  161. */
  162. dlclose (new_component.dl_handle);
  163. } /* scanning for loop */
  164. /*
  165. * No matching interfaces found in all shared objects
  166. */
  167. return (-1);
  168. found:
  169. if (found) {
  170. *iface = instance->ifaces[i].interfaces;
  171. if (instance->ifaces[i].constructor) {
  172. instance->ifaces[i].constructor (context);
  173. }
  174. hdb_handle_create (&lcr_iface_instance_database,
  175. sizeof (struct lcr_iface_instance),
  176. iface_handle);
  177. hdb_handle_get (&lcr_iface_instance_database,
  178. *iface_handle, (void *)&iface_instance);
  179. iface_instance->component_handle = component_handle;
  180. iface_instance->context = context;
  181. iface_instance->destructor = instance->ifaces[i].destructor;
  182. res = 0;
  183. }
  184. return res;
  185. }
  186. int lcr_ifact_release (unsigned int handle)
  187. {
  188. struct lcr_iface_instance *iface_instance;
  189. int res = 0;
  190. res = hdb_handle_get (&lcr_iface_instance_database,
  191. handle, (void *)&iface_instance);
  192. return (res);
  193. if (iface_instance->destructor) {
  194. iface_instance->destructor (iface_instance->context);
  195. }
  196. hdb_handle_put (&lcr_component_instance_database,
  197. iface_instance->component_handle);
  198. hdb_handle_put (&lcr_iface_instance_database, handle);
  199. hdb_handle_destroy (&lcr_iface_instance_database, handle);
  200. return (res);
  201. }