1*7c568831SAndroid Build Coastguard Worker /**
2*7c568831SAndroid Build Coastguard Worker *** dlopen(), dlclose() dlsym(), dlerror() emulation for OS/400.
3*7c568831SAndroid Build Coastguard Worker ***
4*7c568831SAndroid Build Coastguard Worker *** See Copyright for the status of this software.
5*7c568831SAndroid Build Coastguard Worker ***
6*7c568831SAndroid Build Coastguard Worker *** Author: Patrick Monnerat <[email protected]>, DATASPHERE S.A.
7*7c568831SAndroid Build Coastguard Worker **/
8*7c568831SAndroid Build Coastguard Worker
9*7c568831SAndroid Build Coastguard Worker #include <stdarg.h>
10*7c568831SAndroid Build Coastguard Worker #include <stdio.h>
11*7c568831SAndroid Build Coastguard Worker #include <ctype.h>
12*7c568831SAndroid Build Coastguard Worker #include <errno.h>
13*7c568831SAndroid Build Coastguard Worker #include <stdlib.h>
14*7c568831SAndroid Build Coastguard Worker #include <unistd.h>
15*7c568831SAndroid Build Coastguard Worker #include <string.h>
16*7c568831SAndroid Build Coastguard Worker #include <dirent.h>
17*7c568831SAndroid Build Coastguard Worker #include <pthread.h>
18*7c568831SAndroid Build Coastguard Worker
19*7c568831SAndroid Build Coastguard Worker #include <sys/types.h>
20*7c568831SAndroid Build Coastguard Worker #include <sys/stat.h>
21*7c568831SAndroid Build Coastguard Worker
22*7c568831SAndroid Build Coastguard Worker #include <except.h> /* AS400 exceptions. */
23*7c568831SAndroid Build Coastguard Worker #include <miptrnam.h> /* MI pointers support. */
24*7c568831SAndroid Build Coastguard Worker #include <qusec.h> /* Error structures. */
25*7c568831SAndroid Build Coastguard Worker #include <qp0lstdi.h> /* Path to QSYS object name. */
26*7c568831SAndroid Build Coastguard Worker #include <qp0z1170.h> /* For Qp0zInitEnv(). */
27*7c568831SAndroid Build Coastguard Worker #include <qleawi.h> /* For QleActBndPgmLong() definitions. */
28*7c568831SAndroid Build Coastguard Worker #include <qsy.h> /* Qualified name structure. */
29*7c568831SAndroid Build Coastguard Worker #include <qmhrtvm.h> /* Retrieve message from message file. */
30*7c568831SAndroid Build Coastguard Worker
31*7c568831SAndroid Build Coastguard Worker #include <mih/rinzstat.h>
32*7c568831SAndroid Build Coastguard Worker #include <mih/matactex.h>
33*7c568831SAndroid Build Coastguard Worker
34*7c568831SAndroid Build Coastguard Worker #include "libxml/hash.h"
35*7c568831SAndroid Build Coastguard Worker #include "dlfcn.h"
36*7c568831SAndroid Build Coastguard Worker
37*7c568831SAndroid Build Coastguard Worker
38*7c568831SAndroid Build Coastguard Worker /**
39*7c568831SAndroid Build Coastguard Worker *** Maximum internal path length.
40*7c568831SAndroid Build Coastguard Worker **/
41*7c568831SAndroid Build Coastguard Worker
42*7c568831SAndroid Build Coastguard Worker #define MAXPATHLEN 5120
43*7c568831SAndroid Build Coastguard Worker
44*7c568831SAndroid Build Coastguard Worker
45*7c568831SAndroid Build Coastguard Worker /**
46*7c568831SAndroid Build Coastguard Worker *** Maximum error string length.
47*7c568831SAndroid Build Coastguard Worker **/
48*7c568831SAndroid Build Coastguard Worker
49*7c568831SAndroid Build Coastguard Worker #define MAX_ERR_STR 511
50*7c568831SAndroid Build Coastguard Worker
51*7c568831SAndroid Build Coastguard Worker
52*7c568831SAndroid Build Coastguard Worker /**
53*7c568831SAndroid Build Coastguard Worker *** Field address macro.
54*7c568831SAndroid Build Coastguard Worker **/
55*7c568831SAndroid Build Coastguard Worker
56*7c568831SAndroid Build Coastguard Worker #define offset_by(t, b, o) ((t *) ((char *) (b) + (unsigned int) (o)))
57*7c568831SAndroid Build Coastguard Worker
58*7c568831SAndroid Build Coastguard Worker
59*7c568831SAndroid Build Coastguard Worker /**
60*7c568831SAndroid Build Coastguard Worker *** Global flags.
61*7c568831SAndroid Build Coastguard Worker **/
62*7c568831SAndroid Build Coastguard Worker
63*7c568831SAndroid Build Coastguard Worker #define INITED 000001 /* Package has been initialized. */
64*7c568831SAndroid Build Coastguard Worker #define THREADS 000002 /* Multithreaded job. */
65*7c568831SAndroid Build Coastguard Worker #define MULTIBUF 000004 /* One error buffer per thread. */
66*7c568831SAndroid Build Coastguard Worker
67*7c568831SAndroid Build Coastguard Worker
68*7c568831SAndroid Build Coastguard Worker /**
69*7c568831SAndroid Build Coastguard Worker *** DLL handle private structure.
70*7c568831SAndroid Build Coastguard Worker **/
71*7c568831SAndroid Build Coastguard Worker
72*7c568831SAndroid Build Coastguard Worker typedef struct {
73*7c568831SAndroid Build Coastguard Worker Qle_ABP_Info_Long_t actinfo; /* Activation information. */
74*7c568831SAndroid Build Coastguard Worker _SYSPTR pointer; /* Pointer to DLL object. */
75*7c568831SAndroid Build Coastguard Worker unsigned int actcount; /* Activation count. */
76*7c568831SAndroid Build Coastguard Worker } dlinfo;
77*7c568831SAndroid Build Coastguard Worker
78*7c568831SAndroid Build Coastguard Worker
79*7c568831SAndroid Build Coastguard Worker /**
80*7c568831SAndroid Build Coastguard Worker *** Per-thread structure.
81*7c568831SAndroid Build Coastguard Worker **/
82*7c568831SAndroid Build Coastguard Worker
83*7c568831SAndroid Build Coastguard Worker typedef struct {
84*7c568831SAndroid Build Coastguard Worker unsigned int lockcount; /* Mutex lock count. */
85*7c568831SAndroid Build Coastguard Worker unsigned int iserror; /* Flag error present. */
86*7c568831SAndroid Build Coastguard Worker char str[MAX_ERR_STR + 1]; /* Error string buffer. */
87*7c568831SAndroid Build Coastguard Worker } dlts_t;
88*7c568831SAndroid Build Coastguard Worker
89*7c568831SAndroid Build Coastguard Worker
90*7c568831SAndroid Build Coastguard Worker static pthread_mutex_t dlmutex = PTHREAD_MUTEX_INITIALIZER;
91*7c568831SAndroid Build Coastguard Worker static xmlHashTablePtr dldir = (xmlHashTablePtr) NULL; /* DLL directory. */
92*7c568831SAndroid Build Coastguard Worker static unsigned int dlflags = 0; /* Package flags. */
93*7c568831SAndroid Build Coastguard Worker static pthread_key_t dlkey;
94*7c568831SAndroid Build Coastguard Worker static dlts_t static_buf; /* Static error buffer. */
95*7c568831SAndroid Build Coastguard Worker
96*7c568831SAndroid Build Coastguard Worker
97*7c568831SAndroid Build Coastguard Worker
98*7c568831SAndroid Build Coastguard Worker static void
dlthreadterm(void * mem)99*7c568831SAndroid Build Coastguard Worker dlthreadterm(void * mem)
100*7c568831SAndroid Build Coastguard Worker
101*7c568831SAndroid Build Coastguard Worker {
102*7c568831SAndroid Build Coastguard Worker free(mem);
103*7c568831SAndroid Build Coastguard Worker pthread_setspecific(dlkey, NULL);
104*7c568831SAndroid Build Coastguard Worker }
105*7c568831SAndroid Build Coastguard Worker
106*7c568831SAndroid Build Coastguard Worker
107*7c568831SAndroid Build Coastguard Worker static void
dlterm(void)108*7c568831SAndroid Build Coastguard Worker dlterm(void)
109*7c568831SAndroid Build Coastguard Worker
110*7c568831SAndroid Build Coastguard Worker {
111*7c568831SAndroid Build Coastguard Worker void * p;
112*7c568831SAndroid Build Coastguard Worker
113*7c568831SAndroid Build Coastguard Worker if (dlflags & MULTIBUF) {
114*7c568831SAndroid Build Coastguard Worker p = pthread_getspecific(dlkey);
115*7c568831SAndroid Build Coastguard Worker
116*7c568831SAndroid Build Coastguard Worker if (p)
117*7c568831SAndroid Build Coastguard Worker dlthreadterm(p);
118*7c568831SAndroid Build Coastguard Worker }
119*7c568831SAndroid Build Coastguard Worker
120*7c568831SAndroid Build Coastguard Worker if (dlflags & THREADS)
121*7c568831SAndroid Build Coastguard Worker pthread_mutex_lock(&dlmutex);
122*7c568831SAndroid Build Coastguard Worker
123*7c568831SAndroid Build Coastguard Worker if (dldir) {
124*7c568831SAndroid Build Coastguard Worker xmlHashFree(dldir, (xmlHashDeallocator) NULL);
125*7c568831SAndroid Build Coastguard Worker dldir = NULL;
126*7c568831SAndroid Build Coastguard Worker }
127*7c568831SAndroid Build Coastguard Worker
128*7c568831SAndroid Build Coastguard Worker if (dlflags & MULTIBUF)
129*7c568831SAndroid Build Coastguard Worker pthread_key_delete(dlkey);
130*7c568831SAndroid Build Coastguard Worker
131*7c568831SAndroid Build Coastguard Worker dlflags |= ~(INITED | MULTIBUF);
132*7c568831SAndroid Build Coastguard Worker pthread_mutex_unlock(&dlmutex);
133*7c568831SAndroid Build Coastguard Worker pthread_mutex_destroy(&dlmutex);
134*7c568831SAndroid Build Coastguard Worker }
135*7c568831SAndroid Build Coastguard Worker
136*7c568831SAndroid Build Coastguard Worker
137*7c568831SAndroid Build Coastguard Worker static void
dlinit(void)138*7c568831SAndroid Build Coastguard Worker dlinit(void)
139*7c568831SAndroid Build Coastguard Worker
140*7c568831SAndroid Build Coastguard Worker {
141*7c568831SAndroid Build Coastguard Worker int locked;
142*7c568831SAndroid Build Coastguard Worker
143*7c568831SAndroid Build Coastguard Worker /**
144*7c568831SAndroid Build Coastguard Worker *** Initialize the package.
145*7c568831SAndroid Build Coastguard Worker *** Should be call once per process.
146*7c568831SAndroid Build Coastguard Worker **/
147*7c568831SAndroid Build Coastguard Worker
148*7c568831SAndroid Build Coastguard Worker locked = !pthread_mutex_lock(&dlmutex);
149*7c568831SAndroid Build Coastguard Worker
150*7c568831SAndroid Build Coastguard Worker if (!(dlflags & INITED)) {
151*7c568831SAndroid Build Coastguard Worker dlflags &= ~THREADS;
152*7c568831SAndroid Build Coastguard Worker
153*7c568831SAndroid Build Coastguard Worker if (locked)
154*7c568831SAndroid Build Coastguard Worker dlflags |= THREADS;
155*7c568831SAndroid Build Coastguard Worker
156*7c568831SAndroid Build Coastguard Worker Qp0zInitEnv();
157*7c568831SAndroid Build Coastguard Worker dldir = xmlHashCreate(16);
158*7c568831SAndroid Build Coastguard Worker dlflags &= ~MULTIBUF;
159*7c568831SAndroid Build Coastguard Worker
160*7c568831SAndroid Build Coastguard Worker if (dlflags & THREADS)
161*7c568831SAndroid Build Coastguard Worker if (!pthread_key_create(&dlkey, dlthreadterm))
162*7c568831SAndroid Build Coastguard Worker dlflags |= MULTIBUF;
163*7c568831SAndroid Build Coastguard Worker
164*7c568831SAndroid Build Coastguard Worker atexit(dlterm);
165*7c568831SAndroid Build Coastguard Worker dlflags |= INITED;
166*7c568831SAndroid Build Coastguard Worker }
167*7c568831SAndroid Build Coastguard Worker
168*7c568831SAndroid Build Coastguard Worker if (locked)
169*7c568831SAndroid Build Coastguard Worker pthread_mutex_unlock(&dlmutex);
170*7c568831SAndroid Build Coastguard Worker }
171*7c568831SAndroid Build Coastguard Worker
172*7c568831SAndroid Build Coastguard Worker
173*7c568831SAndroid Build Coastguard Worker static void
dlthreadinit(void)174*7c568831SAndroid Build Coastguard Worker dlthreadinit(void)
175*7c568831SAndroid Build Coastguard Worker
176*7c568831SAndroid Build Coastguard Worker {
177*7c568831SAndroid Build Coastguard Worker dlts_t * p;
178*7c568831SAndroid Build Coastguard Worker
179*7c568831SAndroid Build Coastguard Worker if (!(dlflags & INITED))
180*7c568831SAndroid Build Coastguard Worker dlinit();
181*7c568831SAndroid Build Coastguard Worker
182*7c568831SAndroid Build Coastguard Worker if (dlflags & MULTIBUF) {
183*7c568831SAndroid Build Coastguard Worker p = pthread_getspecific(dlkey);
184*7c568831SAndroid Build Coastguard Worker
185*7c568831SAndroid Build Coastguard Worker if (!p) {
186*7c568831SAndroid Build Coastguard Worker p = (dlts_t *) malloc(sizeof *p);
187*7c568831SAndroid Build Coastguard Worker
188*7c568831SAndroid Build Coastguard Worker if (p) {
189*7c568831SAndroid Build Coastguard Worker p->lockcount = 0;
190*7c568831SAndroid Build Coastguard Worker p->iserror = 0;
191*7c568831SAndroid Build Coastguard Worker
192*7c568831SAndroid Build Coastguard Worker if (pthread_setspecific(dlkey, p))
193*7c568831SAndroid Build Coastguard Worker free(p);
194*7c568831SAndroid Build Coastguard Worker }
195*7c568831SAndroid Build Coastguard Worker }
196*7c568831SAndroid Build Coastguard Worker }
197*7c568831SAndroid Build Coastguard Worker }
198*7c568831SAndroid Build Coastguard Worker
199*7c568831SAndroid Build Coastguard Worker
200*7c568831SAndroid Build Coastguard Worker static void
dllock(void)201*7c568831SAndroid Build Coastguard Worker dllock(void)
202*7c568831SAndroid Build Coastguard Worker
203*7c568831SAndroid Build Coastguard Worker {
204*7c568831SAndroid Build Coastguard Worker dlts_t * p;
205*7c568831SAndroid Build Coastguard Worker
206*7c568831SAndroid Build Coastguard Worker if (!(dlflags & THREADS))
207*7c568831SAndroid Build Coastguard Worker return;
208*7c568831SAndroid Build Coastguard Worker
209*7c568831SAndroid Build Coastguard Worker if (dlflags & MULTIBUF) {
210*7c568831SAndroid Build Coastguard Worker p = pthread_getspecific(dlkey);
211*7c568831SAndroid Build Coastguard Worker
212*7c568831SAndroid Build Coastguard Worker if (p && p->lockcount) {
213*7c568831SAndroid Build Coastguard Worker p->lockcount++;
214*7c568831SAndroid Build Coastguard Worker return;
215*7c568831SAndroid Build Coastguard Worker }
216*7c568831SAndroid Build Coastguard Worker }
217*7c568831SAndroid Build Coastguard Worker else
218*7c568831SAndroid Build Coastguard Worker p = (dlts_t *) NULL;
219*7c568831SAndroid Build Coastguard Worker
220*7c568831SAndroid Build Coastguard Worker if (pthread_mutex_lock(&dlmutex))
221*7c568831SAndroid Build Coastguard Worker return;
222*7c568831SAndroid Build Coastguard Worker
223*7c568831SAndroid Build Coastguard Worker if (p)
224*7c568831SAndroid Build Coastguard Worker p->lockcount++;
225*7c568831SAndroid Build Coastguard Worker }
226*7c568831SAndroid Build Coastguard Worker
227*7c568831SAndroid Build Coastguard Worker
228*7c568831SAndroid Build Coastguard Worker static void
dlunlock(void)229*7c568831SAndroid Build Coastguard Worker dlunlock(void)
230*7c568831SAndroid Build Coastguard Worker
231*7c568831SAndroid Build Coastguard Worker {
232*7c568831SAndroid Build Coastguard Worker dlts_t * p;
233*7c568831SAndroid Build Coastguard Worker
234*7c568831SAndroid Build Coastguard Worker if (!(dlflags & THREADS))
235*7c568831SAndroid Build Coastguard Worker return;
236*7c568831SAndroid Build Coastguard Worker
237*7c568831SAndroid Build Coastguard Worker if (dlflags & MULTIBUF) {
238*7c568831SAndroid Build Coastguard Worker p = pthread_getspecific(dlkey);
239*7c568831SAndroid Build Coastguard Worker
240*7c568831SAndroid Build Coastguard Worker if (p && p->lockcount > 1) {
241*7c568831SAndroid Build Coastguard Worker p->lockcount--;
242*7c568831SAndroid Build Coastguard Worker return;
243*7c568831SAndroid Build Coastguard Worker }
244*7c568831SAndroid Build Coastguard Worker }
245*7c568831SAndroid Build Coastguard Worker else
246*7c568831SAndroid Build Coastguard Worker p = (dlts_t *) NULL;
247*7c568831SAndroid Build Coastguard Worker
248*7c568831SAndroid Build Coastguard Worker if (pthread_mutex_unlock(&dlmutex))
249*7c568831SAndroid Build Coastguard Worker return;
250*7c568831SAndroid Build Coastguard Worker
251*7c568831SAndroid Build Coastguard Worker if (p)
252*7c568831SAndroid Build Coastguard Worker p->lockcount--;
253*7c568831SAndroid Build Coastguard Worker }
254*7c568831SAndroid Build Coastguard Worker
255*7c568831SAndroid Build Coastguard Worker
256*7c568831SAndroid Build Coastguard Worker const char *
dlerror(void)257*7c568831SAndroid Build Coastguard Worker dlerror(void)
258*7c568831SAndroid Build Coastguard Worker
259*7c568831SAndroid Build Coastguard Worker {
260*7c568831SAndroid Build Coastguard Worker dlts_t * p;
261*7c568831SAndroid Build Coastguard Worker
262*7c568831SAndroid Build Coastguard Worker dlthreadinit();
263*7c568831SAndroid Build Coastguard Worker
264*7c568831SAndroid Build Coastguard Worker if (!(dlflags & MULTIBUF))
265*7c568831SAndroid Build Coastguard Worker p = &static_buf;
266*7c568831SAndroid Build Coastguard Worker else if (!(p = (dlts_t *) pthread_getspecific(dlkey)))
267*7c568831SAndroid Build Coastguard Worker p = &static_buf;
268*7c568831SAndroid Build Coastguard Worker
269*7c568831SAndroid Build Coastguard Worker if (!p->iserror)
270*7c568831SAndroid Build Coastguard Worker return (const char *) NULL;
271*7c568831SAndroid Build Coastguard Worker
272*7c568831SAndroid Build Coastguard Worker p->iserror = 0;
273*7c568831SAndroid Build Coastguard Worker return p->str;
274*7c568831SAndroid Build Coastguard Worker }
275*7c568831SAndroid Build Coastguard Worker
276*7c568831SAndroid Build Coastguard Worker
277*7c568831SAndroid Build Coastguard Worker static void
dlseterror_from_errno(unsigned int err_no)278*7c568831SAndroid Build Coastguard Worker dlseterror_from_errno(unsigned int err_no)
279*7c568831SAndroid Build Coastguard Worker
280*7c568831SAndroid Build Coastguard Worker {
281*7c568831SAndroid Build Coastguard Worker dlts_t * p;
282*7c568831SAndroid Build Coastguard Worker
283*7c568831SAndroid Build Coastguard Worker if (!(dlflags & MULTIBUF))
284*7c568831SAndroid Build Coastguard Worker p = &static_buf;
285*7c568831SAndroid Build Coastguard Worker else if (!(p = (dlts_t *) pthread_getspecific(dlkey)))
286*7c568831SAndroid Build Coastguard Worker p = &static_buf;
287*7c568831SAndroid Build Coastguard Worker
288*7c568831SAndroid Build Coastguard Worker strcpy(p->str, strerror(err_no));
289*7c568831SAndroid Build Coastguard Worker p->iserror = 1;
290*7c568831SAndroid Build Coastguard Worker }
291*7c568831SAndroid Build Coastguard Worker
292*7c568831SAndroid Build Coastguard Worker
293*7c568831SAndroid Build Coastguard Worker static void
dlseterror_from_exception(volatile _INTRPT_Hndlr_Parms_T * excp)294*7c568831SAndroid Build Coastguard Worker dlseterror_from_exception(volatile _INTRPT_Hndlr_Parms_T * excp)
295*7c568831SAndroid Build Coastguard Worker
296*7c568831SAndroid Build Coastguard Worker {
297*7c568831SAndroid Build Coastguard Worker int i;
298*7c568831SAndroid Build Coastguard Worker Qmh_Rtvm_RTVM0300_t * imp;
299*7c568831SAndroid Build Coastguard Worker char * cp;
300*7c568831SAndroid Build Coastguard Worker _INTRPT_Hndlr_Parms_T * p;
301*7c568831SAndroid Build Coastguard Worker dlts_t * q;
302*7c568831SAndroid Build Coastguard Worker char rtvmbuf[30000];
303*7c568831SAndroid Build Coastguard Worker Qus_EC_t errinfo;
304*7c568831SAndroid Build Coastguard Worker
305*7c568831SAndroid Build Coastguard Worker p = (_INTRPT_Hndlr_Parms_T *) excp;
306*7c568831SAndroid Build Coastguard Worker errinfo.Bytes_Provided = 0; /* Exception on error. */
307*7c568831SAndroid Build Coastguard Worker QMHRTVM(rtvmbuf, sizeof rtvmbuf, "RTVM0300", p->Msg_Id,
308*7c568831SAndroid Build Coastguard Worker "QCPFMSG QSYS ", p->Ex_Data, p->Msg_Data_Len,
309*7c568831SAndroid Build Coastguard Worker "*YES ", "*NO ", &errinfo);
310*7c568831SAndroid Build Coastguard Worker imp = offset_by(Qmh_Rtvm_RTVM0300_t, rtvmbuf, 0);
311*7c568831SAndroid Build Coastguard Worker
312*7c568831SAndroid Build Coastguard Worker if (!(dlflags & MULTIBUF))
313*7c568831SAndroid Build Coastguard Worker q = &static_buf;
314*7c568831SAndroid Build Coastguard Worker else if (!(q = (dlts_t *) pthread_getspecific(dlkey)))
315*7c568831SAndroid Build Coastguard Worker q = &static_buf;
316*7c568831SAndroid Build Coastguard Worker
317*7c568831SAndroid Build Coastguard Worker if (i = imp->Length_Message_Returned)
318*7c568831SAndroid Build Coastguard Worker cp = offset_by(char, imp, imp->Offset_Message_Returned);
319*7c568831SAndroid Build Coastguard Worker else if (i = imp->Length_Help_Returned)
320*7c568831SAndroid Build Coastguard Worker cp = offset_by(char, imp, imp->Offset_Help_Returned);
321*7c568831SAndroid Build Coastguard Worker else {
322*7c568831SAndroid Build Coastguard Worker q->iserror = 0;
323*7c568831SAndroid Build Coastguard Worker return;
324*7c568831SAndroid Build Coastguard Worker }
325*7c568831SAndroid Build Coastguard Worker
326*7c568831SAndroid Build Coastguard Worker q->iserror = 1;
327*7c568831SAndroid Build Coastguard Worker
328*7c568831SAndroid Build Coastguard Worker if (i > sizeof q->str - 1)
329*7c568831SAndroid Build Coastguard Worker i = sizeof q->str - 1;
330*7c568831SAndroid Build Coastguard Worker
331*7c568831SAndroid Build Coastguard Worker memcpy(q->str, cp, i);
332*7c568831SAndroid Build Coastguard Worker q->str[i] = '\0';
333*7c568831SAndroid Build Coastguard Worker }
334*7c568831SAndroid Build Coastguard Worker
335*7c568831SAndroid Build Coastguard Worker
336*7c568831SAndroid Build Coastguard Worker static int
dlparentpath(const char * path,size_t len)337*7c568831SAndroid Build Coastguard Worker dlparentpath(const char * path, size_t len)
338*7c568831SAndroid Build Coastguard Worker
339*7c568831SAndroid Build Coastguard Worker {
340*7c568831SAndroid Build Coastguard Worker if (len <= 1)
341*7c568831SAndroid Build Coastguard Worker return len;
342*7c568831SAndroid Build Coastguard Worker
343*7c568831SAndroid Build Coastguard Worker while (path[--len] != '/')
344*7c568831SAndroid Build Coastguard Worker ;
345*7c568831SAndroid Build Coastguard Worker
346*7c568831SAndroid Build Coastguard Worker return len? len: 1;
347*7c568831SAndroid Build Coastguard Worker }
348*7c568831SAndroid Build Coastguard Worker
349*7c568831SAndroid Build Coastguard Worker
350*7c568831SAndroid Build Coastguard Worker static int
dlmakepath(char * path,size_t pathlen,const char * tail,size_t taillen)351*7c568831SAndroid Build Coastguard Worker dlmakepath(char * path, size_t pathlen, const char * tail, size_t taillen)
352*7c568831SAndroid Build Coastguard Worker
353*7c568831SAndroid Build Coastguard Worker {
354*7c568831SAndroid Build Coastguard Worker int i;
355*7c568831SAndroid Build Coastguard Worker
356*7c568831SAndroid Build Coastguard Worker if (taillen && tail[0] == '/')
357*7c568831SAndroid Build Coastguard Worker pathlen = 0;
358*7c568831SAndroid Build Coastguard Worker
359*7c568831SAndroid Build Coastguard Worker for (;;) {
360*7c568831SAndroid Build Coastguard Worker while (taillen && *tail == '/') {
361*7c568831SAndroid Build Coastguard Worker tail++;
362*7c568831SAndroid Build Coastguard Worker taillen--;
363*7c568831SAndroid Build Coastguard Worker }
364*7c568831SAndroid Build Coastguard Worker
365*7c568831SAndroid Build Coastguard Worker if (!taillen)
366*7c568831SAndroid Build Coastguard Worker break;
367*7c568831SAndroid Build Coastguard Worker
368*7c568831SAndroid Build Coastguard Worker for (i = 0; i < taillen; i++)
369*7c568831SAndroid Build Coastguard Worker if (tail[i] == '/')
370*7c568831SAndroid Build Coastguard Worker break;
371*7c568831SAndroid Build Coastguard Worker
372*7c568831SAndroid Build Coastguard Worker if (*tail == '.')
373*7c568831SAndroid Build Coastguard Worker switch (i) {
374*7c568831SAndroid Build Coastguard Worker
375*7c568831SAndroid Build Coastguard Worker case 2:
376*7c568831SAndroid Build Coastguard Worker if (tail[1] != '.')
377*7c568831SAndroid Build Coastguard Worker break;
378*7c568831SAndroid Build Coastguard Worker
379*7c568831SAndroid Build Coastguard Worker pathlen = dlparentpath(path, pathlen);
380*7c568831SAndroid Build Coastguard Worker
381*7c568831SAndroid Build Coastguard Worker case 1:
382*7c568831SAndroid Build Coastguard Worker tail += i;
383*7c568831SAndroid Build Coastguard Worker taillen -= i;
384*7c568831SAndroid Build Coastguard Worker continue;
385*7c568831SAndroid Build Coastguard Worker }
386*7c568831SAndroid Build Coastguard Worker
387*7c568831SAndroid Build Coastguard Worker if (pathlen + i + 1 >= MAXPATHLEN) {
388*7c568831SAndroid Build Coastguard Worker errno = ENAMETOOLONG;
389*7c568831SAndroid Build Coastguard Worker return -1;
390*7c568831SAndroid Build Coastguard Worker }
391*7c568831SAndroid Build Coastguard Worker
392*7c568831SAndroid Build Coastguard Worker path[pathlen++] = '/';
393*7c568831SAndroid Build Coastguard Worker memcpy(path + pathlen, tail, i);
394*7c568831SAndroid Build Coastguard Worker pathlen += i;
395*7c568831SAndroid Build Coastguard Worker }
396*7c568831SAndroid Build Coastguard Worker
397*7c568831SAndroid Build Coastguard Worker if (!pathlen)
398*7c568831SAndroid Build Coastguard Worker path[pathlen++] = '/';
399*7c568831SAndroid Build Coastguard Worker
400*7c568831SAndroid Build Coastguard Worker path[pathlen] = '\0';
401*7c568831SAndroid Build Coastguard Worker return pathlen;
402*7c568831SAndroid Build Coastguard Worker }
403*7c568831SAndroid Build Coastguard Worker
404*7c568831SAndroid Build Coastguard Worker
405*7c568831SAndroid Build Coastguard Worker static int
dlresolveLink(const char * path,char * buf,size_t bufsiz)406*7c568831SAndroid Build Coastguard Worker dlresolveLink(const char * path, char * buf, size_t bufsiz)
407*7c568831SAndroid Build Coastguard Worker
408*7c568831SAndroid Build Coastguard Worker {
409*7c568831SAndroid Build Coastguard Worker int n;
410*7c568831SAndroid Build Coastguard Worker int l1;
411*7c568831SAndroid Build Coastguard Worker int l2;
412*7c568831SAndroid Build Coastguard Worker struct stat sbuf;
413*7c568831SAndroid Build Coastguard Worker char buf1[MAXPATHLEN + 1];
414*7c568831SAndroid Build Coastguard Worker char buf2[MAXPATHLEN + 1];
415*7c568831SAndroid Build Coastguard Worker
416*7c568831SAndroid Build Coastguard Worker /**
417*7c568831SAndroid Build Coastguard Worker *** Resolve symbolic link to IFS object name.
418*7c568831SAndroid Build Coastguard Worker **/
419*7c568831SAndroid Build Coastguard Worker
420*7c568831SAndroid Build Coastguard Worker if (!buf) {
421*7c568831SAndroid Build Coastguard Worker errno = EFAULT;
422*7c568831SAndroid Build Coastguard Worker return -1;
423*7c568831SAndroid Build Coastguard Worker }
424*7c568831SAndroid Build Coastguard Worker
425*7c568831SAndroid Build Coastguard Worker if (!path || !*path || !bufsiz) {
426*7c568831SAndroid Build Coastguard Worker errno = EINVAL;
427*7c568831SAndroid Build Coastguard Worker return -1;
428*7c568831SAndroid Build Coastguard Worker }
429*7c568831SAndroid Build Coastguard Worker
430*7c568831SAndroid Build Coastguard Worker if (*path != '/') {
431*7c568831SAndroid Build Coastguard Worker if (!getcwd(buf1, sizeof buf1))
432*7c568831SAndroid Build Coastguard Worker return -1;
433*7c568831SAndroid Build Coastguard Worker
434*7c568831SAndroid Build Coastguard Worker l1 = strlen(buf1);
435*7c568831SAndroid Build Coastguard Worker }
436*7c568831SAndroid Build Coastguard Worker else
437*7c568831SAndroid Build Coastguard Worker l1 = 0;
438*7c568831SAndroid Build Coastguard Worker
439*7c568831SAndroid Build Coastguard Worker l1 = dlmakepath(buf1, l1, path, strlen(path));
440*7c568831SAndroid Build Coastguard Worker n = 0;
441*7c568831SAndroid Build Coastguard Worker
442*7c568831SAndroid Build Coastguard Worker for (;;) {
443*7c568831SAndroid Build Coastguard Worker if (l1 < 0)
444*7c568831SAndroid Build Coastguard Worker return -1;
445*7c568831SAndroid Build Coastguard Worker
446*7c568831SAndroid Build Coastguard Worker if (n++ >= 256) {
447*7c568831SAndroid Build Coastguard Worker errno = ELOOP;
448*7c568831SAndroid Build Coastguard Worker return -1;
449*7c568831SAndroid Build Coastguard Worker }
450*7c568831SAndroid Build Coastguard Worker
451*7c568831SAndroid Build Coastguard Worker if (lstat(buf1, &sbuf)) {
452*7c568831SAndroid Build Coastguard Worker if (errno == ENOENT)
453*7c568831SAndroid Build Coastguard Worker break;
454*7c568831SAndroid Build Coastguard Worker
455*7c568831SAndroid Build Coastguard Worker return -1;
456*7c568831SAndroid Build Coastguard Worker }
457*7c568831SAndroid Build Coastguard Worker
458*7c568831SAndroid Build Coastguard Worker if (!S_ISLNK(sbuf.st_mode))
459*7c568831SAndroid Build Coastguard Worker break;
460*7c568831SAndroid Build Coastguard Worker
461*7c568831SAndroid Build Coastguard Worker if (sbuf.st_size > MAXPATHLEN) {
462*7c568831SAndroid Build Coastguard Worker errno = ENAMETOOLONG;
463*7c568831SAndroid Build Coastguard Worker return -1;
464*7c568831SAndroid Build Coastguard Worker }
465*7c568831SAndroid Build Coastguard Worker
466*7c568831SAndroid Build Coastguard Worker l2 = readlink(buf1, buf2, MAXPATHLEN + 1);
467*7c568831SAndroid Build Coastguard Worker
468*7c568831SAndroid Build Coastguard Worker if (l2 < 0)
469*7c568831SAndroid Build Coastguard Worker return -1;
470*7c568831SAndroid Build Coastguard Worker
471*7c568831SAndroid Build Coastguard Worker if (buf2[0] != '/')
472*7c568831SAndroid Build Coastguard Worker l1 = dlparentpath(buf1, l1);
473*7c568831SAndroid Build Coastguard Worker
474*7c568831SAndroid Build Coastguard Worker l1 = dlmakepath(buf1, l1, buf2, l2);
475*7c568831SAndroid Build Coastguard Worker }
476*7c568831SAndroid Build Coastguard Worker
477*7c568831SAndroid Build Coastguard Worker if (l1 >= bufsiz) {
478*7c568831SAndroid Build Coastguard Worker errno = ENAMETOOLONG;
479*7c568831SAndroid Build Coastguard Worker return -1;
480*7c568831SAndroid Build Coastguard Worker }
481*7c568831SAndroid Build Coastguard Worker
482*7c568831SAndroid Build Coastguard Worker memcpy(buf, buf1, l1 + 1);
483*7c568831SAndroid Build Coastguard Worker return l1;
484*7c568831SAndroid Build Coastguard Worker }
485*7c568831SAndroid Build Coastguard Worker
486*7c568831SAndroid Build Coastguard Worker
487*7c568831SAndroid Build Coastguard Worker static int
dlGetObjectName(Qp0l_QSYS_Info_t * qsysinfo,const char * dir,int dirlen,const char * link)488*7c568831SAndroid Build Coastguard Worker dlGetObjectName(Qp0l_QSYS_Info_t * qsysinfo, const char * dir,
489*7c568831SAndroid Build Coastguard Worker int dirlen, const char * link)
490*7c568831SAndroid Build Coastguard Worker
491*7c568831SAndroid Build Coastguard Worker {
492*7c568831SAndroid Build Coastguard Worker int n;
493*7c568831SAndroid Build Coastguard Worker char * namebuf;
494*7c568831SAndroid Build Coastguard Worker Qlg_Path_Name_T * qptp;
495*7c568831SAndroid Build Coastguard Worker char pathbuf[sizeof(Qlg_Path_Name_T) + _QP0L_DIR_NAME_LG + 4];
496*7c568831SAndroid Build Coastguard Worker Qus_EC_t errinfo;
497*7c568831SAndroid Build Coastguard Worker struct stat sbuf;
498*7c568831SAndroid Build Coastguard Worker
499*7c568831SAndroid Build Coastguard Worker /**
500*7c568831SAndroid Build Coastguard Worker *** Get QSYS object library/name/member and type corresponding to
501*7c568831SAndroid Build Coastguard Worker *** the symbolic `link' in directory `dir'.
502*7c568831SAndroid Build Coastguard Worker **/
503*7c568831SAndroid Build Coastguard Worker
504*7c568831SAndroid Build Coastguard Worker if (!qsysinfo) {
505*7c568831SAndroid Build Coastguard Worker errno = EFAULT;
506*7c568831SAndroid Build Coastguard Worker return -1;
507*7c568831SAndroid Build Coastguard Worker }
508*7c568831SAndroid Build Coastguard Worker
509*7c568831SAndroid Build Coastguard Worker if (!dir && !link) {
510*7c568831SAndroid Build Coastguard Worker errno = EINVAL;
511*7c568831SAndroid Build Coastguard Worker return -1;
512*7c568831SAndroid Build Coastguard Worker }
513*7c568831SAndroid Build Coastguard Worker
514*7c568831SAndroid Build Coastguard Worker qptp = (Qlg_Path_Name_T *) pathbuf;
515*7c568831SAndroid Build Coastguard Worker namebuf = pathbuf + sizeof(Qlg_Path_Name_T);
516*7c568831SAndroid Build Coastguard Worker n = 0;
517*7c568831SAndroid Build Coastguard Worker
518*7c568831SAndroid Build Coastguard Worker /**
519*7c568831SAndroid Build Coastguard Worker *** Build full path.
520*7c568831SAndroid Build Coastguard Worker **/
521*7c568831SAndroid Build Coastguard Worker
522*7c568831SAndroid Build Coastguard Worker if (dir) {
523*7c568831SAndroid Build Coastguard Worker if (dirlen < 0 || dirlen > _QP0L_DIR_NAME_LG + 4)
524*7c568831SAndroid Build Coastguard Worker dirlen = _QP0L_DIR_NAME_LG + 4;
525*7c568831SAndroid Build Coastguard Worker
526*7c568831SAndroid Build Coastguard Worker while (*dir && n < dirlen)
527*7c568831SAndroid Build Coastguard Worker namebuf[n++] = *dir++;
528*7c568831SAndroid Build Coastguard Worker }
529*7c568831SAndroid Build Coastguard Worker
530*7c568831SAndroid Build Coastguard Worker if (n && namebuf[n - 1] == '/')
531*7c568831SAndroid Build Coastguard Worker n--;
532*7c568831SAndroid Build Coastguard Worker
533*7c568831SAndroid Build Coastguard Worker if (link) {
534*7c568831SAndroid Build Coastguard Worker if (*link && *link != '/' && n < _QP0L_DIR_NAME_LG + 4)
535*7c568831SAndroid Build Coastguard Worker namebuf[n++] = '/';
536*7c568831SAndroid Build Coastguard Worker
537*7c568831SAndroid Build Coastguard Worker while (*link && n < _QP0L_DIR_NAME_LG + 4)
538*7c568831SAndroid Build Coastguard Worker namebuf[n++] = *link++;
539*7c568831SAndroid Build Coastguard Worker }
540*7c568831SAndroid Build Coastguard Worker
541*7c568831SAndroid Build Coastguard Worker if (!n || n > _QP0L_DIR_NAME_LG) {
542*7c568831SAndroid Build Coastguard Worker errno = ENAMETOOLONG;
543*7c568831SAndroid Build Coastguard Worker return -1;
544*7c568831SAndroid Build Coastguard Worker }
545*7c568831SAndroid Build Coastguard Worker
546*7c568831SAndroid Build Coastguard Worker namebuf[n] = '\0';
547*7c568831SAndroid Build Coastguard Worker n = dlresolveLink(namebuf, namebuf, _QP0L_DIR_NAME_LG + 1);
548*7c568831SAndroid Build Coastguard Worker
549*7c568831SAndroid Build Coastguard Worker if (n == -1)
550*7c568831SAndroid Build Coastguard Worker return -1;
551*7c568831SAndroid Build Coastguard Worker
552*7c568831SAndroid Build Coastguard Worker if (stat(namebuf, &sbuf))
553*7c568831SAndroid Build Coastguard Worker return -1;
554*7c568831SAndroid Build Coastguard Worker
555*7c568831SAndroid Build Coastguard Worker memset((char *) qptp, 0, sizeof *qptp);
556*7c568831SAndroid Build Coastguard Worker qptp->Path_Length = n;
557*7c568831SAndroid Build Coastguard Worker qptp->Path_Name_Delimiter[0] = '/';
558*7c568831SAndroid Build Coastguard Worker errinfo.Bytes_Provided = sizeof errinfo;
559*7c568831SAndroid Build Coastguard Worker Qp0lCvtPathToQSYSObjName(qptp, qsysinfo, "QSYS0100", sizeof *qsysinfo,
560*7c568831SAndroid Build Coastguard Worker 0, &errinfo);
561*7c568831SAndroid Build Coastguard Worker return errinfo.Bytes_Available? -1: 0;
562*7c568831SAndroid Build Coastguard Worker }
563*7c568831SAndroid Build Coastguard Worker
564*7c568831SAndroid Build Coastguard Worker
565*7c568831SAndroid Build Coastguard Worker static const char *
getcomponent(char * dst,const char * src)566*7c568831SAndroid Build Coastguard Worker getcomponent(char * dst, const char * src)
567*7c568831SAndroid Build Coastguard Worker
568*7c568831SAndroid Build Coastguard Worker {
569*7c568831SAndroid Build Coastguard Worker int i;
570*7c568831SAndroid Build Coastguard Worker
571*7c568831SAndroid Build Coastguard Worker /**
572*7c568831SAndroid Build Coastguard Worker *** Get a path component of at most 10 characters and
573*7c568831SAndroid Build Coastguard Worker *** map it to upper case.
574*7c568831SAndroid Build Coastguard Worker *** Return the address of the next delimiter in source.
575*7c568831SAndroid Build Coastguard Worker **/
576*7c568831SAndroid Build Coastguard Worker
577*7c568831SAndroid Build Coastguard Worker for (i = 0;; src++) {
578*7c568831SAndroid Build Coastguard Worker if (!*src || *src == ' ' || *src == '/') {
579*7c568831SAndroid Build Coastguard Worker *dst = '\0';
580*7c568831SAndroid Build Coastguard Worker return src;
581*7c568831SAndroid Build Coastguard Worker }
582*7c568831SAndroid Build Coastguard Worker
583*7c568831SAndroid Build Coastguard Worker if (i < 10) {
584*7c568831SAndroid Build Coastguard Worker *dst++ = toupper(*src);
585*7c568831SAndroid Build Coastguard Worker i++;
586*7c568831SAndroid Build Coastguard Worker }
587*7c568831SAndroid Build Coastguard Worker }
588*7c568831SAndroid Build Coastguard Worker }
589*7c568831SAndroid Build Coastguard Worker
590*7c568831SAndroid Build Coastguard Worker
591*7c568831SAndroid Build Coastguard Worker static int
dlpath2QSYS(Qp0l_QSYS_Info_t * qsysinfo,const char * path,const char * dftlib)592*7c568831SAndroid Build Coastguard Worker dlpath2QSYS(Qp0l_QSYS_Info_t * qsysinfo, const char * path, const char * dftlib)
593*7c568831SAndroid Build Coastguard Worker
594*7c568831SAndroid Build Coastguard Worker {
595*7c568831SAndroid Build Coastguard Worker unsigned int flags;
596*7c568831SAndroid Build Coastguard Worker char * cp;
597*7c568831SAndroid Build Coastguard Worker
598*7c568831SAndroid Build Coastguard Worker /**
599*7c568831SAndroid Build Coastguard Worker *** Convert the given path to a QSYS object name.
600*7c568831SAndroid Build Coastguard Worker *** Syntax rules for paths are:
601*7c568831SAndroid Build Coastguard Worker ***
602*7c568831SAndroid Build Coastguard Worker *** '/'+ [ <library> [ '/'+ <file> [ '/'+ <member> ] ] '/'* ]
603*7c568831SAndroid Build Coastguard Worker *** <library> '/'+ <file> [ '/'+ <member> ] '/'*
604*7c568831SAndroid Build Coastguard Worker *** <file> '/'*
605*7c568831SAndroid Build Coastguard Worker ***
606*7c568831SAndroid Build Coastguard Worker *** If default library is not given, *LIBL is assumed.
607*7c568831SAndroid Build Coastguard Worker *** Components may no contain spaces. They are translated to
608*7c568831SAndroid Build Coastguard Worker *** uppercase. Only the first 10 characters are significant.
609*7c568831SAndroid Build Coastguard Worker *** There is no check for the validity of the given components and
610*7c568831SAndroid Build Coastguard Worker *** for the object existence.
611*7c568831SAndroid Build Coastguard Worker *** Component types are not in the path, but generated internally.
612*7c568831SAndroid Build Coastguard Worker *** CCSID is not processed.
613*7c568831SAndroid Build Coastguard Worker ***
614*7c568831SAndroid Build Coastguard Worker *** Return 0 upon success, else -1.
615*7c568831SAndroid Build Coastguard Worker **/
616*7c568831SAndroid Build Coastguard Worker
617*7c568831SAndroid Build Coastguard Worker if (!qsysinfo || !path) {
618*7c568831SAndroid Build Coastguard Worker errno = EFAULT;
619*7c568831SAndroid Build Coastguard Worker return -1;
620*7c568831SAndroid Build Coastguard Worker }
621*7c568831SAndroid Build Coastguard Worker
622*7c568831SAndroid Build Coastguard Worker /**
623*7c568831SAndroid Build Coastguard Worker *** Strip leading spaces.
624*7c568831SAndroid Build Coastguard Worker **/
625*7c568831SAndroid Build Coastguard Worker
626*7c568831SAndroid Build Coastguard Worker while (*path == ' ')
627*7c568831SAndroid Build Coastguard Worker path++;
628*7c568831SAndroid Build Coastguard Worker
629*7c568831SAndroid Build Coastguard Worker /**
630*7c568831SAndroid Build Coastguard Worker *** Check for null path.
631*7c568831SAndroid Build Coastguard Worker **/
632*7c568831SAndroid Build Coastguard Worker
633*7c568831SAndroid Build Coastguard Worker if (!*path) {
634*7c568831SAndroid Build Coastguard Worker errno = EINVAL;
635*7c568831SAndroid Build Coastguard Worker return -1;
636*7c568831SAndroid Build Coastguard Worker }
637*7c568831SAndroid Build Coastguard Worker
638*7c568831SAndroid Build Coastguard Worker /**
639*7c568831SAndroid Build Coastguard Worker *** Preset the result structure.
640*7c568831SAndroid Build Coastguard Worker **/
641*7c568831SAndroid Build Coastguard Worker
642*7c568831SAndroid Build Coastguard Worker memset((char *) qsysinfo, 0, sizeof *qsysinfo);
643*7c568831SAndroid Build Coastguard Worker
644*7c568831SAndroid Build Coastguard Worker /**
645*7c568831SAndroid Build Coastguard Worker *** Determine the format.
646*7c568831SAndroid Build Coastguard Worker **/
647*7c568831SAndroid Build Coastguard Worker
648*7c568831SAndroid Build Coastguard Worker if (*path == '/') {
649*7c568831SAndroid Build Coastguard Worker /**
650*7c568831SAndroid Build Coastguard Worker *** Library component present.
651*7c568831SAndroid Build Coastguard Worker **/
652*7c568831SAndroid Build Coastguard Worker
653*7c568831SAndroid Build Coastguard Worker while (*++path == '/')
654*7c568831SAndroid Build Coastguard Worker ;
655*7c568831SAndroid Build Coastguard Worker
656*7c568831SAndroid Build Coastguard Worker if (!*path || *path == ' ')
657*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Lib_Name, "QSYS");
658*7c568831SAndroid Build Coastguard Worker else
659*7c568831SAndroid Build Coastguard Worker path = getcomponent(qsysinfo->Lib_Name, path);
660*7c568831SAndroid Build Coastguard Worker
661*7c568831SAndroid Build Coastguard Worker /**
662*7c568831SAndroid Build Coastguard Worker *** Check for file component and get it.
663*7c568831SAndroid Build Coastguard Worker **/
664*7c568831SAndroid Build Coastguard Worker
665*7c568831SAndroid Build Coastguard Worker if (*path == '/') {
666*7c568831SAndroid Build Coastguard Worker while (*++path == '/')
667*7c568831SAndroid Build Coastguard Worker ;
668*7c568831SAndroid Build Coastguard Worker
669*7c568831SAndroid Build Coastguard Worker if (*path && *path != ' ')
670*7c568831SAndroid Build Coastguard Worker path = getcomponent(qsysinfo->Obj_Name, path);
671*7c568831SAndroid Build Coastguard Worker }
672*7c568831SAndroid Build Coastguard Worker }
673*7c568831SAndroid Build Coastguard Worker else {
674*7c568831SAndroid Build Coastguard Worker /**
675*7c568831SAndroid Build Coastguard Worker *** The mandatory component is the <file>.
676*7c568831SAndroid Build Coastguard Worker **/
677*7c568831SAndroid Build Coastguard Worker
678*7c568831SAndroid Build Coastguard Worker path = getcomponent(qsysinfo->Obj_Name, path);
679*7c568831SAndroid Build Coastguard Worker
680*7c568831SAndroid Build Coastguard Worker while (*path == '/')
681*7c568831SAndroid Build Coastguard Worker path++;
682*7c568831SAndroid Build Coastguard Worker
683*7c568831SAndroid Build Coastguard Worker /**
684*7c568831SAndroid Build Coastguard Worker *** If there is a second component, move the first to
685*7c568831SAndroid Build Coastguard Worker *** the library name and parse the file name.
686*7c568831SAndroid Build Coastguard Worker **/
687*7c568831SAndroid Build Coastguard Worker
688*7c568831SAndroid Build Coastguard Worker if (*path && *path != ' ') {
689*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Lib_Name, qsysinfo->Obj_Name);
690*7c568831SAndroid Build Coastguard Worker memset(qsysinfo->Obj_Name, 0,
691*7c568831SAndroid Build Coastguard Worker sizeof qsysinfo->Obj_Name);
692*7c568831SAndroid Build Coastguard Worker path = getcomponent(qsysinfo->Obj_Name, path);
693*7c568831SAndroid Build Coastguard Worker }
694*7c568831SAndroid Build Coastguard Worker else
695*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Lib_Name, dftlib? dftlib: "*LIBL");
696*7c568831SAndroid Build Coastguard Worker }
697*7c568831SAndroid Build Coastguard Worker
698*7c568831SAndroid Build Coastguard Worker /**
699*7c568831SAndroid Build Coastguard Worker *** Check and set-up member.
700*7c568831SAndroid Build Coastguard Worker **/
701*7c568831SAndroid Build Coastguard Worker
702*7c568831SAndroid Build Coastguard Worker while (*path == '/')
703*7c568831SAndroid Build Coastguard Worker path++;
704*7c568831SAndroid Build Coastguard Worker
705*7c568831SAndroid Build Coastguard Worker if (*path && *path != ' ') {
706*7c568831SAndroid Build Coastguard Worker path = getcomponent(qsysinfo->Mbr_Name, path);
707*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Mbr_Type, "*MBR");
708*7c568831SAndroid Build Coastguard Worker
709*7c568831SAndroid Build Coastguard Worker while (*path == '/')
710*7c568831SAndroid Build Coastguard Worker path++;
711*7c568831SAndroid Build Coastguard Worker }
712*7c568831SAndroid Build Coastguard Worker
713*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Lib_Type, "*LIB");
714*7c568831SAndroid Build Coastguard Worker
715*7c568831SAndroid Build Coastguard Worker if (qsysinfo->Obj_Name[0])
716*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Obj_Type, "*FILE");
717*7c568831SAndroid Build Coastguard Worker
718*7c568831SAndroid Build Coastguard Worker qsysinfo->Bytes_Returned = sizeof *qsysinfo;
719*7c568831SAndroid Build Coastguard Worker qsysinfo->Bytes_Available = sizeof *qsysinfo;
720*7c568831SAndroid Build Coastguard Worker
721*7c568831SAndroid Build Coastguard Worker /**
722*7c568831SAndroid Build Coastguard Worker *** Strip trailing spaces.
723*7c568831SAndroid Build Coastguard Worker **/
724*7c568831SAndroid Build Coastguard Worker
725*7c568831SAndroid Build Coastguard Worker while (*path == ' ')
726*7c568831SAndroid Build Coastguard Worker path++;
727*7c568831SAndroid Build Coastguard Worker
728*7c568831SAndroid Build Coastguard Worker if (*path) {
729*7c568831SAndroid Build Coastguard Worker errno = EINVAL;
730*7c568831SAndroid Build Coastguard Worker return -1;
731*7c568831SAndroid Build Coastguard Worker }
732*7c568831SAndroid Build Coastguard Worker
733*7c568831SAndroid Build Coastguard Worker return 0;
734*7c568831SAndroid Build Coastguard Worker }
735*7c568831SAndroid Build Coastguard Worker
736*7c568831SAndroid Build Coastguard Worker
737*7c568831SAndroid Build Coastguard Worker static int
dl_ifs_link(Qp0l_QSYS_Info_t * qsysinfo,const char * pathname)738*7c568831SAndroid Build Coastguard Worker dl_ifs_link(Qp0l_QSYS_Info_t * qsysinfo, const char * pathname)
739*7c568831SAndroid Build Coastguard Worker
740*7c568831SAndroid Build Coastguard Worker {
741*7c568831SAndroid Build Coastguard Worker /**
742*7c568831SAndroid Build Coastguard Worker *** If `pathname' is a link found in IFS, set `qsysinfo' to its
743*7c568831SAndroid Build Coastguard Worker *** DB2 name.
744*7c568831SAndroid Build Coastguard Worker *** Return 0 if OK, else -1.
745*7c568831SAndroid Build Coastguard Worker **/
746*7c568831SAndroid Build Coastguard Worker
747*7c568831SAndroid Build Coastguard Worker return dlGetObjectName(qsysinfo, (const char *) NULL, 0, pathname);
748*7c568831SAndroid Build Coastguard Worker }
749*7c568831SAndroid Build Coastguard Worker
750*7c568831SAndroid Build Coastguard Worker
751*7c568831SAndroid Build Coastguard Worker static int
dl_path_link(Qp0l_QSYS_Info_t * qsysinfo,const char * pathvar,const char * filename,int (* testproc)(const Qp0l_QSYS_Info_t *))752*7c568831SAndroid Build Coastguard Worker dl_path_link(Qp0l_QSYS_Info_t * qsysinfo, const char * pathvar,
753*7c568831SAndroid Build Coastguard Worker const char * filename, int (* testproc)(const Qp0l_QSYS_Info_t *))
754*7c568831SAndroid Build Coastguard Worker
755*7c568831SAndroid Build Coastguard Worker {
756*7c568831SAndroid Build Coastguard Worker const char * p;
757*7c568831SAndroid Build Coastguard Worker const char * q;
758*7c568831SAndroid Build Coastguard Worker unsigned int i;
759*7c568831SAndroid Build Coastguard Worker const char * path;
760*7c568831SAndroid Build Coastguard Worker
761*7c568831SAndroid Build Coastguard Worker /**
762*7c568831SAndroid Build Coastguard Worker *** If `filename' is not a path and is a link found in one of the
763*7c568831SAndroid Build Coastguard Worker *** colon-separated paths in environment variable `pathvar',
764*7c568831SAndroid Build Coastguard Worker *** set `qsysinfo' to its DB2 name.
765*7c568831SAndroid Build Coastguard Worker *** Return 0 if OK, else -1.
766*7c568831SAndroid Build Coastguard Worker **/
767*7c568831SAndroid Build Coastguard Worker
768*7c568831SAndroid Build Coastguard Worker i = _QP0L_DIR_NAME_LG;
769*7c568831SAndroid Build Coastguard Worker
770*7c568831SAndroid Build Coastguard Worker for (p = filename; *p; p++)
771*7c568831SAndroid Build Coastguard Worker if (*p == '/' || !--i)
772*7c568831SAndroid Build Coastguard Worker return -1; /* Too long or a path. */
773*7c568831SAndroid Build Coastguard Worker
774*7c568831SAndroid Build Coastguard Worker /**
775*7c568831SAndroid Build Coastguard Worker *** Make sure we have the LD_LIBRARY_PATH environment
776*7c568831SAndroid Build Coastguard Worker *** variable value.
777*7c568831SAndroid Build Coastguard Worker **/
778*7c568831SAndroid Build Coastguard Worker
779*7c568831SAndroid Build Coastguard Worker path = getenv(pathvar);
780*7c568831SAndroid Build Coastguard Worker
781*7c568831SAndroid Build Coastguard Worker if (!path)
782*7c568831SAndroid Build Coastguard Worker return -1; /* No path list. */
783*7c568831SAndroid Build Coastguard Worker
784*7c568831SAndroid Build Coastguard Worker /**
785*7c568831SAndroid Build Coastguard Worker *** Try in each path listed.
786*7c568831SAndroid Build Coastguard Worker **/
787*7c568831SAndroid Build Coastguard Worker
788*7c568831SAndroid Build Coastguard Worker q = path;
789*7c568831SAndroid Build Coastguard Worker
790*7c568831SAndroid Build Coastguard Worker if (!*q)
791*7c568831SAndroid Build Coastguard Worker return -1; /* No path list. */
792*7c568831SAndroid Build Coastguard Worker
793*7c568831SAndroid Build Coastguard Worker for (;;) {
794*7c568831SAndroid Build Coastguard Worker for (p = q; *p && *p != ':'; p++)
795*7c568831SAndroid Build Coastguard Worker ;
796*7c568831SAndroid Build Coastguard Worker
797*7c568831SAndroid Build Coastguard Worker if (p > q) /* Ignore null path. */
798*7c568831SAndroid Build Coastguard Worker if (!dlGetObjectName(qsysinfo, q, p - q, filename))
799*7c568831SAndroid Build Coastguard Worker if (!testproc || (*testproc)(qsysinfo))
800*7c568831SAndroid Build Coastguard Worker return 0; /* Found: return. */
801*7c568831SAndroid Build Coastguard Worker
802*7c568831SAndroid Build Coastguard Worker if (!*p)
803*7c568831SAndroid Build Coastguard Worker break;
804*7c568831SAndroid Build Coastguard Worker
805*7c568831SAndroid Build Coastguard Worker q = p + 1;
806*7c568831SAndroid Build Coastguard Worker }
807*7c568831SAndroid Build Coastguard Worker
808*7c568831SAndroid Build Coastguard Worker errno = ENOENT;
809*7c568831SAndroid Build Coastguard Worker return -1;
810*7c568831SAndroid Build Coastguard Worker }
811*7c568831SAndroid Build Coastguard Worker
812*7c568831SAndroid Build Coastguard Worker
813*7c568831SAndroid Build Coastguard Worker static int
dl_DB2_path(Qp0l_QSYS_Info_t * qsysinfo,const char * pathname)814*7c568831SAndroid Build Coastguard Worker dl_DB2_path(Qp0l_QSYS_Info_t * qsysinfo, const char * pathname)
815*7c568831SAndroid Build Coastguard Worker
816*7c568831SAndroid Build Coastguard Worker {
817*7c568831SAndroid Build Coastguard Worker if (dlpath2QSYS(qsysinfo, pathname, (const char *) NULL))
818*7c568831SAndroid Build Coastguard Worker return -1;
819*7c568831SAndroid Build Coastguard Worker
820*7c568831SAndroid Build Coastguard Worker if (qsysinfo->Mbr_Type[0])
821*7c568831SAndroid Build Coastguard Worker return -1; /* Service program may not have members. */
822*7c568831SAndroid Build Coastguard Worker
823*7c568831SAndroid Build Coastguard Worker if (!qsysinfo->Obj_Type[0])
824*7c568831SAndroid Build Coastguard Worker return -1; /* Object must be specified. */
825*7c568831SAndroid Build Coastguard Worker
826*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Obj_Type, "*SRVPGM"); /* Set our object type. */
827*7c568831SAndroid Build Coastguard Worker return 0;
828*7c568831SAndroid Build Coastguard Worker }
829*7c568831SAndroid Build Coastguard Worker
830*7c568831SAndroid Build Coastguard Worker
831*7c568831SAndroid Build Coastguard Worker static int
dl_DB2_name(char * dst,const char * name)832*7c568831SAndroid Build Coastguard Worker dl_DB2_name(char * dst, const char * name)
833*7c568831SAndroid Build Coastguard Worker
834*7c568831SAndroid Build Coastguard Worker {
835*7c568831SAndroid Build Coastguard Worker int i;
836*7c568831SAndroid Build Coastguard Worker
837*7c568831SAndroid Build Coastguard Worker for (i = 0; i < 10; i++) {
838*7c568831SAndroid Build Coastguard Worker switch (*name) {
839*7c568831SAndroid Build Coastguard Worker
840*7c568831SAndroid Build Coastguard Worker default:
841*7c568831SAndroid Build Coastguard Worker if (!islower(*name))
842*7c568831SAndroid Build Coastguard Worker break;
843*7c568831SAndroid Build Coastguard Worker
844*7c568831SAndroid Build Coastguard Worker case '\0':
845*7c568831SAndroid Build Coastguard Worker case '/':
846*7c568831SAndroid Build Coastguard Worker case ' ':
847*7c568831SAndroid Build Coastguard Worker return -1;
848*7c568831SAndroid Build Coastguard Worker }
849*7c568831SAndroid Build Coastguard Worker
850*7c568831SAndroid Build Coastguard Worker *dst++ = *name++;
851*7c568831SAndroid Build Coastguard Worker }
852*7c568831SAndroid Build Coastguard Worker
853*7c568831SAndroid Build Coastguard Worker if (!i)
854*7c568831SAndroid Build Coastguard Worker return -1;
855*7c568831SAndroid Build Coastguard Worker
856*7c568831SAndroid Build Coastguard Worker *dst = '\0';
857*7c568831SAndroid Build Coastguard Worker return 0;
858*7c568831SAndroid Build Coastguard Worker }
859*7c568831SAndroid Build Coastguard Worker
860*7c568831SAndroid Build Coastguard Worker
861*7c568831SAndroid Build Coastguard Worker static int
dl_qualified_object(Qp0l_QSYS_Info_t * qsysinfo,const char * pathname)862*7c568831SAndroid Build Coastguard Worker dl_qualified_object(Qp0l_QSYS_Info_t * qsysinfo, const char * pathname)
863*7c568831SAndroid Build Coastguard Worker
864*7c568831SAndroid Build Coastguard Worker {
865*7c568831SAndroid Build Coastguard Worker memset((char *) qsysinfo, 0, sizeof *qsysinfo);
866*7c568831SAndroid Build Coastguard Worker
867*7c568831SAndroid Build Coastguard Worker if (dl_DB2_name(qsysinfo->Obj_Name, pathname) ||
868*7c568831SAndroid Build Coastguard Worker dl_DB2_name(qsysinfo->Lib_Name, pathname + 10))
869*7c568831SAndroid Build Coastguard Worker return -1;
870*7c568831SAndroid Build Coastguard Worker
871*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Lib_Type, "*LIB");
872*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Obj_Type, "*SRVPGM");
873*7c568831SAndroid Build Coastguard Worker return 0;
874*7c568831SAndroid Build Coastguard Worker }
875*7c568831SAndroid Build Coastguard Worker
876*7c568831SAndroid Build Coastguard Worker
877*7c568831SAndroid Build Coastguard Worker static int
dl_lib_object(Qp0l_QSYS_Info_t * qsysinfo,const char * libname,const char * pathname)878*7c568831SAndroid Build Coastguard Worker dl_lib_object(Qp0l_QSYS_Info_t * qsysinfo,
879*7c568831SAndroid Build Coastguard Worker const char * libname, const char * pathname)
880*7c568831SAndroid Build Coastguard Worker
881*7c568831SAndroid Build Coastguard Worker {
882*7c568831SAndroid Build Coastguard Worker int i;
883*7c568831SAndroid Build Coastguard Worker char * cp;
884*7c568831SAndroid Build Coastguard Worker
885*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Lib_Name, libname);
886*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Lib_Type, "*LIB");
887*7c568831SAndroid Build Coastguard Worker strcpy(qsysinfo->Obj_Type, "*SRVPGM");
888*7c568831SAndroid Build Coastguard Worker cp = qsysinfo->Obj_Name;
889*7c568831SAndroid Build Coastguard Worker
890*7c568831SAndroid Build Coastguard Worker while (*pathname == ' ')
891*7c568831SAndroid Build Coastguard Worker pathname++;
892*7c568831SAndroid Build Coastguard Worker
893*7c568831SAndroid Build Coastguard Worker for (i = 0;; pathname++) {
894*7c568831SAndroid Build Coastguard Worker switch (*pathname) {
895*7c568831SAndroid Build Coastguard Worker
896*7c568831SAndroid Build Coastguard Worker case '\0':
897*7c568831SAndroid Build Coastguard Worker case ' ':
898*7c568831SAndroid Build Coastguard Worker break;
899*7c568831SAndroid Build Coastguard Worker
900*7c568831SAndroid Build Coastguard Worker case '/':
901*7c568831SAndroid Build Coastguard Worker return -1;
902*7c568831SAndroid Build Coastguard Worker
903*7c568831SAndroid Build Coastguard Worker default:
904*7c568831SAndroid Build Coastguard Worker if (i < 10)
905*7c568831SAndroid Build Coastguard Worker *cp++ = toupper(*pathname);
906*7c568831SAndroid Build Coastguard Worker
907*7c568831SAndroid Build Coastguard Worker i++;
908*7c568831SAndroid Build Coastguard Worker continue;
909*7c568831SAndroid Build Coastguard Worker }
910*7c568831SAndroid Build Coastguard Worker
911*7c568831SAndroid Build Coastguard Worker break;
912*7c568831SAndroid Build Coastguard Worker }
913*7c568831SAndroid Build Coastguard Worker
914*7c568831SAndroid Build Coastguard Worker while (*pathname == ' ')
915*7c568831SAndroid Build Coastguard Worker pathname++;
916*7c568831SAndroid Build Coastguard Worker
917*7c568831SAndroid Build Coastguard Worker if (!i || *pathname)
918*7c568831SAndroid Build Coastguard Worker return -1;
919*7c568831SAndroid Build Coastguard Worker
920*7c568831SAndroid Build Coastguard Worker *cp = '\0';
921*7c568831SAndroid Build Coastguard Worker return 0;
922*7c568831SAndroid Build Coastguard Worker }
923*7c568831SAndroid Build Coastguard Worker
924*7c568831SAndroid Build Coastguard Worker
925*7c568831SAndroid Build Coastguard Worker static int
dl_is_srvpgm(const Qp0l_QSYS_Info_t * qsysinfo)926*7c568831SAndroid Build Coastguard Worker dl_is_srvpgm(const Qp0l_QSYS_Info_t * qsysinfo)
927*7c568831SAndroid Build Coastguard Worker
928*7c568831SAndroid Build Coastguard Worker {
929*7c568831SAndroid Build Coastguard Worker struct stat sbuf;
930*7c568831SAndroid Build Coastguard Worker char namebuf[100];
931*7c568831SAndroid Build Coastguard Worker
932*7c568831SAndroid Build Coastguard Worker if (!qsysinfo->Lib_Name[0] || strcmp(qsysinfo->Lib_Type, "*LIB") ||
933*7c568831SAndroid Build Coastguard Worker !qsysinfo->Obj_Name[0] || strcmp(qsysinfo->Obj_Type, "*SRVPGM") ||
934*7c568831SAndroid Build Coastguard Worker qsysinfo->Mbr_Name[0] || qsysinfo->Mbr_Type[0])
935*7c568831SAndroid Build Coastguard Worker return 0;
936*7c568831SAndroid Build Coastguard Worker
937*7c568831SAndroid Build Coastguard Worker /**
938*7c568831SAndroid Build Coastguard Worker *** Build the IFS path name for the DB2 object.
939*7c568831SAndroid Build Coastguard Worker **/
940*7c568831SAndroid Build Coastguard Worker
941*7c568831SAndroid Build Coastguard Worker sprintf(namebuf, "%s/%s.LIB/%s.SRVPGM",
942*7c568831SAndroid Build Coastguard Worker strcmp(qsysinfo->Lib_Name, "QSYS")? "/QSYS.LIB": "",
943*7c568831SAndroid Build Coastguard Worker qsysinfo->Lib_Name, qsysinfo->Obj_Name);
944*7c568831SAndroid Build Coastguard Worker
945*7c568831SAndroid Build Coastguard Worker return stat(namebuf, &sbuf) == 0;
946*7c568831SAndroid Build Coastguard Worker }
947*7c568831SAndroid Build Coastguard Worker
948*7c568831SAndroid Build Coastguard Worker
949*7c568831SAndroid Build Coastguard Worker static int
dlreinit(dlinfo * dlip)950*7c568831SAndroid Build Coastguard Worker dlreinit(dlinfo * dlip)
951*7c568831SAndroid Build Coastguard Worker
952*7c568831SAndroid Build Coastguard Worker {
953*7c568831SAndroid Build Coastguard Worker RINZ_TEMPL_T t;
954*7c568831SAndroid Build Coastguard Worker RINZ_TEMPL_T * p;
955*7c568831SAndroid Build Coastguard Worker volatile _INTRPT_Hndlr_Parms_T excbuf;
956*7c568831SAndroid Build Coastguard Worker
957*7c568831SAndroid Build Coastguard Worker if (dlip->actinfo.Flags & QLE_ABP_WAS_ACTIVE)
958*7c568831SAndroid Build Coastguard Worker return 0;
959*7c568831SAndroid Build Coastguard Worker
960*7c568831SAndroid Build Coastguard Worker /**
961*7c568831SAndroid Build Coastguard Worker *** Attempt to reinitialize the service program that was loaded.
962*7c568831SAndroid Build Coastguard Worker *** The service program must be created to allow re-initialization:
963*7c568831SAndroid Build Coastguard Worker *** ALWRINZ(*YES) for this to work. The default is
964*7c568831SAndroid Build Coastguard Worker *** ALWRINZ(*NO).
965*7c568831SAndroid Build Coastguard Worker **/
966*7c568831SAndroid Build Coastguard Worker
967*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(err, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
968*7c568831SAndroid Build Coastguard Worker p = &t;
969*7c568831SAndroid Build Coastguard Worker t.rinz_pgm = dlip->pointer;
970*7c568831SAndroid Build Coastguard Worker t.rinz_agpmk = dlip->actinfo.Act_Grp_Mark;
971*7c568831SAndroid Build Coastguard Worker _RINZSTAT(p);
972*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
973*7c568831SAndroid Build Coastguard Worker
974*7c568831SAndroid Build Coastguard Worker return 0;
975*7c568831SAndroid Build Coastguard Worker
976*7c568831SAndroid Build Coastguard Worker err:
977*7c568831SAndroid Build Coastguard Worker if (!memcmp((char *) excbuf.Msg_Id, "MCH4421", 7))
978*7c568831SAndroid Build Coastguard Worker return 0; /* Program cannot be reinitialized. */
979*7c568831SAndroid Build Coastguard Worker
980*7c568831SAndroid Build Coastguard Worker dlseterror_from_exception(&excbuf);
981*7c568831SAndroid Build Coastguard Worker return -1;
982*7c568831SAndroid Build Coastguard Worker }
983*7c568831SAndroid Build Coastguard Worker
984*7c568831SAndroid Build Coastguard Worker
985*7c568831SAndroid Build Coastguard Worker void *
dlsym(void * handle,const char * symbol)986*7c568831SAndroid Build Coastguard Worker dlsym(void * handle, const char * symbol)
987*7c568831SAndroid Build Coastguard Worker
988*7c568831SAndroid Build Coastguard Worker {
989*7c568831SAndroid Build Coastguard Worker dlinfo * dlip;
990*7c568831SAndroid Build Coastguard Worker void * p;
991*7c568831SAndroid Build Coastguard Worker int export_type;
992*7c568831SAndroid Build Coastguard Worker Qus_EC_t errinfo;
993*7c568831SAndroid Build Coastguard Worker volatile _INTRPT_Hndlr_Parms_T excbuf;
994*7c568831SAndroid Build Coastguard Worker static int zero = 0;
995*7c568831SAndroid Build Coastguard Worker
996*7c568831SAndroid Build Coastguard Worker dlthreadinit();
997*7c568831SAndroid Build Coastguard Worker
998*7c568831SAndroid Build Coastguard Worker if (!handle || !symbol) {
999*7c568831SAndroid Build Coastguard Worker dlseterror_from_errno(EFAULT);
1000*7c568831SAndroid Build Coastguard Worker return (void *) NULL;
1001*7c568831SAndroid Build Coastguard Worker }
1002*7c568831SAndroid Build Coastguard Worker
1003*7c568831SAndroid Build Coastguard Worker dlip = (dlinfo *) handle;
1004*7c568831SAndroid Build Coastguard Worker
1005*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(error, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
1006*7c568831SAndroid Build Coastguard Worker errinfo.Bytes_Provided = 0;
1007*7c568831SAndroid Build Coastguard Worker QleGetExpLong(&dlip->actinfo.Act_Mark, &zero, &zero,
1008*7c568831SAndroid Build Coastguard Worker (char *) symbol, &p, &export_type, &errinfo);
1009*7c568831SAndroid Build Coastguard Worker return p;
1010*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
1011*7c568831SAndroid Build Coastguard Worker
1012*7c568831SAndroid Build Coastguard Worker error:
1013*7c568831SAndroid Build Coastguard Worker dlseterror_from_exception(&excbuf);
1014*7c568831SAndroid Build Coastguard Worker return (void *) NULL;
1015*7c568831SAndroid Build Coastguard Worker }
1016*7c568831SAndroid Build Coastguard Worker
1017*7c568831SAndroid Build Coastguard Worker
1018*7c568831SAndroid Build Coastguard Worker int
dlclose(void * handle)1019*7c568831SAndroid Build Coastguard Worker dlclose(void * handle)
1020*7c568831SAndroid Build Coastguard Worker
1021*7c568831SAndroid Build Coastguard Worker {
1022*7c568831SAndroid Build Coastguard Worker dlinfo * dlip;
1023*7c568831SAndroid Build Coastguard Worker void (* _fini)(void);
1024*7c568831SAndroid Build Coastguard Worker
1025*7c568831SAndroid Build Coastguard Worker dlthreadinit();
1026*7c568831SAndroid Build Coastguard Worker
1027*7c568831SAndroid Build Coastguard Worker if (!handle) {
1028*7c568831SAndroid Build Coastguard Worker dlseterror_from_errno(EFAULT);
1029*7c568831SAndroid Build Coastguard Worker return -1;
1030*7c568831SAndroid Build Coastguard Worker }
1031*7c568831SAndroid Build Coastguard Worker
1032*7c568831SAndroid Build Coastguard Worker dlip = (dlinfo *) handle;
1033*7c568831SAndroid Build Coastguard Worker
1034*7c568831SAndroid Build Coastguard Worker if (dlip->actcount) {
1035*7c568831SAndroid Build Coastguard Worker if (--(dlip->actcount))
1036*7c568831SAndroid Build Coastguard Worker return 0;
1037*7c568831SAndroid Build Coastguard Worker
1038*7c568831SAndroid Build Coastguard Worker if (_fini = dlsym(handle, "_fini"))
1039*7c568831SAndroid Build Coastguard Worker (*_fini)();
1040*7c568831SAndroid Build Coastguard Worker }
1041*7c568831SAndroid Build Coastguard Worker
1042*7c568831SAndroid Build Coastguard Worker return dlreinit(dlip);
1043*7c568831SAndroid Build Coastguard Worker }
1044*7c568831SAndroid Build Coastguard Worker
1045*7c568831SAndroid Build Coastguard Worker
1046*7c568831SAndroid Build Coastguard Worker static void *
dlopenqsys(const Qp0l_QSYS_Info_t * dllinfo)1047*7c568831SAndroid Build Coastguard Worker dlopenqsys(const Qp0l_QSYS_Info_t * dllinfo)
1048*7c568831SAndroid Build Coastguard Worker
1049*7c568831SAndroid Build Coastguard Worker {
1050*7c568831SAndroid Build Coastguard Worker dlinfo * dlip;
1051*7c568831SAndroid Build Coastguard Worker dlinfo * dlip2;
1052*7c568831SAndroid Build Coastguard Worker void (* _init)(void);
1053*7c568831SAndroid Build Coastguard Worker unsigned int i;
1054*7c568831SAndroid Build Coastguard Worker _SYSPTR pgmptr;
1055*7c568831SAndroid Build Coastguard Worker unsigned long long actmark;
1056*7c568831SAndroid Build Coastguard Worker Qus_EC_t errinfo;
1057*7c568831SAndroid Build Coastguard Worker char actmarkstr[2 * sizeof actmark + 1];
1058*7c568831SAndroid Build Coastguard Worker static int actinfo_size = sizeof dlip->actinfo;
1059*7c568831SAndroid Build Coastguard Worker volatile _INTRPT_Hndlr_Parms_T excbuf;
1060*7c568831SAndroid Build Coastguard Worker
1061*7c568831SAndroid Build Coastguard Worker /**
1062*7c568831SAndroid Build Coastguard Worker *** Capture any type of error and if any occurs,
1063*7c568831SAndroid Build Coastguard Worker *** return not found.
1064*7c568831SAndroid Build Coastguard Worker **/
1065*7c568831SAndroid Build Coastguard Worker
1066*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(error1, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
1067*7c568831SAndroid Build Coastguard Worker pgmptr = rslvsp(WLI_SRVPGM, (char *) dllinfo->Obj_Name,
1068*7c568831SAndroid Build Coastguard Worker (char *) dllinfo->Lib_Name ,_AUTH_NONE);
1069*7c568831SAndroid Build Coastguard Worker
1070*7c568831SAndroid Build Coastguard Worker if (!pgmptr) {
1071*7c568831SAndroid Build Coastguard Worker errno = ENOENT;
1072*7c568831SAndroid Build Coastguard Worker return (void *) NULL;
1073*7c568831SAndroid Build Coastguard Worker }
1074*7c568831SAndroid Build Coastguard Worker
1075*7c568831SAndroid Build Coastguard Worker /**
1076*7c568831SAndroid Build Coastguard Worker *** Create a new DLL info block.
1077*7c568831SAndroid Build Coastguard Worker **/
1078*7c568831SAndroid Build Coastguard Worker
1079*7c568831SAndroid Build Coastguard Worker dlip = (dlinfo *) malloc(sizeof *dlip);
1080*7c568831SAndroid Build Coastguard Worker
1081*7c568831SAndroid Build Coastguard Worker if (!dlip)
1082*7c568831SAndroid Build Coastguard Worker return (void *) NULL; /* Cannot create block. */
1083*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
1084*7c568831SAndroid Build Coastguard Worker
1085*7c568831SAndroid Build Coastguard Worker dllock();
1086*7c568831SAndroid Build Coastguard Worker
1087*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(error2, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
1088*7c568831SAndroid Build Coastguard Worker memset((char *) dlip, 0, sizeof *dlip);
1089*7c568831SAndroid Build Coastguard Worker dlip->pointer = pgmptr;
1090*7c568831SAndroid Build Coastguard Worker
1091*7c568831SAndroid Build Coastguard Worker /**
1092*7c568831SAndroid Build Coastguard Worker *** Activate the DLL.
1093*7c568831SAndroid Build Coastguard Worker **/
1094*7c568831SAndroid Build Coastguard Worker
1095*7c568831SAndroid Build Coastguard Worker errinfo.Bytes_Provided = 0;
1096*7c568831SAndroid Build Coastguard Worker QleActBndPgmLong(&pgmptr, &actmark,
1097*7c568831SAndroid Build Coastguard Worker &dlip->actinfo, &actinfo_size, &errinfo);
1098*7c568831SAndroid Build Coastguard Worker dlip->actinfo.Act_Mark = actmark;
1099*7c568831SAndroid Build Coastguard Worker
1100*7c568831SAndroid Build Coastguard Worker /**
1101*7c568831SAndroid Build Coastguard Worker *** Dummy string encoding activation mark to use as hash table key.
1102*7c568831SAndroid Build Coastguard Worker **/
1103*7c568831SAndroid Build Coastguard Worker
1104*7c568831SAndroid Build Coastguard Worker for (i = 0; actmark; actmark >>= 6)
1105*7c568831SAndroid Build Coastguard Worker actmarkstr[i++] = 0x40 + (actmark & 0x3F);
1106*7c568831SAndroid Build Coastguard Worker
1107*7c568831SAndroid Build Coastguard Worker actmarkstr[i] = '\0';
1108*7c568831SAndroid Build Coastguard Worker
1109*7c568831SAndroid Build Coastguard Worker /**
1110*7c568831SAndroid Build Coastguard Worker *** Check if already activated.
1111*7c568831SAndroid Build Coastguard Worker **/
1112*7c568831SAndroid Build Coastguard Worker
1113*7c568831SAndroid Build Coastguard Worker dlip2 = (dlinfo *) xmlHashLookup(dldir, actmarkstr);
1114*7c568831SAndroid Build Coastguard Worker
1115*7c568831SAndroid Build Coastguard Worker if (dlip2) {
1116*7c568831SAndroid Build Coastguard Worker free((char *) dlip);
1117*7c568831SAndroid Build Coastguard Worker dlip = dlip2;
1118*7c568831SAndroid Build Coastguard Worker }
1119*7c568831SAndroid Build Coastguard Worker else if (xmlHashAddEntry(dldir, (const xmlChar *) actmarkstr, dlip)) {
1120*7c568831SAndroid Build Coastguard Worker dlreinit(dlip);
1121*7c568831SAndroid Build Coastguard Worker free((char *) dlip);
1122*7c568831SAndroid Build Coastguard Worker dlunlock();
1123*7c568831SAndroid Build Coastguard Worker return (void *) NULL;
1124*7c568831SAndroid Build Coastguard Worker }
1125*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
1126*7c568831SAndroid Build Coastguard Worker
1127*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(error2, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
1128*7c568831SAndroid Build Coastguard Worker
1129*7c568831SAndroid Build Coastguard Worker /**
1130*7c568831SAndroid Build Coastguard Worker *** Bump activation counter.
1131*7c568831SAndroid Build Coastguard Worker **/
1132*7c568831SAndroid Build Coastguard Worker
1133*7c568831SAndroid Build Coastguard Worker if (!(dlip->actcount++) && (_init = dlsym(dlip, "_init")))
1134*7c568831SAndroid Build Coastguard Worker (*_init)();
1135*7c568831SAndroid Build Coastguard Worker
1136*7c568831SAndroid Build Coastguard Worker dlunlock();
1137*7c568831SAndroid Build Coastguard Worker
1138*7c568831SAndroid Build Coastguard Worker /**
1139*7c568831SAndroid Build Coastguard Worker *** Return the handle.
1140*7c568831SAndroid Build Coastguard Worker **/
1141*7c568831SAndroid Build Coastguard Worker
1142*7c568831SAndroid Build Coastguard Worker return (void *) dlip;
1143*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
1144*7c568831SAndroid Build Coastguard Worker
1145*7c568831SAndroid Build Coastguard Worker error2:
1146*7c568831SAndroid Build Coastguard Worker free((char *) dlip);
1147*7c568831SAndroid Build Coastguard Worker dlunlock();
1148*7c568831SAndroid Build Coastguard Worker
1149*7c568831SAndroid Build Coastguard Worker error1:
1150*7c568831SAndroid Build Coastguard Worker dlseterror_from_exception(&excbuf);
1151*7c568831SAndroid Build Coastguard Worker return (void *) NULL;
1152*7c568831SAndroid Build Coastguard Worker }
1153*7c568831SAndroid Build Coastguard Worker
1154*7c568831SAndroid Build Coastguard Worker
1155*7c568831SAndroid Build Coastguard Worker void *
dlopen(const char * filename,int flag)1156*7c568831SAndroid Build Coastguard Worker dlopen(const char * filename, int flag)
1157*7c568831SAndroid Build Coastguard Worker
1158*7c568831SAndroid Build Coastguard Worker {
1159*7c568831SAndroid Build Coastguard Worker void * dlhandle;
1160*7c568831SAndroid Build Coastguard Worker int sverrno;
1161*7c568831SAndroid Build Coastguard Worker Qp0l_QSYS_Info_t dllinfo;
1162*7c568831SAndroid Build Coastguard Worker
1163*7c568831SAndroid Build Coastguard Worker sverrno = errno;
1164*7c568831SAndroid Build Coastguard Worker errno = 0;
1165*7c568831SAndroid Build Coastguard Worker
1166*7c568831SAndroid Build Coastguard Worker dlthreadinit();
1167*7c568831SAndroid Build Coastguard Worker
1168*7c568831SAndroid Build Coastguard Worker if (!filename) {
1169*7c568831SAndroid Build Coastguard Worker dlseterror_from_errno(EFAULT);
1170*7c568831SAndroid Build Coastguard Worker errno = sverrno;
1171*7c568831SAndroid Build Coastguard Worker return NULL;
1172*7c568831SAndroid Build Coastguard Worker }
1173*7c568831SAndroid Build Coastguard Worker
1174*7c568831SAndroid Build Coastguard Worker /**
1175*7c568831SAndroid Build Coastguard Worker *** Try to locate the object in the following order:
1176*7c568831SAndroid Build Coastguard Worker *** _ `filename' is an IFS path.
1177*7c568831SAndroid Build Coastguard Worker *** _ `filename' is not a path and resides in one of
1178*7c568831SAndroid Build Coastguard Worker *** LD_LIBRARY_PATH colon-separated paths.
1179*7c568831SAndroid Build Coastguard Worker *** _ `filename' is not a path and resides in one of
1180*7c568831SAndroid Build Coastguard Worker *** PATH colon-separated paths.
1181*7c568831SAndroid Build Coastguard Worker *** _ `filename' is a DB2 path (as /library/object).
1182*7c568831SAndroid Build Coastguard Worker *** _ `filename' is a qualified object name.
1183*7c568831SAndroid Build Coastguard Worker *** _ `filename' is an object in *CURLIB.
1184*7c568831SAndroid Build Coastguard Worker *** _ `filename' is an object in *LIBL.
1185*7c568831SAndroid Build Coastguard Worker **/
1186*7c568831SAndroid Build Coastguard Worker
1187*7c568831SAndroid Build Coastguard Worker if (!dl_ifs_link(&dllinfo, filename) && dl_is_srvpgm(&dllinfo))
1188*7c568831SAndroid Build Coastguard Worker dlhandle = dlopenqsys(&dllinfo);
1189*7c568831SAndroid Build Coastguard Worker else if (!dl_path_link(&dllinfo,
1190*7c568831SAndroid Build Coastguard Worker "LD_LIBRARY_PATH", filename, dl_is_srvpgm))
1191*7c568831SAndroid Build Coastguard Worker dlhandle = dlopenqsys(&dllinfo);
1192*7c568831SAndroid Build Coastguard Worker else if (!dl_path_link(&dllinfo, "PATH", filename, dl_is_srvpgm))
1193*7c568831SAndroid Build Coastguard Worker dlhandle = dlopenqsys(&dllinfo);
1194*7c568831SAndroid Build Coastguard Worker else if (!dl_DB2_path(&dllinfo, filename) && dl_is_srvpgm(&dllinfo))
1195*7c568831SAndroid Build Coastguard Worker dlhandle = dlopenqsys(&dllinfo);
1196*7c568831SAndroid Build Coastguard Worker else if (!dl_qualified_object(&dllinfo, filename) &&
1197*7c568831SAndroid Build Coastguard Worker dl_is_srvpgm(&dllinfo))
1198*7c568831SAndroid Build Coastguard Worker dlhandle = dlopenqsys(&dllinfo);
1199*7c568831SAndroid Build Coastguard Worker else if (!dl_lib_object(&dllinfo, "*CURLIB", filename) &&
1200*7c568831SAndroid Build Coastguard Worker dl_is_srvpgm(&dllinfo))
1201*7c568831SAndroid Build Coastguard Worker dlhandle = dlopenqsys(&dllinfo);
1202*7c568831SAndroid Build Coastguard Worker else if (!dl_lib_object(&dllinfo, "*LIBL", filename) &&
1203*7c568831SAndroid Build Coastguard Worker dl_is_srvpgm(&dllinfo))
1204*7c568831SAndroid Build Coastguard Worker dlhandle = dlopenqsys(&dllinfo);
1205*7c568831SAndroid Build Coastguard Worker else
1206*7c568831SAndroid Build Coastguard Worker dlhandle = NULL;
1207*7c568831SAndroid Build Coastguard Worker
1208*7c568831SAndroid Build Coastguard Worker if (!dlhandle && errno)
1209*7c568831SAndroid Build Coastguard Worker dlseterror_from_errno(errno);
1210*7c568831SAndroid Build Coastguard Worker
1211*7c568831SAndroid Build Coastguard Worker errno = sverrno;
1212*7c568831SAndroid Build Coastguard Worker return dlhandle;
1213*7c568831SAndroid Build Coastguard Worker }
1214