00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdio.h>
00028 #include <errno.h>
00029 #include <sys/types.h>
00030 #include <fcntl.h>
00031 #include <sys/stat.h>
00032 #include <string.h>
00033 #include "mmprivate.h"
00034
00035 #ifndef WIN32
00036 # include <sys/mman.h>
00037 #else
00038 # include <io.h>
00039 #endif
00040
00041 #ifndef SEEK_SET
00042 #define SEEK_SET 0
00043 #endif
00044
00045
00046 #if defined(R__HAVE_MMAP)
00047
00048
00049
00050 #ifndef WIN32
00051 static struct mdesc *reuse PARAMS ((int));
00052 #else
00053 static struct mdesc *reuse PARAMS ((HANDLE));
00054 #endif
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 PTR
00088 mmalloc_attach (fd, baseaddr, minsize)
00089 #ifndef WIN32
00090 int fd;
00091 #else
00092 HANDLE fd;
00093 #endif
00094 PTR baseaddr;
00095 int minsize;
00096 {
00097 struct mdesc mtemp;
00098 struct mdesc *mdp;
00099 PTR mbase;
00100 int coresize;
00101 #ifndef WIN32
00102 struct stat sbuf;
00103 #else
00104 BY_HANDLE_FILE_INFORMATION sbuf;
00105 #endif
00106
00107
00108
00109
00110
00111
00112
00113
00114 #ifndef WIN32
00115 if (fd >= 0)
00116 {
00117 if (fstat (fd, &sbuf) < 0)
00118 {
00119 return (NULL);
00120 }
00121 else if (sbuf.st_size > 0)
00122 {
00123 return ((PTR) reuse (fd));
00124 }
00125 }
00126 #else
00127 if (fd != INVALID_HANDLE_VALUE)
00128 {
00129 if ( !GetFileInformationByHandle(fd, &sbuf) )
00130 {
00131 return (NULL);
00132 }
00133 else if (sbuf.nFileSizeLow || sbuf.nFileSizeHigh )
00134 {
00135 return ((PTR) reuse (fd));
00136 }
00137 }
00138 #endif
00139
00140
00141
00142
00143
00144
00145 mdp = &mtemp;
00146 memset ((char *) mdp, 0, sizeof (mtemp));
00147 strncpy (mdp -> magic, MMALLOC_MAGIC, MMALLOC_MAGIC_SIZE);
00148 mdp -> headersize = sizeof (mtemp);
00149 mdp -> version = MMALLOC_VERSION;
00150 mdp -> morecore = __mmalloc_mmap_morecore;
00151 mdp -> fd = fd;
00152 mdp -> base = mdp -> breakval = mdp -> top = baseaddr;
00153
00154
00155
00156
00157 #ifndef WIN32
00158 if (mdp -> fd < 0)
00159 {
00160 if ((mdp -> fd = open ("/dev/zero", O_RDWR)) < 0)
00161 {
00162 return (NULL);
00163 }
00164 else
00165 {
00166 mdp -> flags |= MMALLOC_DEVZERO;
00167 }
00168 }
00169 #else
00170 if (mdp -> fd == (HANDLE)0xffffffff) mdp -> flags |= MMALLOC_DEVZERO;
00171 #endif
00172
00173
00174
00175
00176
00177
00178 if (minsize)
00179 coresize = minsize;
00180 else
00181 coresize = sizeof(mtemp);
00182
00183 if ((mbase = mdp -> morecore (mdp, coresize)) != NULL)
00184 {
00185 mdp->breakval = mdp->base + sizeof(mtemp);
00186 memcpy (mbase, mdp, sizeof (mtemp));
00187 #ifndef WIN32
00188 # ifndef VMS
00189 # ifndef R__LYNXOS
00190 # ifndef R__HURD
00191
00192 msync(mbase, sizeof(mtemp), MS_ASYNC);
00193 # endif
00194 # endif
00195 # endif
00196 #endif
00197 mdp = (struct mdesc *) mbase;
00198 }
00199 else
00200 {
00201 if (mdp -> flags & MMALLOC_DEVZERO)
00202 {
00203 #ifndef WIN32
00204 close (mdp -> fd);
00205 #else
00206 CloseHandle (mdp -> fd);
00207 #endif
00208 }
00209 mdp = NULL;
00210 }
00211
00212 return ((PTR) mdp);
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 static struct mdesc *
00239 reuse (cfd)
00240 #ifndef WIN32
00241 int cfd;
00242 #else
00243 HANDLE cfd;
00244 #endif
00245 {
00246 struct mdesc *mtemp = (struct mdesc*) malloc(sizeof(struct mdesc));
00247 struct mdesc *mdp = NULL;
00248
00249 #ifdef WIN32
00250 int rdonly = 0;
00251 BY_HANDLE_FILE_INFORMATION FileInformation;
00252 DWORD lbuf;
00253 long fd = _get_osfhandle((int)cfd);
00254 if (!GetFileInformationByHandle(cfd,&FileInformation))
00255 {
00256 fprintf(stderr, "reuse: error calling GetFileInformationByHandle(%d)\n", GetLastError());
00257 free(mtemp);
00258 return (mdp);
00259 }
00260 if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY) rdonly = 1;
00261 rdonly = 1;
00262 if ((SetFilePointer(cfd,0,NULL,FILE_BEGIN) != 0xFFFFFFFF) &&
00263 (ReadFile (cfd, (char *) mtemp, sizeof (*mtemp),&lbuf,NULL) && lbuf == sizeof (*mtemp)) &&
00264 (mtemp->headersize == sizeof (*mtemp)) &&
00265 (strcmp (mtemp->magic, MMALLOC_MAGIC) == 0) &&
00266 (mtemp->version <= MMALLOC_VERSION))
00267 #else
00268 int val, rdonly = 0;
00269 int fd = cfd;
00270
00271 if ((val = fcntl(fd, F_GETFL, 0)) < 0) {
00272 fprintf(stderr, "reuse: error calling fcntl(%d)\n", errno);
00273 free(mtemp);
00274 return (mdp);
00275 }
00276 if ((val & O_ACCMODE) == O_RDONLY) rdonly = 1;
00277
00278 if ((lseek (fd, 0L, SEEK_SET) == 0) &&
00279 (read (fd, (char *) mtemp, sizeof (*mtemp)) == sizeof (*mtemp)) &&
00280 (mtemp->headersize == sizeof (*mtemp)) &&
00281 (strcmp (mtemp->magic, MMALLOC_MAGIC) == 0) &&
00282 (mtemp->version <= MMALLOC_VERSION))
00283 #endif
00284 {
00285 mtemp->fd = cfd;
00286 if (__mmalloc_remap_core (mtemp) != (char*)-1)
00287 {
00288 if (rdonly) {
00289 mdp = mtemp;
00290
00291 } else {
00292
00293 if (mtemp->offset != 0) goto end;
00294 mdp = (struct mdesc *) mtemp->base;
00295 mdp -> fd = cfd;
00296 #ifndef WIN32
00297 # ifndef VMS
00298 # ifndef R__LYNXOS
00299 # ifndef R__HURD
00300
00301 msync((void *)mdp, sizeof(*mtemp), MS_ASYNC);
00302 # endif
00303 # endif
00304 # endif
00305 #endif
00306 free(mtemp);
00307 }
00308 mdp -> morecore = __mmalloc_mmap_morecore;
00309 if (mdp -> mfree_hook != NULL)
00310 {
00311 mmcheck ((PTR) mdp, (void (*) PARAMS ((void))) NULL);
00312 }
00313 }
00314 }
00315 end:
00316 if (mdp == NULL) free(mtemp);
00317 return (mdp);
00318 }
00319
00320 #else
00321
00322
00323
00324
00325
00326
00327 #ifdef VMS
00328 PTR
00329 mmalloc_attach (fd,baseaddr,minsize)
00330 #else
00331 PTR
00332 mmalloc_attach (fd, baseaddr)
00333 #endif
00334
00335 #ifndef WIN32
00336 int fd;
00337 #else
00338 HANDLE fd;
00339 #endif
00340 PTR baseaddr;
00341 {
00342 return (NULL);
00343 }
00344
00345 #endif
00346