~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to ext.c

  • Committer: Arnold D. Robbins
  • Date: 2011-12-26 21:39:48 UTC
  • Revision ID: git-v1:73d24cae0db6cc817db209e5e1ea93b0733d1cca
The grand merge: dgawk and pgawk folded into gawk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
static unsigned long long dummy;        /* fake out gcc for dynamic loading? */
38
38
#endif
39
39
 
40
 
/* do_ext --- load an extension */
41
 
 
 
40
/* do_ext --- load an extension at run-time: interface to load_ext */
 
41
 
42
42
NODE *
43
43
do_ext(int nargs)
44
44
{
45
 
        NODE *obj;
46
 
        NODE *fun;
 
45
        NODE *obj, *fun, *ret = NULL;
 
46
        SRCFILE *s;
 
47
        extern SRCFILE *srcfiles;
 
48
 
 
49
        fun = POP_STRING();
 
50
        obj = POP_STRING();
 
51
 
 
52
        s = add_srcfile(SRC_EXTLIB, obj->stptr, srcfiles, NULL, NULL);
 
53
        if (s != NULL)
 
54
                ret = load_ext(s->fullpath, fun->stptr, obj);
 
55
        DEREF(obj);
 
56
        DEREF(fun);
 
57
        if (ret == NULL)
 
58
                ret = dupnode(Nnull_string);
 
59
        return ret;
 
60
}
 
61
 
 
62
/* load_ext --- load an external library */
 
63
 
 
64
NODE *
 
65
load_ext(const char *lib_name, const char *init_func, NODE *obj)
 
66
{
47
67
        NODE *tmp = NULL;
48
68
        NODE *(*func)(NODE *, void *);
49
69
        void *dl;
50
70
        int flags = RTLD_LAZY;
51
 
        int fatal_error = FALSE;
52
71
        int *gpl_compat;
53
72
 
54
73
#ifdef __GNUC__
61
80
                fatal(_("extensions are not allowed in sandbox mode"));
62
81
 
63
82
        if (do_traditional || do_posix)
64
 
                error(_("`extension' is a gawk extension"));
65
 
 
66
 
        fun = POP_STRING();
67
 
        obj = POP_STRING();
 
83
                fatal(_("`extension' is a gawk extension"));
68
84
 
69
85
#ifdef RTLD_GLOBAL
70
86
        flags |= RTLD_GLOBAL;
71
87
#endif
72
 
        if ((dl = dlopen(obj->stptr, flags)) == NULL) {
73
 
                /* fatal needs `obj', and we need to deallocate it! */
74
 
                msg(_("fatal: extension: cannot open `%s' (%s)\n"), obj->stptr,
 
88
 
 
89
        if ((dl = dlopen(lib_name, flags)) == NULL)
 
90
                fatal(_("extension: cannot open library `%s' (%s)\n"), lib_name,
75
91
                      dlerror());
76
 
                fatal_error = TRUE;
77
 
                goto done;
78
 
        }
79
92
 
80
93
        /* Per the GNU Coding standards */
81
94
        gpl_compat = (int *) dlsym(dl, "plugin_is_GPL_compatible");
82
 
        if (gpl_compat == NULL) {
83
 
                msg(_("fatal: extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"),
84
 
                                obj->stptr, dlerror());
85
 
                fatal_error = TRUE;
86
 
                goto done;
87
 
        }
88
 
 
89
 
        func = (NODE *(*)(NODE *, void *)) dlsym(dl, fun->stptr);
90
 
        if (func == NULL) {
91
 
                msg(_("fatal: extension: library `%s': cannot call function `%s' (%s)\n"),
92
 
                                obj->stptr, fun->stptr, dlerror());
93
 
                fatal_error = TRUE;
94
 
                goto done;
 
95
        if (gpl_compat == NULL)
 
96
                fatal(_("extension: library `%s': does not define `plugin_is_GPL_compatible' (%s)\n"),
 
97
                                lib_name, dlerror());
 
98
 
 
99
        func = (NODE *(*)(NODE *, void *)) dlsym(dl, init_func);
 
100
        if (func == NULL)
 
101
                fatal(_("extension: library `%s': cannot call function `%s' (%s)\n"),
 
102
                                lib_name, init_func, dlerror());
 
103
 
 
104
        if (obj == NULL) {
 
105
                obj = make_string(lib_name, strlen(lib_name));
 
106
                tmp = (*func)(obj, dl);
 
107
                unref(tmp);
 
108
                unref(obj);
 
109
                return NULL;
95
110
        }
96
111
 
97
112
        tmp = (*func)(obj, dl);
98
 
        if (tmp == NULL)
99
 
                tmp = dupnode(Nnull_string);
100
 
done:
101
 
        DEREF(obj);
102
 
        DEREF(fun);
103
 
        if (fatal_error)
104
 
                gawk_exit(EXIT_FATAL);
105
113
        return tmp; 
106
114
}
107
115
 
173
181
 
174
182
        if (i < 0 || i >= pcount || i >= arg_count)
175
183
                return NULL;
176
 
        i++;
177
 
        t = PEEK(i);
 
184
 
 
185
        t = PEEK(arg_count - i);
 
186
        if (t->type == Node_param_list)
 
187
                t = GET_PARAM(t->param_cnt);
 
188
 
178
189
        if (t->type == Node_array_ref)
179
190
                t = t->orig_array;
180
191
        if (t->type == Node_var)        /* See Case Node_var in setup_frame(), eval.c */
247
258
        ERRNO_node->var_value = make_string(emsg, strlen(emsg));
248
259
        return make_number((AWKNUM) -1);
249
260
}
 
261
 
 
262
/* load_ext --- dummy version if extensions not available */
 
263
 
 
264
NODE *
 
265
load_ext(const char *lib_name, const char *init_func, NODE *obj)
 
266
{
 
267
        fatal(_("dynamic loading of library not supported"));
 
268
        return NULL;
 
269
}
250
270
#endif