source: sources/src/xexec.cc @ 1500:872b0b69e0d5

Revision 1500:872b0b69e0d5, 8.0 KB checked in by niam, 12 months ago (diff)

{issue #103} added implementation of sl- and dl- lists

Line 
1/***************************************************************************
2 *            xexec.cc
3 *
4 *  Wed Aug 24 2005
5 *  Copyright  2005  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#ifdef DL_EXT
33#include <dlfcn.h>
34#include <string.h>
35#endif
36
37#include <libdodo/xexec.h>
38#include <libdodo/xexecEx.h>
39#include <libdodo/types.h>
40
41using namespace dodo;
42
43xexec::__collected_data__::__collected_data__(xexec *executor,
44                                              short execObject) : executor(executor)
45{
46    executor->execObjectData = this;
47    executor->execObject = execObject;
48}
49
50void
51xexec::__collected_data__::setExecObject(short execObject)
52{
53    executor->execObject = execObject;
54}
55
56//-------------------------------------------------------------------
57
58xexec::xexec(const xexec &)
59{
60}
61
62//-------------------------------------------------------------------
63
64xexec::xexec() : safeXExecs(true),
65                 disableXExecs(false),
66                 execs(0),
67                 execObject(xexec::OBJECT_XEXEC),
68                 execObjectData(NULL)
69{
70}
71
72//-------------------------------------------------------------------
73
74xexec::~xexec()
75{
76#ifdef DL_EXT
77    deinitModule deinit;
78
79    dodo::slList<__item__>::iterator i(preExec.begin()), j(preExec.end());
80    for (; i != j; ++i) {
81        if (i->handle == NULL)
82            continue;
83
84        deinit = (deinitModule)dlsym(i->handle, "deinitXexecModule");
85        if (deinit != NULL)
86            deinit(i->cookie);
87
88#ifndef DL_FAST
89        dlclose(i->handle);
90#endif
91    }
92
93    i = postExec.begin();
94    j = postExec.end();
95    for (; i != j; ++i) {
96        if (i->handle == NULL)
97            continue;
98
99        deinit = (deinitModule)dlsym(i->handle, "deinitXexecModule");
100        if (deinit != NULL)
101            deinit(i->cookie);
102
103#ifndef DL_FAST
104        dlclose(i->handle);
105#endif
106    }
107#endif
108}
109
110//-------------------------------------------------------------------
111
112int
113xexec::addXExec(dodo::slList<__item__> &list,
114                hook               func,
115                void               *data)
116{
117    __item__ e;
118
119    e.data = data;
120    e.func = func;
121    e.id   = ++execs;
122
123#ifdef DL_EXT
124    e.handle = NULL;
125#endif
126
127    list.push(e);
128
129    return e.id;
130}
131
132//-------------------------------------------------------------------
133
134void
135xexec::removeXExec(int id)
136{
137    if (getXexec(preExec, id))
138        preExec.remove(current);
139    else if (getXexec(postExec, id))
140        postExec.remove(current);
141    else
142        return;
143
144#ifdef DL_EXT
145    if (current->handle != NULL) {
146        deinitModule deinit;
147
148        deinit = (deinitModule)dlsym(current->handle, "deinitXexecModule");
149        if (deinit != NULL)
150            deinit(current->cookie);
151
152#ifndef DL_FAST
153        if (dlclose(current->handle) != 0)
154            dodo_throw exception::basic(exception::MODULE_XEXEC, XEXECEX_REMOVEXEXEC, exception::ERRNO_DYNLOAD, 0, dlerror(), __LINE__, __FILE__);
155#endif
156    }
157#endif
158}
159
160//-------------------------------------------------------------------
161
162int
163xexec::addXExec(short type,
164                hook  func,
165                void  *data)
166{
167    if (type == ACTION_PREEXEC)
168        return addXExec(preExec, func, data);
169    else if (type == ACTION_POSTEXEC)
170        return addXExec(postExec, func, data);
171    else
172        dodo_throw exception::basic(exception::MODULE_XEXEC, XEXECEX_ADDXEXEC, exception::ERRNO_LIBDODO, XEXECEX_WRONGTYPE, XEXECEX_WRONGTYPE_STR, __LINE__, __FILE__);
173}
174
175//-------------------------------------------------------------------
176
177void
178xexec::performPreExec(short operation) const
179{
180    performXExec(preExec, operation);
181}
182
183//-------------------------------------------------------------------
184
185void
186xexec::performPostExec(short operation) const
187{
188    performXExec(postExec, operation);
189}
190
191//-------------------------------------------------------------------
192
193void
194xexec::performXExec(dodo::slList<__item__> &list,
195                    short              operation) const
196{
197    if (disableXExecs)
198        return;
199
200    dodo::slList<__item__>::iterator i(list.begin()), j(list.end());
201
202    for (; i != j; ++i) {
203        if (safeXExecs)
204            disableXExecs = true;
205
206        i->func(execObjectData, execObject, operation, i->data);
207
208        if (safeXExecs)
209            disableXExecs = false;
210    }
211}
212
213//-------------------------------------------------------------------
214
215#ifdef DL_EXT
216xexec::__module__
217xexec::module(const dodo::string &module,
218              void             *initData)
219{
220#ifdef DL_FAST
221    void *handle = dlopen(module.data(), RTLD_LAZY | RTLD_NODELETE);
222#else
223    void *handle = dlopen(module.data(), RTLD_LAZY);
224#endif
225    if (handle == NULL)
226        dodo_throw exception::basic(exception::MODULE_XEXEC, XEXECEX_MODULE, exception::ERRNO_DYNLOAD, 0, dlerror(), __LINE__, __FILE__);
227
228    initModule init = (initModule)dlsym(handle, "initXexecModule");
229    if (init == NULL)
230        dodo_throw exception::basic(exception::MODULE_XEXEC, XEXECEX_MODULE, exception::ERRNO_DYNLOAD, 0, dlerror(), __LINE__, __FILE__);
231
232    __module__ mod = init(initData);
233
234    deinitModule deinit = (deinitModule)dlsym(handle, "deinitXexecModule");
235    if (deinit != NULL)
236        deinit(mod.cookie);
237
238#ifndef DL_FAST
239    if (dlclose(handle) != 0)
240        dodo_throw exception::basic(exception::MODULE_XEXEC, XEXECEX_MODULE, exception::ERRNO_DYNLOAD, 0, dlerror(), __LINE__, __FILE__);
241
242#endif
243
244    return mod;
245}
246
247//-------------------------------------------------------------------
248
249void
250xexec::addXExec(const dodo::string &module,
251                void             *data,
252                int              &preExecId,
253                int              &postExecId,
254                void             *initData)
255{
256    __item__ e;
257
258    e.data = data;
259
260#ifdef DL_FAST
261    e.handle = dlopen(module.data(), RTLD_LAZY | RTLD_NODELETE);
262#else
263    e.handle = dlopen(module.data(), RTLD_LAZY);
264#endif
265    if (e.handle == NULL)
266        dodo_throw exception::basic(exception::MODULE_XEXEC, XEXECEX_ADDXEXEC, exception::ERRNO_DYNLOAD, 0, dlerror(), __LINE__, __FILE__);
267
268    initModule init = (initModule)dlsym(e.handle, "initXexecModule");
269    if (init == NULL)
270        dodo_throw exception::basic(exception::MODULE_XEXEC, XEXECEX_ADDXEXEC, exception::ERRNO_DYNLOAD, 0, dlerror(), __LINE__, __FILE__);
271
272    __module__ mod = init(initData);
273
274    hook in = (hook)dlsym(e.handle, mod.hook);
275    if (in == NULL)
276        dodo_throw exception::basic(exception::MODULE_XEXEC, XEXECEX_ADDXEXEC, exception::ERRNO_DYNLOAD, 0, dlerror(), __LINE__, __FILE__);
277
278    e.func = in;
279    memcpy(e.cookie, mod.cookie, 32);
280
281    if (mod.type & ACTION_PREEXEC) {
282        e.id = ++execs;
283        preExec.push(e);
284        preExecId = e.id;
285    }
286
287    if (mod.type & ACTION_POSTEXEC) {
288        e.id = ++execs;
289        postExec.push(e);
290        postExecId = e.id;
291    }
292}
293
294#endif
295
296//-------------------------------------------------------------------
297
298bool
299xexec::getXexec(dodo::slList<__item__> &list,
300                int                id)
301{
302    dodo::slList<__item__>::iterator i(list.begin()), j(list.end());
303    for (; i != j; ++i) {
304        if (i->id == id) {
305            current = i;
306
307            return true;
308        }
309    }
310
311    return false;
312}
313
314//-------------------------------------------------------------------
315
Note: See TracBrowser for help on using the repository browser.