1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
/*-------------------------------------------------------------------------
*
* support.c
* BeOS Support functions
*
* Copyright (c) 1999-2000, Cyril VELTER
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
/* Support Globals */
char* self_binary=NULL;
port_id beos_dl_port_in=0;
port_id beos_dl_port_out=0;
sem_id beos_shm_sem;
image_id beos_dl_open(char * filename)
{
image_id im;
/* Start the support server */
if (self_binary==NULL)
{
/* Can't start support server without binary name */
elog(NOTICE, "Error loading BeOS support server : can't find binary");
return B_ERROR;
}
else
{
/* If a port doesn't exist, lauch support server */
if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
{
/* Create communication port */
beos_dl_port_in=create_port(50,"beos_support_in");
beos_dl_port_out=create_port(50,"beos_support_in");
if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
{
elog(NOTICE, "Error loading BeOS support server : can't create communication ports");
return B_ERROR;
}
else
{
char Cmd[4000];
/* Build arg list */
sprintf(Cmd,"%s -beossupportserver %d %d &",self_binary,(int)beos_dl_port_in,(int)beos_dl_port_out);
/* Lauch process */
system(Cmd);
}
}
}
/* Add-on loading */
/* Send command '1' (load) to the support server */
write_port(beos_dl_port_in,1,filename,strlen(filename)+1);
/* Read Object Id */
read_port(beos_dl_port_out,&im,NULL,0);
/* Checking integrity */
if (im<0)
{
elog(NOTICE, "Can't load this add-on ");
return B_ERROR;
}
else
{
/* Map text and data segment in our address space */
char datas[4000];
int32 area;
int32 resu;
void* add;
/* read text segment id and address */
read_port(beos_dl_port_out,&area,datas,4000);
read_port(beos_dl_port_out,(void*)&add,datas,4000);
/* map text segment in our address space */
resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
if (resu<0)
{
/* If we can't map, we are in reload case */
/* delete the mapping */
resu=delete_area(area_for(add));
/* Remap */
resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
if (resu<0)
{
elog(NOTICE, "Can't load this add-on : map text error");
}
}
/* read text segment id and address */
read_port(beos_dl_port_out,&area,datas,4000);
read_port(beos_dl_port_out,(void*)&add,datas,4000);
/* map text segment in our address space */
resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
if (resu<0)
{
/* If we can't map, we are in reload case */
/* delete the mapping */
resu=delete_area(area_for(add));
/* Remap */
resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
if (resu<0)
{
elog(NOTICE, "Can't load this add-on : map data error");
}
}
return im;
}
}
status_t beos_dl_close(image_id im)
{
/* unload add-on */
int32 resu;
write_port(beos_dl_port_in,2,&im,4);
read_port(beos_dl_port_out,&resu,NULL,0);
return resu;
}
/* Main support server loop */
void beos_startup(int argc,char** argv)
{
if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - 10, "postmaster"))
{
/* Shared memory cloning protection semaphore */
beos_shm_sem=create_sem(1,"beos_shm_sem");
}
if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0)
{
port_id port_in;
port_id port_out;
/* Get back port ids from arglist */
sscanf(argv[2],"%d",(int*)(&port_in));
sscanf(argv[3],"%d",(int*)(&port_out));
/* Main server loop */
for (;;)
{
int32 opcode=0;
char datas[4000];
/* Wait for a message from the backend :
1 : load a shared object
2 : unload a shared object
any other : exit support server */
read_port(port_in,&opcode,datas,4000);
switch(opcode)
{
image_id addon;
image_info info_im;
area_info info_ar;
/* Load Add-On */
case 1 :
/* Load shared object */
addon=load_add_on(datas);
/* send back the shared object Id */
write_port(port_out,addon,NULL,0);
/* Get Shared Object infos */
get_image_info(addon,&info_im);
/* get text segment info */
get_area_info(area_for(info_im.text),&info_ar);
/* Send back area_id of text segment */
write_port(port_out,info_ar.area,info_ar.name,strlen(info_ar.name)+1);
/* Send back real address of text segment */
write_port(port_out,(int)info_ar.address,info_ar.name,strlen(info_ar.name)+1);
/* get data segment info */
get_area_info(area_for(info_im.data),&info_ar);
/* Send back area_id of data segment */
write_port(port_out,info_ar.area,info_ar.name,strlen(info_ar.name)+1);
/* Send back real address of data segment */
write_port(port_out,(int)info_ar.address,info_ar.name,strlen(info_ar.name)+1);
break;
/* UnLoad Add-On */
case 2 :
/* Unload shared object and send back the result of the operation */
write_port(port_out,unload_add_on(*((int*)(datas))),NULL,0);
break;
/* Cleanup and exit */
default:
/* Free system resources */
delete_port(port_in);
delete_port(port_out);
/* Exit */
exit(0);
break;
}
}
/* Never be there */
exit(1);
}
}
void beos_backend_startup(char * binary)
{
team_id ct;
thread_info inft;
char nom[50];
char nvnom[50];
area_info inf;
int32 cook=0;
/* remember full path binary name to load dl*/
self_binary=strdup(binary);
/* find the current team */
get_thread_info(find_thread(NULL),&inft);
ct=inft.team;
/* find all area with a name begining by pgsql and destroy / clone then */
/* This operation must be done by only one backend at a time */
if(acquire_sem(beos_shm_sem)==B_OK)
{
while (get_next_area_info(0, &cook, &inf) == B_OK)
{
strcpy(nom,inf.name);
strcpy(nvnom,inf.name);
nom[9]=0;
nvnom[5]='i';
if (!strcmp(nom,"SYSV_IPC_"))
{
void* add;
area_id ar;
add=inf.address;
delete_area(inf.area);
ar=find_area(inf.name);
clone_area(nvnom,&add,B_CLONE_ADDRESS,B_READ_AREA|B_WRITE_AREA,ar);
}
}
release_sem(beos_shm_sem);
}
else
{
/* Fatal error, exiting with error */
exit(1);
}
}
|