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

Diff of /hurd/libstore/module.c

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

revision 1.1 by roland, Sat Feb 9 04:04:43 2002 UTC revision 1.2 by roland, Thu Mar 14 21:09:49 2002 UTC
# Line 0  Line 1 
1    /* Dynamic loading of store class modules
2       Copyright (C) 2002 Free Software Foundation, Inc.
3    
4       This file is part of the GNU Hurd.
5    
6       The GNU Hurd is free software; you can redistribute it and/or
7       modify it under the terms of the GNU General Public License as
8       published by the Free Software Foundation; either version 2, or (at
9       your option) any later version.
10    
11       The GNU Hurd is distributed in the hope that it will be useful, but
12       WITHOUT ANY WARRANTY; without even the implied warranty of
13       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14       General Public License for more details.
15    
16       You should have received a copy of the GNU General Public License
17       along with this program; if not, write to the Free Software
18       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
19    
20    #include "store.h"
21    #include <dlfcn.h>
22    #include <stdio.h>
23    #include <stdlib.h>
24    #include <string.h>
25    #include <error.h>              /* XXX */
26    
27    static error_t
28    open_class (int need_open,
29                const char *name, const char *clname_end,
30                const struct store_class **classp)
31    {
32      char *modname, *clsym;
33      void *mod;
34    
35      /* Construct the name of the shared object for this module.  */
36      if (asprintf (&modname,
37                    "libstore_%.*s%s", clname_end - name, name,
38                    STORE_SONAME_SUFFIX) < 0)
39        return ENOMEM;
40    
41      /* Now try to load the module.
42    
43         Note we never dlclose the module, and add a ref every time we open it
44         anew.  We can't dlclose it until no stores of this class exist, so
45         we'd need a creation/deletion hook for that.  */
46    
47      errno = 0;
48      mod = dlopen (modname, RTLD_LAZY);
49      if (mod == NULL)
50        {
51          const char *errstring = dlerror (); /* Must always call or it leaks! */
52          if (errno != ENOENT)
53            /* XXX not good, but how else to report the error? */
54            error (0, 0, "cannot load %s: %s", modname, errstring);
55        }
56      free (modname);
57      if (mod == NULL)
58        return errno ?: ENOENT;
59    
60      if (asprintf (&clsym, "store_%.*s_class", clname_end - name, name) < 0)
61        {
62          dlclose (mod);
63          return ENOMEM;
64        }
65    
66      *classp = dlsym (mod, clsym);
67      free (clsym);
68      if (*classp == NULL)
69        {
70          error (0, 0, "invalid store module %.*s: %s",
71                 clname_end - name, name, dlerror ());
72          dlclose (mod);
73          return EGRATUITOUS;
74        }
75    
76      if (need_open && ! (*classp)->open)
77        {
78          /* This class cannot be opened as needed.  */
79          dlclose (mod);
80          return EOPNOTSUPP;
81        }
82    
83      return 0;
84    }
85    
86    error_t
87    store_module_find_class (const char *name, const char *clname_end,
88                             const struct store_class **classp)
89    {
90      return open_class (0, name, clname_end, classp);
91    }
92    
93    error_t
94    store_module_open (const char *name, int flags,
95                       const struct store_class *const *classes,
96                       struct store **store)
97    {
98      const struct store_class *cl;
99      const char *clname_end = strchr (name, ':');
100      error_t err;
101    
102      if (! clname_end)
103        return EINVAL;
104    
105      err = open_class (1, name, clname_end, &cl);
106      if (err)
107        return err;
108    
109      if (*clname_end)
110        /* Skip the ':' separating the class-name from the device name.  */
111        clname_end++;
112    
113      if (! *clname_end)
114        /* The class-specific portion of the name is empty, so make it *really*
115           empty.  */
116        clname_end = 0;
117    
118      return (*cl->open) (clname_end, flags, classes, store);
119    }
120    
121    const struct store_class store_module_open_class =
122    { -1, "module", open: store_module_open };
123    STORE_STD_CLASS (module_open);
124    
125    error_t
126    store_module_decode (struct store_enc *enc,
127                         const struct store_class *const *classes,
128                         struct store **store)
129    {
130      char *modname;
131      void *mod;
132      const struct store_class *const *cl, *const *clend;
133      enum file_storage_class id;
134    
135      if (enc->cur_int >= enc->num_ints)
136        /* The first int should always be the type.  */
137        return EINVAL;
138    
139      id = enc->ints[enc->cur_int];
140    
141      /* Construct the name of the shared object for this module.  */
142      if (asprintf (&modname, "libstore_type-%d%s", id, STORE_SONAME_SUFFIX) < 0)
143        return ENOMEM;
144    
145      /* Try to open the module.  */
146      mod = dlopen (modname, RTLD_LAZY);
147      free (modname);
148      if (mod == NULL)
149        {
150          (void) dlerror ();        /* otherwise it leaks */
151          return ENOENT;
152        }
153    
154      /* Now find its "store_std_classes" section, which points to each
155         `struct store_class' defined in this module.  */
156      cl = dlsym (mod, "__start_store_std_classes");
157      if (cl == NULL)
158        {
159          error (0, 0, "invalid store module type-%d: %s", id, dlerror ());
160          dlclose (mod);
161          return EGRATUITOUS;
162        }
163      clend = dlsym (mod, "__stop_store_std_classes");
164      if (clend == NULL)
165        {
166          error (0, 0, "invalid store module type-%d: %s", id, dlerror ());
167          dlclose (mod);
168          return EGRATUITOUS;
169        }
170    
171      while (cl < clend)
172        if ((*cl)->decode && (*cl)->id == id)
173          return (*(*cl)->decode) (enc, classes, store);
174        else
175          ++cl;
176    
177      /* This class cannot be opened via store_decode.  */
178      dlclose (mod);
179      return EOPNOTSUPP;
180    }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

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