1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | /*
|
---|
10 | * xfermem.c
|
---|
11 | *
|
---|
12 | * Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
|
---|
13 | * Sun Apr 6 02:26:26 MET DST 1997
|
---|
14 | *
|
---|
15 | * See xfermem.h for documentation/description.
|
---|
16 | */
|
---|
17 |
|
---|
18 | #include <stdio.h>
|
---|
19 | #include <stdlib.h>
|
---|
20 | #include <string.h>
|
---|
21 | #include <unistd.h>
|
---|
22 | #include <errno.h>
|
---|
23 | #include <sys/types.h>
|
---|
24 | #include <sys/time.h>
|
---|
25 | #include <sys/uio.h>
|
---|
26 | #include <sys/mman.h>
|
---|
27 | #include <sys/socket.h>
|
---|
28 | #include <fcntl.h>
|
---|
29 |
|
---|
30 | #include "xfermem.h"
|
---|
31 |
|
---|
32 | #ifndef USE_MMAP
|
---|
33 | #include <sys/ipc.h>
|
---|
34 | #include <sys/shm.h>
|
---|
35 | #endif
|
---|
36 |
|
---|
37 | extern int errno;
|
---|
38 |
|
---|
39 | #if defined (USE_MMAP) && defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
|
---|
40 | #define MAP_ANON MAP_ANONYMOUS
|
---|
41 | #endif
|
---|
42 |
|
---|
43 | void xfermem_init (txfermem **xf, int bufsize, int msize)
|
---|
44 | {
|
---|
45 | int regsize = bufsize + msize + sizeof(txfermem);
|
---|
46 |
|
---|
47 | #ifdef USE_MMAP
|
---|
48 | # ifdef MAP_ANON
|
---|
49 | if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE,
|
---|
50 | MAP_ANON | MAP_SHARED, -1, 0)) == (txfermem *) -1) {
|
---|
51 | perror ("mmap()");
|
---|
52 | exit (1);
|
---|
53 | }
|
---|
54 | # else
|
---|
55 | int devzero;
|
---|
56 | if ((devzero = open("/dev/zero", O_RDWR, 0)) == -1) {
|
---|
57 | perror ("open(/dev/zero)");
|
---|
58 | exit (1);
|
---|
59 | }
|
---|
60 | if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE,
|
---|
61 | MAP_SHARED, devzero, 0)) == (txfermem *) -1) {
|
---|
62 | perror ("mmap()");
|
---|
63 | exit (1);
|
---|
64 | }
|
---|
65 | close (devzero);
|
---|
66 | # endif
|
---|
67 | #else
|
---|
68 | struct shmid_ds shmemds;
|
---|
69 | int shmemid;
|
---|
70 | if ((shmemid = shmget(IPC_PRIVATE, regsize, IPC_CREAT | 0600)) == -1) {
|
---|
71 | perror ("shmget()");
|
---|
72 | exit (1);
|
---|
73 | }
|
---|
74 | if ((*xf = (txfermem *) shmat(shmemid, 0, 0)) == (txfermem *) -1) {
|
---|
75 | perror ("shmat()");
|
---|
76 | shmctl (shmemid, IPC_RMID, &shmemds);
|
---|
77 | exit (1);
|
---|
78 | }
|
---|
79 | if (shmctl(shmemid, IPC_RMID, &shmemds) == -1) {
|
---|
80 | perror ("shmctl()");
|
---|
81 | xfermem_done (*xf);
|
---|
82 | exit (1);
|
---|
83 | }
|
---|
84 | #endif
|
---|
85 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, (*xf)->fd) < 0) {
|
---|
86 | perror ("socketpair()");
|
---|
87 | xfermem_done (*xf);
|
---|
88 | exit (1);
|
---|
89 | }
|
---|
90 | (*xf)->freeindex = (*xf)->readindex = 0;
|
---|
91 | (*xf)->wakeme[0] = (*xf)->wakeme[1] = FALSE;
|
---|
92 | (*xf)->data = ((byte *) *xf) + sizeof(txfermem) + msize;
|
---|
93 | (*xf)->metadata = ((byte *) *xf) + sizeof(txfermem);
|
---|
94 | (*xf)->size = bufsize;
|
---|
95 | (*xf)->metasize = msize;
|
---|
96 | }
|
---|
97 |
|
---|
98 | void xfermem_done (txfermem *xf)
|
---|
99 | {
|
---|
100 | #ifdef USE_MMAP
|
---|
101 | munmap ((caddr_t) xf, xf->size + xf->metasize + sizeof(txfermem));
|
---|
102 | #else
|
---|
103 | if (shmdt((void *) xf) == -1) {
|
---|
104 | perror ("shmdt()");
|
---|
105 | exit (1);
|
---|
106 | }
|
---|
107 | #endif
|
---|
108 | }
|
---|
109 |
|
---|
110 | void xfermem_init_writer (txfermem *xf)
|
---|
111 | {
|
---|
112 | close (xf->fd[XF_READER]);
|
---|
113 | }
|
---|
114 |
|
---|
115 | void xfermem_init_reader (txfermem *xf)
|
---|
116 | {
|
---|
117 | close (xf->fd[XF_WRITER]);
|
---|
118 | }
|
---|
119 |
|
---|
120 | int xfermem_get_freespace (txfermem *xf)
|
---|
121 | {
|
---|
122 | int freeindex, readindex;
|
---|
123 |
|
---|
124 | if ((freeindex = xf->freeindex) < 0
|
---|
125 | || (readindex = xf->readindex) < 0)
|
---|
126 | return (0);
|
---|
127 | if (readindex > freeindex)
|
---|
128 | return ((readindex - freeindex) - 1);
|
---|
129 | else
|
---|
130 | return ((xf->size - (freeindex - readindex)) - 1);
|
---|
131 | }
|
---|
132 |
|
---|
133 | int xfermem_get_usedspace (txfermem *xf)
|
---|
134 | {
|
---|
135 | int freeindex, readindex;
|
---|
136 |
|
---|
137 | if ((freeindex = xf->freeindex) < 0
|
---|
138 | || (readindex = xf->readindex) < 0)
|
---|
139 | return (0);
|
---|
140 | if (freeindex >= readindex)
|
---|
141 | return (freeindex - readindex);
|
---|
142 | else
|
---|
143 | return (xf->size - (readindex - freeindex));
|
---|
144 | }
|
---|
145 |
|
---|
146 | int xfermem_write (txfermem *xf, byte *data, int count)
|
---|
147 | {
|
---|
148 | int nbytes;
|
---|
149 |
|
---|
150 | if ((nbytes = xfermem_get_freespace(xf))> count)
|
---|
151 | nbytes = count;
|
---|
152 | if (nbytes) {
|
---|
153 | if (xf->freeindex + nbytes > xf->size) {
|
---|
154 | int first = xf->size - xf->freeindex;
|
---|
155 | memcpy (xf->data + xf->freeindex, data, first);
|
---|
156 | memcpy (xf->data, data + first, nbytes - first);
|
---|
157 | }
|
---|
158 | else
|
---|
159 | memcpy (xf->data + xf->freeindex, data, nbytes);
|
---|
160 | xf->freeindex = (xf->freeindex + nbytes) % xf->size;
|
---|
161 | }
|
---|
162 | return (nbytes);
|
---|
163 | }
|
---|
164 |
|
---|
165 | int xfermem_read (txfermem *xf, byte *data, int count)
|
---|
166 | {
|
---|
167 | int nbytes;
|
---|
168 |
|
---|
169 | if ((nbytes = xfermem_get_usedspace(xf))> count)
|
---|
170 | nbytes = count;
|
---|
171 | if (nbytes) {
|
---|
172 | if (xf->readindex + nbytes > xf->size) {
|
---|
173 | int first = xf->size - xf->readindex;
|
---|
174 | memcpy (data, xf->data + xf->readindex, first);
|
---|
175 | memcpy (data + first, xf->data, nbytes - first);
|
---|
176 | }
|
---|
177 | else
|
---|
178 | memcpy (data, xf->data + xf->readindex, nbytes);
|
---|
179 | xf->readindex = (xf->readindex + nbytes) % xf->size;
|
---|
180 | }
|
---|
181 | return (nbytes);
|
---|
182 | }
|
---|
183 |
|
---|
184 | int xfermem_getcmd (int fd, int block)
|
---|
185 | {
|
---|
186 | fd_set selfds;
|
---|
187 | struct timeval selto = {0, 0};
|
---|
188 | byte cmd;
|
---|
189 |
|
---|
190 | for (;;) {
|
---|
191 | FD_ZERO (&selfds);
|
---|
192 | FD_SET (fd, &selfds);
|
---|
193 | switch (select(FD_SETSIZE, &selfds, NULL, NULL, block ? NULL : &selto)) {
|
---|
194 | case 0:
|
---|
195 | if (!block)
|
---|
196 | return (0);
|
---|
197 | continue;
|
---|
198 | case -1:
|
---|
199 | if (errno == EINTR)
|
---|
200 | continue;
|
---|
201 | return (-2);
|
---|
202 | case 1:
|
---|
203 | if (FD_ISSET(fd, &selfds))
|
---|
204 | switch (read(fd, &cmd, 1)) {
|
---|
205 | case 0: /* EOF */
|
---|
206 | return (-1);
|
---|
207 | case -1:
|
---|
208 | if (errno == EINTR)
|
---|
209 | continue;
|
---|
210 | return (-3);
|
---|
211 | case 1:
|
---|
212 | return (cmd);
|
---|
213 | default: /* ?!? */
|
---|
214 | return (-4);
|
---|
215 | }
|
---|
216 | else /* ?!? */
|
---|
217 | return (-5);
|
---|
218 | default: /* ?!? */
|
---|
219 | return (-6);
|
---|
220 | }
|
---|
221 | }
|
---|
222 | }
|
---|
223 |
|
---|
224 | int xfermem_putcmd (int fd, byte cmd)
|
---|
225 | {
|
---|
226 | for (;;)
|
---|
227 | switch (write(fd, &cmd, 1)) {
|
---|
228 | case 1:
|
---|
229 | return (1);
|
---|
230 | case -1:
|
---|
231 | if (errno != EINTR)
|
---|
232 | return (-1);
|
---|
233 | }
|
---|
234 | }
|
---|
235 |
|
---|
236 | int xfermem_block (int readwrite, txfermem *xf)
|
---|
237 | {
|
---|
238 | int myfd = xf->fd[readwrite];
|
---|
239 | int result;
|
---|
240 |
|
---|
241 | xf->wakeme[readwrite] = TRUE;
|
---|
242 | if (xf->wakeme[1 - readwrite])
|
---|
243 | xfermem_putcmd (myfd, XF_CMD_WAKEUP);
|
---|
244 | result = xfermem_getcmd(myfd, TRUE);
|
---|
245 | xf->wakeme[readwrite] = FALSE;
|
---|
246 | return ((result <= 0) ? -1 : result);
|
---|
247 | }
|
---|
248 |
|
---|
249 | /* EOF */
|
---|