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
|
/*-------------------------------------------------------------------------
*
* shm.c
* BeOS System V Shared Memory Emulation
*
* Copyright (c) 1999-2001, Cyril VELTER
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <OS.h>
#include <errno.h>
/* Emulating SYS shared memory with beos areas. WARNING : fork clone
areas in copy on write mode */
/* Detach from a shared mem area based on its address */
int
shmdt(char *shmaddr)
{
/* Find area id for this address */
area_id s;
s = area_for(shmaddr);
/* Delete area */
return delete_area(s);
}
/* Attach to an existing area */
int *
shmat(int memId, int m1, int m2)
{
/* Get our team id */
thread_info thinfo;
team_info teinfo;
area_info ainfo;
get_thread_info(find_thread(NULL), &thinfo);
get_team_info(thinfo.team, &teinfo);
/* Get area teamid */
if (get_area_info(memId, &ainfo) != B_OK)
printf("AREA %d Invalide\n", memId);
if (ainfo.team == teinfo.team)
{
/*
* the area is already in our address space, just return the address
*/
return (int *) ainfo.address;
}
else
{
/*
* the area is not in our address space, clone it before and return
* the address
*/
area_id narea;
narea = clone_area(ainfo.name, &(ainfo.address), B_CLONE_ADDRESS, B_READ_AREA | B_WRITE_AREA, memId);
get_area_info(narea, &ainfo);
return (int *) ainfo.address;
}
}
/* Control a shared mem area */
int
shmctl(int shmid, int flag, struct shmid_ds * dummy)
{
if (flag == IPC_RMID)
{
/* Delete the area */
delete_area(shmid);
return 0;
}
if (flag == IPC_STAT)
{
/* Find any SYSV area with the shmid in its name */
area_info inf;
team_info infteam;
int32 cookteam = 0;
char name[50];
sprintf(name, "SYSV_IPC %d", shmid);
dummy->shm_nattch = 0;
while (get_next_team_info(&cookteam, &infteam) == B_OK)
{
int32 cook = 0;
while (get_next_area_info(infteam.team, &cook, &inf) == B_OK)
{
if (strcmp(name, inf.name) == 0)
dummy->shm_nattch++;
}
}
errno = 0;
return 0;
}
errno = EINVAL;
return -1;
}
/* Get an area based on the IPC key */
int
shmget(int memKey, int size, int flag)
{
char nom[50];
void *Address;
area_id parea;
/* Area name */
sprintf(nom, "SYSV_IPC_SHM : %d", memKey);
/* Find area */
parea = find_area(nom);
/* area exist, just return its id */
if (parea != B_NAME_NOT_FOUND)
return parea;
/* area does not exist and no creation is requested : error */
if (flag == 0)
return -1;
/*
* area does not exist and its creation is requested, create it (be sure
* to have a 4ko multiple size
*/
return create_area(nom, &Address, B_ANY_ADDRESS, ((size / 4096) + 1) * 4096, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
}
|