archivers/dir.c
changeset 135 57ba3130b1e7
parent 132 b53fa5093749
child 137 66bddb94b6e0
equal deleted inserted replaced
134:eb030f2e342a 135:57ba3130b1e7
    95 
    95 
    96 
    96 
    97 static PHYSFS_sint64 DIR_read(FileHandle *handle, void *buffer,
    97 static PHYSFS_sint64 DIR_read(FileHandle *handle, void *buffer,
    98                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
    98                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
    99 {
    99 {
   100     FILE *h = (FILE *) (handle->opaque);
   100     PHYSFS_sint64 retval;
   101     size_t retval;
   101     retval = __PHYSFS_platformRead(handle->opaque, buffer, objSize, objCount);
   102 
   102     return(retval);
   103     errno = 0;
       
   104     retval = fread(buffer, objSize, objCount, h);
       
   105     BAIL_IF_MACRO((retval < (size_t) objCount) && (ferror(h)),
       
   106                    strerror(errno), (int) retval);
       
   107 
       
   108     return((int) retval);
       
   109 } /* DIR_read */
   103 } /* DIR_read */
   110 
   104 
   111 
   105 
   112 static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer,
   106 static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer,
   113                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
   107                                PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
   114 {
   108 {
   115     FILE *h = (FILE *) (handle->opaque);
   109     PHYSFS_sint64 retval;
   116     size_t retval;
   110     retval = __PHYSFS_platformWrite(handle->opaque, buffer, objSize, objCount);
   117 
   111     return(retval);
   118     errno = 0;
       
   119     retval = fwrite(buffer, (size_t) objSize, objCount, h);
       
   120     if ( (retval < (signed int) objCount) && (ferror(h)) )
       
   121         __PHYSFS_setError(strerror(errno));
       
   122 
       
   123     return((int) retval);
       
   124 } /* DIR_write */
   112 } /* DIR_write */
   125 
   113 
   126 
   114 
   127 static int DIR_eof(FileHandle *handle)
   115 static int DIR_eof(FileHandle *handle)
   128 {
   116 {
   129     return(feof((FILE *) (handle->opaque)));
   117     return(__PHYSFS_platformEOF(handle->opaque));
   130 } /* DIR_eof */
   118 } /* DIR_eof */
   131 
   119 
   132 
   120 
   133 static PHYSFS_sint64 DIR_tell(FileHandle *handle)
   121 static PHYSFS_sint64 DIR_tell(FileHandle *handle)
   134 {
   122 {
   135     return(ftell((FILE *) (handle->opaque)));
   123     return(__PHYSFS_platformTell(handle->opaque));
   136 } /* DIR_tell */
   124 } /* DIR_tell */
   137 
   125 
   138 
   126 
   139 static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset)
   127 static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset)
   140 {
   128 {
   141     return(fseek((FILE *) (handle->opaque), offset, SEEK_SET) == 0);
   129     return(__PHYSFS_platformSeek(handle->opaque, offset));
   142 } /* DIR_seek */
   130 } /* DIR_seek */
   143 
   131 
   144 
   132 
   145 static PHYSFS_sint64 DIR_fileLength(FileHandle *handle)
   133 static PHYSFS_sint64 DIR_fileLength(FileHandle *handle)
   146 {
   134 {
   147     return(__PHYSFS_platformFileLength((FILE *) (handle->opaque)));
   135     return(__PHYSFS_platformFileLength(handle->opaque));
   148 } /* DIR_fileLength */
   136 } /* DIR_fileLength */
   149 
   137 
   150 
   138 
   151 static int DIR_fileClose(FileHandle *handle)
   139 static int DIR_fileClose(FileHandle *handle)
   152 {
   140 {
   153     FILE *h = (FILE *) (handle->opaque);
       
   154 
       
   155 #if 0
       
   156     /*
   141     /*
   157      * we manually fflush() the buffer, since that's the place fclose() will
   142      * we manually flush the buffer, since that's the place a close will
   158      *  most likely fail, but that will leave the file handle in an undefined
   143      *  most likely fail, but that will leave the file handle in an undefined
   159      *  state if it fails. fflush() failures we can recover from.
   144      *  state if it fails. Flush failures we can recover from.
   160      */
   145      */
   161 
   146     BAIL_IF_MACRO(!__PHYSFS_platformFlush(handle->opaque), NULL, 0);
   162     /* keep trying until there's success or an unrecoverable error... */
   147     BAIL_IF_MACRO(!__PHYSFS_platformClose(handle->opaque), NULL, 0);
   163     do {
       
   164         __PHYSFS_platformTimeslice();
       
   165         errno = 0;
       
   166     } while ( (fflush(h) == EOF) && ((errno == EAGAIN) || (errno == EINTR)) );
       
   167 
       
   168     /* EBADF == "Not open for writing". That's fine. */
       
   169     BAIL_IF_MACRO((errno != 0) && (errno != EBADF), strerror(errno), 0);
       
   170 #endif
       
   171 
       
   172     /* if fclose fails anyhow, we just have to pray that it's still usable. */
       
   173     errno = 0;
       
   174     BAIL_IF_MACRO(fclose(h) == EOF, strerror(errno), 0);  /* (*shrug*) */
       
   175 
       
   176     free(handle);
   148     free(handle);
   177     return(1);
   149     return(1);
   178 } /* DIR_fileClose */
   150 } /* DIR_fileClose */
   179 
   151 
   180 
   152 
   263     free(f);
   235     free(f);
   264     return(retval);
   236     return(retval);
   265 } /* DIR_isSymLink */
   237 } /* DIR_isSymLink */
   266 
   238 
   267 
   239 
   268 static FileHandle *doOpen(DirHandle *h, const char *name, const char *mode)
   240 static FileHandle *doOpen(DirHandle *h, const char *name,
   269 {
   241                           void *(*openFunc)(const char *filename),
   270     char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
   242                           const FileFunctions *fileFuncs)
   271     FILE *rc;
   243 {
       
   244     char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
       
   245     void *rc;
   272     FileHandle *retval;
   246     FileHandle *retval;
   273     char *str;
   247     char *str;
   274 
   248 
   275     BAIL_IF_MACRO(f == NULL, NULL, NULL);
   249     BAIL_IF_MACRO(f == NULL, NULL, NULL);
   276 
   250 
   277     retval = (FileHandle *) malloc(sizeof (FileHandle));
   251     retval = (FileHandle *) malloc(sizeof (FileHandle));
   278     if (!retval)
   252     if (!retval)
   279     {
   253     {
   280         free(f);
   254         free(f);
   281         BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
   255         BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
   282     } /* if */
   256     } /* if */
   283 
   257 
   284     errno = 0;
   258     rc = openFunc(f);
   285     rc = fopen(f, mode);
       
   286     str = strerror(errno);
       
   287     free(f);
   259     free(f);
   288 
   260 
   289     if (!rc)
   261     if (!rc)
   290     {
   262     {
   291         free(retval);
   263         free(retval);
   292         BAIL_IF_MACRO(1, str, NULL);
   264         BAIL_MACRO(str, NULL);
   293     } /* if */
   265     } /* if */
   294 
   266 
   295     retval->opaque = (void *) rc;
   267     retval->opaque = (void *) rc;
   296     retval->dirHandle = h;
   268     retval->dirHandle = h;
   297     retval->funcs = (mode[0] == 'r') ?
   269     retval->funcs = fileFuncs;
   298                 &__PHYSFS_FileFunctions_DIR : &__PHYSFS_FileFunctions_DIRW;
   270 
   299     return(retval);
   271     return(retval);
   300 } /* doOpen */
   272 } /* doOpen */
   301 
   273 
   302 
   274 
   303 static FileHandle *DIR_openRead(DirHandle *h, const char *filename)
   275 static FileHandle *DIR_openRead(DirHandle *h, const char *filename)
   304 {
   276 {
   305     return(doOpen(h, filename, "rb"));
   277     return(doOpen(h, filename, __PHYSFS_platformOpenRead,
       
   278                   &__PHYSFS_FileFunctions_DIR));
   306 } /* DIR_openRead */
   279 } /* DIR_openRead */
   307 
   280 
   308 
   281 
   309 static FileHandle *DIR_openWrite(DirHandle *h, const char *filename)
   282 static FileHandle *DIR_openWrite(DirHandle *h, const char *filename)
   310 {
   283 {
   311     return(doOpen(h, filename, "wb"));
   284     return(doOpen(h, filename, __PHYSFS_platformOpenWrite,
       
   285                   &__PHYSFS_FileFunctions_DIRW));
   312 } /* DIR_openWrite */
   286 } /* DIR_openWrite */
   313 
   287 
   314 
   288 
   315 static FileHandle *DIR_openAppend(DirHandle *h, const char *filename)
   289 static FileHandle *DIR_openAppend(DirHandle *h, const char *filename)
   316 {
   290 {
   317     return(doOpen(h, filename, "ab"));
   291     return(doOpen(h, filename, __PHYSFS_platformOpenAppend,
       
   292                   &__PHYSFS_FileFunctions_DIRW));
   318 } /* DIR_openAppend */
   293 } /* DIR_openAppend */
   319 
   294 
   320 
   295 
   321 static int DIR_remove(DirHandle *h, const char *name)
   296 static int DIR_remove(DirHandle *h, const char *name)
   322 {
   297 {
   323     char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
   298     char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
   324     int retval;
   299     int retval;
   325 
   300 
   326     BAIL_IF_MACRO(f == NULL, NULL, 0);
   301     BAIL_IF_MACRO(f == NULL, NULL, 0);
   327 
   302 
       
   303     /* !!! FIXME: Abstract in platform drivers. */
   328     errno = 0;
   304     errno = 0;
   329     retval = (remove(f) == 0);
   305     retval = (remove(f) == 0);
   330     if (!retval)
   306     if (!retval)
   331         __PHYSFS_setError(strerror(errno));
   307         __PHYSFS_setError(strerror(errno));
   332 
   308 
   339 {
   315 {
   340     char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
   316     char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
   341     int retval;
   317     int retval;
   342 
   318 
   343     BAIL_IF_MACRO(f == NULL, NULL, 0);
   319     BAIL_IF_MACRO(f == NULL, NULL, 0);
   344 
       
   345     errno = 0;
       
   346     retval = __PHYSFS_platformMkDir(f);
   320     retval = __PHYSFS_platformMkDir(f);
   347     if (!retval)
       
   348         __PHYSFS_setError(strerror(errno));
       
   349 
       
   350     free(f);
   321     free(f);
   351     return(retval);
   322     return(retval);
   352 } /* DIR_mkdir */
   323 } /* DIR_mkdir */
   353 
   324 
   354 
   325