/[hurd]/hurd/libstore/typed.c
ViewVC logotype

Diff of /hurd/libstore/typed.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by roland, Sun Oct 14 21:11:09 2001 UTC revision 1.6 by roland, Thu Mar 14 21:10:01 2002 UTC
# Line 1  Line 1 
1  /* Support for opening `typed' stores  /* Support for opening `typed' stores
2    
3     Copyright (C) 1997,98,2001 Free Software Foundation, Inc.     Copyright (C) 1997,98,2001,02 Free Software Foundation, Inc.
4     Written by Miles Bader <miles@gnu.org>     Written by Miles Bader <miles@gnu.org>
5    
6     This file is part of the GNU Hurd.     This file is part of the GNU Hurd.
# Line 21  Line 21 
21    
22  #include "store.h"  #include "store.h"
23  #include <string.h>  #include <string.h>
24    #include <dlfcn.h>
25    #include <link.h>
26    
27    
28    const struct store_class *
29    store_find_class (const char *name, const char *clname_end,
30                      const struct store_class *const *classes)
31    {
32      const struct store_class *const *cl;
33    
34      if (! clname_end)
35        clname_end = strchr (name, '\0');
36    
37      if (classes != 0)
38        {
39          /* The caller gave a class list, so that's is all we'll use.  */
40          for (cl = classes; *cl != 0; ++cl)
41            if (strlen ((*cl)->name) == (clname_end - name)
42                && !memcmp (name, (*cl)->name, (clname_end - name)))
43              break;
44          return *cl;
45        }
46    
47      /* Check the statically-linked set of classes found in the
48         "store_std_classes" section.  For static linking, this is the section
49         in the program executable itself and it has been populated by the set
50         of -lstore_TYPE pseudo-libraries included in the link.  For dynamic
51         linking with just -lstore, these symbols will be found in libstore.so
52         and have the set statically included when the shared object was built.
53         If a dynamically-linked program has its own "store_std_classes"
54         section, e.g. by -lstore_TYPE objects included in the link, this will
55         be just that section and libstore.so itself is covered below.  */
56    # pragma weak __start_store_std_classes
57    # pragma weak __stop_store_std_classes
58      for (cl = __start_store_std_classes; cl < __stop_store_std_classes; ++cl)
59        if (strlen ((*cl)->name) == (clname_end - name)
60            && strncmp (name, (*cl)->name, (clname_end - name)) == 0)
61          return *cl;
62    
63      /* Now we will iterate through all of the dynamic objects loaded
64         and examine each one's "store_std_classes" section.  */
65    # pragma weak _r_debug
66    # pragma weak dlsym
67    # pragma weak dlerror
68      if (dlsym)
69        {
70          struct link_map *map;
71          for (map = _r_debug.r_map; map != 0; map = map->l_next)
72            {
73              const struct store_class *const *start;
74              const struct store_class *const *stop;
75              start = dlsym (map, "__start_store_std_classes");
76              if (start == 0)
77                {
78                  (void) dlerror ();        /* Required to avoid a leak! */
79                  continue;
80                }
81              if (start == __start_store_std_classes)
82                continue;
83              stop = dlsym (map, "__stop_store_std_classes");
84              if (stop == 0)
85                {
86                  (void) dlerror ();        /* Required to avoid a leak! */
87                  continue;
88                }
89              for (cl = start; cl < stop; ++cl)
90                if (strlen ((*cl)->name) == (clname_end - name)
91                    && strncmp (name, (*cl)->name, (clname_end - name)) == 0)
92                  return *cl;
93            }
94        }
95    
96      return 0;
97    }
98    
99    
100  /* Open the store indicated by NAME, which should consist of a store type  /* Open the store indicated by NAME, which should consist of a store type
101     name followed by a ':' and any type-specific name, returning the new store     name followed by a ':' and any type-specific name, returning the new store
# Line 35  store_typed_open (const char *name, int Line 110  store_typed_open (const char *name, int
110                    const struct store_class *const *classes,                    const struct store_class *const *classes,
111                    struct store **store)                    struct store **store)
112  {  {
113    const struct store_class *const *cl;    const struct store_class *cl;
114    const char *clname_end = strchr (name, ':');    const char *clname_end = strchrnul (name, ':');
115    
116    if (clname_end == name)    if (clname_end == name)
117      /* Open NAME with store_open.  */      /* Open NAME with store_open.  */
118      return store_open (name + 1, flags, classes, store);      return store_open (name + 1, flags, classes, store);
119    
120    if (! clname_end)    /* Try to find an existing class by the given name.  */
121      clname_end = name + strlen (name);    cl = store_find_class (name, clname_end, classes);
122      if (cl != 0)
   if (! classes)  
     classes = store_std_classes;  
   for (cl = classes; *cl; cl++)  
     if (strlen ((*cl)->name) == (clname_end - name)  
         && strncmp (name, (*cl)->name, (clname_end - name)) == 0)  
       break;  
   
   if (! *cl)  
123      {      {
124        /* No class with the given name found.  */        if (! cl->open)
125            /* CL cannot be opened.  */
126            return EOPNOTSUPP;
127    
128        if (*clname_end)        if (*clname_end)
129          /* NAME really should be a class name, which doesn't exist.  */          /* Skip the ':' separating the class-name from the device name.  */
130          return EINVAL;          clname_end++;
       else  
         /* Try opening NAME by querying it as a file instead.  */  
         return store_open (name, flags, classes, store);  
     }  
131    
132    if (! (*cl)->open)        if (! *clname_end)
133      /* CL cannot be opened.  */          /* The class-specific portion of the name is empty, so make it *really*
134      return EOPNOTSUPP;             empty.  */
135            clname_end = 0;
136    
137    if (*clname_end)        return (*cl->open) (clname_end, flags, classes, store);
138      /* Skip the ':' separating the class-name from the device name.  */      }
     clname_end++;  
139    
140    if (! *clname_end)    /* Try to open a store by loading a module to define the class, if we
141      /* The class-specific portion of the name is empty, so make it *really*       have the module-loading support linked in.  We don't just use
142         empty.  */       store_module_find_class, because store_module_open will unload the new
143      clname_end = 0;       module if the open doesn't succeed and we have no other way to unload
144         it.  We always leave modules loaded once a store from the module has
145         been successfully opened and so can leave unbounded numbers of old
146         modules loaded after closing all the stores using them.  But at least
147         we can avoid having modules loaded for stores we never even opened.  */
148    # pragma weak store_module_open
149      if (store_module_open)
150        {
151          error_t err = store_module_open (name, flags, classes, store);
152          if (err != ENOENT)
153            return err;
154        }
155    
156    return (*(*cl)->open) (clname_end, flags, classes, store);    /* No class with the given name found.  */
157      if (*clname_end)
158        /* NAME really should be a class name, which doesn't exist.  */
159        return EINVAL;
160      else
161        /* Try opening NAME by querying it as a file instead.  */
162        return store_open (name, flags, classes, store);
163  }  }
164    
165  const struct store_class  const struct store_class
166  store_typed_open_class = { -1, "typed", open: store_typed_open };  store_typed_open_class = { -1, "typed", open: store_typed_open };
167    STORE_STD_CLASS (typed_open);

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26