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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include <fcntl.h>
00051 #include <unistd.h>
00052 #include <sys/stat.h>
00053 #ifdef __MINGW32__
00054 #include <windows.h>
00055 #else
00056 #include <sys/mman.h>
00057 #endif
00058 #include <sys/types.h>
00059 #include <sys/param.h>
00060
00061 #include "defs.h"
00062 #include "glob.h"
00063 #include "erbe.h"
00064 #include "erglob.h"
00065 #include "file_util.h"
00066
00067 #include "dra_internal.h"
00068
00069
00070
00071
00072
00073
00074
00075
00076 INT DRA_file_desc = -1;
00077
00078 char *DRA_file_mmap = NULL;
00079
00080 char DRA_file_name[MAXPATHLEN];
00081
00082 #ifdef __MINGW32__
00083 HANDLE DRA_file_mmap_handle = NULL;
00084 #endif
00085
00086
00087
00088
00089
00090
00091
00092 static void DRA_Make_File_Name();
00093
00094 static char* basename(char *const s);
00095
00096 static char* dirname(char *const s);
00097
00098
00099
00100
00101
00102
00103
00104
00105 static char *DRA_keep_old_file;
00106
00107 static off_t DRA_file_size, DRA_bytes_to_keep;
00108
00109 static const char* DRA_DIRECTORY = "/rii_files/";
00110
00111 static const char* DRA_FILE_EXTENSION = ".rii";
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void
00130 DRA_Open_And_Map_File()
00131 {
00132 Set_Error_Phase("Reading prelinker file");
00133
00134 DRA_Make_File_Name();
00135
00136 struct stat stat_buf;
00137 errno = 0;
00138
00139 DRA_file_desc = open(DRA_file_name, O_RDONLY);
00140
00141 if (DRA_file_desc < 0 || fstat(DRA_file_desc, &stat_buf) != 0) {
00142 close(DRA_file_desc);
00143 ErrMsg(EC_DRA_rii_file_io, DRA_file_name, errno);
00144 return;
00145 }
00146
00147 #ifdef __MINGW32__
00148 DRA_file_mmap = NULL;
00149 DRA_file_mmap_handle =
00150 CreateFileMapping((HANDLE) _get_osfhandle(DRA_file_desc), NULL,
00151 PAGE_READWRITE, 0, stat_buf.st_size, DRA_file_name);
00152 if (DRA_file_mmap_handle)
00153 DRA_file_mmap = (char *) MapViewOfFileEx(DRA_file_mmap_handle,
00154 FILE_MAP_COPY,
00155 0, 0, stat_buf.st_size, 0);
00156 if (DRA_file_mmap == NULL) {
00157 close(DRA_file_desc);
00158 ErrMsg(EC_DRA_rii_file_io, DRA_file_name, GetLastError());
00159 return;
00160 }
00161 #else
00162 DRA_file_mmap = (char *) mmap(0,
00163 stat_buf.st_size,
00164 PROT_READ|PROT_WRITE,
00165 MAP_PRIVATE,
00166 DRA_file_desc,
00167 0);
00168
00169 if (DRA_file_mmap == (char *)(MAP_FAILED)) {
00170 close(DRA_file_desc);
00171 ErrMsg(EC_DRA_rii_file_io, DRA_file_name, errno);
00172 return;
00173 }
00174 #endif
00175
00176 close(DRA_file_desc);
00177
00178
00179
00180 DRA_file_size = stat_buf.st_size;
00181
00182
00183
00184
00185
00186
00187
00188
00189 char *first_sep = strstr(DRA_file_mmap, DRA_FILE_SEPARATOR);
00190
00191
00192
00193 if (first_sep == NULL) {
00194 (void) unlink(DRA_file_name);
00195 ErrMsg(EC_DRA_rii_file_format, DRA_file_name);
00196 return;
00197 }
00198
00199 char *second_sep = strstr(first_sep+1, DRA_FILE_SEPARATOR);
00200
00201 if (second_sep == NULL) {
00202 DRA_bytes_to_keep = DRA_file_size;
00203 }
00204 else {
00205 DRA_bytes_to_keep = second_sep - DRA_file_mmap;
00206 }
00207
00208 DRA_keep_old_file = CXX_NEW_ARRAY(char, DRA_bytes_to_keep, Malloc_Mem_Pool);
00209 if (DRA_keep_old_file == NULL) {
00210 ErrMsg(EC_No_Mem, "DRA_Open_And_Map_File");
00211 return;
00212 }
00213 else {
00214 (void) strncpy(DRA_keep_old_file, DRA_file_mmap, DRA_bytes_to_keep);
00215 }
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 void
00231 DRA_Set_Write_Location(void)
00232 {
00233 errno = 0;
00234
00235 DRA_file_desc = open(DRA_file_name, O_WRONLY|O_TRUNC);
00236
00237 if (DRA_file_desc < 0) {
00238 close(DRA_file_desc);
00239 ErrMsg(EC_DRA_rii_file_io, DRA_file_name, errno);
00240 return;
00241 }
00242
00243 write(DRA_file_desc, (void*)DRA_keep_old_file, DRA_bytes_to_keep);
00244 write(DRA_file_desc, (void*)DRA_FILE_SEPARATOR, strlen(DRA_FILE_SEPARATOR));
00245
00246 CXX_DELETE_ARRAY(DRA_keep_old_file, Malloc_Mem_Pool);
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 void
00261 DRA_Mem_Unmap_File()
00262 {
00263 #ifdef __MINGW32__
00264 (void) UnmapViewOfFile(DRA_file_mmap);
00265 (void) CloseHandle(DRA_file_mmap_handle);
00266 #else
00267 (void) munmap((void *)DRA_file_mmap, (size_t)DRA_file_size);
00268 #endif
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 void
00283 DRA_Close_File()
00284 {
00285 if (DRA_file_desc >= 0) {
00286 close(DRA_file_desc);
00287 }
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 static void
00311 DRA_Make_File_Name()
00312 {
00313 char *obj_file_name = Obj_File_Name ?
00314 Obj_File_Name : New_Extension (Src_File_Name, ".o");
00315
00316 char *dir = dirname(obj_file_name);
00317 strcpy (DRA_file_name, dir);
00318 strcat (DRA_file_name, DRA_DIRECTORY);
00319
00320 char *base = basename(obj_file_name);
00321 INT baselen = strlen(base);
00322
00323 if (base[baselen-2] == '.' && base[baselen-1] == 'o')
00324 strcpy(&base[baselen-2], DRA_FILE_EXTENSION);
00325 else
00326 strcpy(&base[baselen], DRA_FILE_EXTENSION);
00327
00328 strcat (DRA_file_name, base);
00329 }
00330
00331
00332
00333
00334 static char tempbuf[MAXPATHLEN];
00335
00336
00337 static char*
00338 basename(char *const s)
00339 {
00340 register char *p;
00341 register char *const t = tempbuf;
00342
00343 if (s == NULL || *s == 0) {
00344 return strcpy(t, ".");
00345 } else {
00346 p = strcpy(t, s);
00347 p += strlen(p);
00348 while( p != t && *--p == '/' )
00349 *p = '\0';
00350 while( p != t ) {
00351 if( *--p == '/' )
00352 return ++p;
00353 }
00354 return p;
00355 }
00356 }
00357
00358
00359 static char*
00360 dirname(char *const s)
00361 {
00362 register char *p;
00363 register char *const t = tempbuf;
00364
00365 if (s == NULL || *s == 0) {
00366 return strcpy(t, ".");
00367 } else {
00368 p = strcpy(t, s);
00369 p += strlen(p);
00370 while( p != t && *--p == '/' )
00371 ;
00372
00373 if ( p == t && *p == '/' )
00374 return strcpy(t, "/");
00375
00376 while( p != t ) {
00377 if( *--p == '/' ) {
00378 if ( p == t )
00379 return strcpy(t, "/");
00380 while ( *p == '/' )
00381 p--;
00382 *++p = '\0';
00383 return t;
00384 }
00385 }
00386 return strcpy(t, ".");
00387 }
00388 }