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 #include "sysdep.h"
00030
00031 #include "bfd.h"
00032 #include "libbfd.h"
00033
00034 #include <limits.h>
00035
00036 #ifndef S_IXUSR
00037 #define S_IXUSR 0100
00038 #endif
00039 #ifndef S_IXGRP
00040 #define S_IXGRP 0010
00041 #endif
00042 #ifndef S_IXOTH
00043 #define S_IXOTH 0001
00044 #endif
00045
00046 file_ptr
00047 real_ftell (FILE *file)
00048 {
00049 #if defined (HAVE_FTELLO64)
00050 return ftello64 (file);
00051 #elif defined (HAVE_FTELLO)
00052 return ftello (file);
00053 #else
00054 return ftell (file);
00055 #endif
00056 }
00057
00058 int
00059 real_fseek (FILE *file, file_ptr offset, int whence)
00060 {
00061 #if defined (HAVE_FSEEKO64)
00062 return fseeko64 (file, offset, whence);
00063 #elif defined (HAVE_FSEEKO)
00064 return fseeko (file, offset, whence);
00065 #else
00066 return fseek (file, offset, whence);
00067 #endif
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 bfd_size_type
00109 bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
00110 {
00111 size_t nread;
00112
00113 if ((abfd->flags & BFD_IN_MEMORY) != 0)
00114 {
00115 struct bfd_in_memory *bim;
00116 bfd_size_type get;
00117
00118 bim = abfd->iostream;
00119 get = size;
00120 if (abfd->where + get > bim->size)
00121 {
00122 if (bim->size < (bfd_size_type) abfd->where)
00123 get = 0;
00124 else
00125 get = bim->size - abfd->where;
00126 bfd_set_error (bfd_error_file_truncated);
00127 }
00128 memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
00129 abfd->where += get;
00130 return get;
00131 }
00132
00133 if (abfd->iovec)
00134 nread = abfd->iovec->bread (abfd, ptr, size);
00135 else
00136 nread = 0;
00137 if (nread != (size_t) -1)
00138 abfd->where += nread;
00139
00140 return nread;
00141 }
00142
00143 bfd_size_type
00144 bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
00145 {
00146 size_t nwrote;
00147
00148 if ((abfd->flags & BFD_IN_MEMORY) != 0)
00149 {
00150 struct bfd_in_memory *bim = abfd->iostream;
00151
00152 size = (size_t) size;
00153 if (abfd->where + size > bim->size)
00154 {
00155 bfd_size_type newsize, oldsize;
00156
00157 oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
00158 bim->size = abfd->where + size;
00159
00160 newsize = (bim->size + 127) & ~(bfd_size_type) 127;
00161 if (newsize > oldsize)
00162 {
00163 bim->buffer = bfd_realloc (bim->buffer, newsize);
00164 if (bim->buffer == 0)
00165 {
00166 bim->size = 0;
00167 return 0;
00168 }
00169 }
00170 }
00171 memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
00172 abfd->where += size;
00173 return size;
00174 }
00175
00176 if (abfd->iovec)
00177 nwrote = abfd->iovec->bwrite (abfd, ptr, size);
00178 else
00179 nwrote = 0;
00180
00181 if (nwrote != (size_t) -1)
00182 abfd->where += nwrote;
00183 if (nwrote != size)
00184 {
00185 #ifdef ENOSPC
00186 errno = ENOSPC;
00187 #endif
00188 bfd_set_error (bfd_error_system_call);
00189 }
00190 return nwrote;
00191 }
00192
00193 file_ptr
00194 bfd_tell (bfd *abfd)
00195 {
00196 file_ptr ptr;
00197
00198 if ((abfd->flags & BFD_IN_MEMORY) != 0)
00199 return abfd->where;
00200
00201 if (abfd->iovec)
00202 {
00203 ptr = abfd->iovec->btell (abfd);
00204
00205 if (abfd->my_archive)
00206 ptr -= abfd->origin;
00207 }
00208 else
00209 ptr = 0;
00210
00211 abfd->where = ptr;
00212 return ptr;
00213 }
00214
00215 int
00216 bfd_flush (bfd *abfd)
00217 {
00218 if ((abfd->flags & BFD_IN_MEMORY) != 0)
00219 return 0;
00220
00221 if (abfd->iovec)
00222 return abfd->iovec->bflush (abfd);
00223 return 0;
00224 }
00225
00226
00227
00228 int
00229 bfd_stat (bfd *abfd, struct stat *statbuf)
00230 {
00231 int result;
00232
00233 if ((abfd->flags & BFD_IN_MEMORY) != 0)
00234 abort ();
00235
00236 if (abfd->iovec)
00237 result = abfd->iovec->bstat (abfd, statbuf);
00238 else
00239 result = -1;
00240
00241 if (result < 0)
00242 bfd_set_error (bfd_error_system_call);
00243 return result;
00244 }
00245
00246
00247
00248
00249 int
00250 bfd_seek (bfd *abfd, file_ptr position, int direction)
00251 {
00252 int result;
00253 file_ptr file_position;
00254
00255
00256
00257
00258 BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
00259
00260 if (direction == SEEK_CUR && position == 0)
00261 return 0;
00262
00263 if ((abfd->flags & BFD_IN_MEMORY) != 0)
00264 {
00265 struct bfd_in_memory *bim;
00266
00267 bim = abfd->iostream;
00268
00269 if (direction == SEEK_SET)
00270 abfd->where = position;
00271 else
00272 abfd->where += position;
00273
00274 if (abfd->where > bim->size)
00275 {
00276 if ((abfd->direction == write_direction) ||
00277 (abfd->direction == both_direction))
00278 {
00279 bfd_size_type newsize, oldsize;
00280
00281 oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
00282 bim->size = abfd->where;
00283
00284 newsize = (bim->size + 127) & ~(bfd_size_type) 127;
00285 if (newsize > oldsize)
00286 {
00287 bim->buffer = bfd_realloc (bim->buffer, newsize);
00288 if (bim->buffer == 0)
00289 {
00290 bim->size = 0;
00291 return -1;
00292 }
00293 }
00294 }
00295 else
00296 {
00297 abfd->where = bim->size;
00298 bfd_set_error (bfd_error_file_truncated);
00299 return -1;
00300 }
00301 }
00302 return 0;
00303 }
00304
00305 if (abfd->format != bfd_archive && abfd->my_archive == 0)
00306 {
00307 if (direction == SEEK_SET && (bfd_vma) position == abfd->where)
00308 return 0;
00309 }
00310 else
00311 {
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 }
00324
00325 file_position = position;
00326 if (direction == SEEK_SET && abfd->my_archive != NULL)
00327 file_position += abfd->origin;
00328
00329 if (abfd->iovec)
00330 result = abfd->iovec->bseek (abfd, file_position, direction);
00331 else
00332 result = -1;
00333
00334 if (result != 0)
00335 {
00336 int hold_errno = errno;
00337
00338
00339 bfd_tell (abfd);
00340
00341
00342
00343 if (hold_errno == EINVAL)
00344 bfd_set_error (bfd_error_file_truncated);
00345 else
00346 {
00347 bfd_set_error (bfd_error_system_call);
00348 errno = hold_errno;
00349 }
00350 }
00351 else
00352 {
00353
00354 if (direction == SEEK_SET)
00355 abfd->where = position;
00356 else
00357 abfd->where += position;
00358 }
00359 return result;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 long
00376 bfd_get_mtime (bfd *abfd)
00377 {
00378 struct stat buf;
00379
00380 if (abfd->mtime_set)
00381 return abfd->mtime;
00382
00383 if (abfd->iovec == NULL)
00384 return 0;
00385
00386 if (abfd->iovec->bstat (abfd, &buf) != 0)
00387 return 0;
00388
00389 abfd->mtime = buf.st_mtime;
00390 return buf.st_mtime;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 long
00427 bfd_get_size (bfd *abfd)
00428 {
00429 struct stat buf;
00430
00431 if ((abfd->flags & BFD_IN_MEMORY) != 0)
00432 return ((struct bfd_in_memory *) abfd->iostream)->size;
00433
00434 if (abfd->iovec == NULL)
00435 return 0;
00436
00437 if (abfd->iovec->bstat (abfd, &buf) != 0)
00438 return 0;
00439
00440 return buf.st_size;
00441 }