misc/libphysfs/platform_posix.c
changeset 12213 bb5522e88ab2
parent 10017 de822cd3df3a
equal deleted inserted replaced
12212:ea891871f481 12213:bb5522e88ab2
    39         case EDQUOT: return PHYSFS_ERR_NO_SPACE;
    39         case EDQUOT: return PHYSFS_ERR_NO_SPACE;
    40         case EIO: return PHYSFS_ERR_IO;
    40         case EIO: return PHYSFS_ERR_IO;
    41         case ELOOP: return PHYSFS_ERR_SYMLINK_LOOP;
    41         case ELOOP: return PHYSFS_ERR_SYMLINK_LOOP;
    42         case EMLINK: return PHYSFS_ERR_NO_SPACE;
    42         case EMLINK: return PHYSFS_ERR_NO_SPACE;
    43         case ENAMETOOLONG: return PHYSFS_ERR_BAD_FILENAME;
    43         case ENAMETOOLONG: return PHYSFS_ERR_BAD_FILENAME;
    44         case ENOENT: return PHYSFS_ERR_NO_SUCH_PATH;
    44         case ENOENT: return PHYSFS_ERR_NOT_FOUND;
    45         case ENOSPC: return PHYSFS_ERR_NO_SPACE;
    45         case ENOSPC: return PHYSFS_ERR_NO_SPACE;
    46         case ENOTDIR: return PHYSFS_ERR_NO_SUCH_PATH;
    46         case ENOTDIR: return PHYSFS_ERR_NOT_FOUND;
    47         case EISDIR: return PHYSFS_ERR_NOT_A_FILE;
    47         case EISDIR: return PHYSFS_ERR_NOT_A_FILE;
    48         case EROFS: return PHYSFS_ERR_READ_ONLY;
    48         case EROFS: return PHYSFS_ERR_READ_ONLY;
    49         case ETXTBSY: return PHYSFS_ERR_BUSY;
    49         case ETXTBSY: return PHYSFS_ERR_BUSY;
    50         case EBUSY: return PHYSFS_ERR_BUSY;
    50         case EBUSY: return PHYSFS_ERR_BUSY;
    51         case ENOMEM: return PHYSFS_ERR_OUT_OF_MEMORY;
    51         case ENOMEM: return PHYSFS_ERR_OUT_OF_MEMORY;
    81                 retval[dlen] = '/';
    81                 retval[dlen] = '/';
    82                 retval[dlen+1] = '\0';
    82                 retval[dlen+1] = '\0';
    83             } /* if */
    83             } /* if */
    84         } /* if */
    84         } /* if */
    85     } /* if */
    85     } /* if */
    86 
    86     
    87     return retval;
    87     return retval;
    88 } /* getUserDirByUID */
    88 } /* getUserDirByUID */
    89 
    89 
    90 
    90 
    91 char *__PHYSFS_platformCalcUserDir(void)
    91 char *__PHYSFS_platformCalcUserDir(void)
   120     return retval;
   120     return retval;
   121 } /* __PHYSFS_platformCalcUserDir */
   121 } /* __PHYSFS_platformCalcUserDir */
   122 
   122 
   123 
   123 
   124 void __PHYSFS_platformEnumerateFiles(const char *dirname,
   124 void __PHYSFS_platformEnumerateFiles(const char *dirname,
   125                                      int omitSymLinks,
       
   126                                      PHYSFS_EnumFilesCallback callback,
   125                                      PHYSFS_EnumFilesCallback callback,
   127                                      const char *origdir,
   126                                      const char *origdir,
   128                                      void *callbackdata)
   127                                      void *callbackdata)
   129 {
   128 {
   130     DIR *dir;
   129     DIR *dir;
   131     struct dirent *ent;
   130     struct dirent *ent;
   132     int bufsize = 0;
       
   133     char *buf = NULL;
   131     char *buf = NULL;
   134     int dlen = 0;
       
   135 
       
   136     if (omitSymLinks)  /* !!! FIXME: this malloc sucks. */
       
   137     {
       
   138         dlen = strlen(dirname);
       
   139         bufsize = dlen + 256;
       
   140         buf = (char *) allocator.Malloc(bufsize);
       
   141         if (buf == NULL)
       
   142             return;
       
   143         strcpy(buf, dirname);
       
   144         if (buf[dlen - 1] != '/')
       
   145         {
       
   146             buf[dlen++] = '/';
       
   147             buf[dlen] = '\0';
       
   148         } /* if */
       
   149     } /* if */
       
   150 
   132 
   151     errno = 0;
   133     errno = 0;
   152     dir = opendir(dirname);
   134     dir = opendir(dirname);
   153     if (dir == NULL)
   135     if (dir == NULL)
   154     {
   136     {
   158 
   140 
   159     while ((ent = readdir(dir)) != NULL)
   141     while ((ent = readdir(dir)) != NULL)
   160     {
   142     {
   161         if (strcmp(ent->d_name, ".") == 0)
   143         if (strcmp(ent->d_name, ".") == 0)
   162             continue;
   144             continue;
   163 
   145         else if (strcmp(ent->d_name, "..") == 0)
   164         if (strcmp(ent->d_name, "..") == 0)
       
   165             continue;
   146             continue;
   166 
       
   167         if (omitSymLinks)
       
   168         {
       
   169             PHYSFS_Stat statbuf;
       
   170             int exists = 0;
       
   171             char *p;
       
   172             int len = strlen(ent->d_name) + dlen + 1;
       
   173             if (len > bufsize)
       
   174             {
       
   175                 p = (char *) allocator.Realloc(buf, len);
       
   176                 if (p == NULL)
       
   177                     continue;
       
   178                 buf = p;
       
   179                 bufsize = len;
       
   180             } /* if */
       
   181 
       
   182             strcpy(buf + dlen, ent->d_name);
       
   183 
       
   184             if (!__PHYSFS_platformStat(buf, &exists, &statbuf))
       
   185                 continue;
       
   186             else if (!exists)
       
   187                 continue;  /* probably can't happen, but just in case. */
       
   188             else if (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK)
       
   189                 continue;
       
   190         } /* if */
       
   191 
   147 
   192         callback(callbackdata, origdir, ent->d_name);
   148         callback(callbackdata, origdir, ent->d_name);
   193     } /* while */
   149     } /* while */
   194 
   150 
   195     allocator.Free(buf);
   151     allocator.Free(buf);
   321 
   277 
   322 
   278 
   323 int __PHYSFS_platformFlush(void *opaque)
   279 int __PHYSFS_platformFlush(void *opaque)
   324 {
   280 {
   325     const int fd = *((int *) opaque);
   281     const int fd = *((int *) opaque);
   326     BAIL_IF_MACRO(fsync(fd) == -1, errcodeFromErrno(), 0);
   282     if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY)
       
   283         BAIL_IF_MACRO(fsync(fd) == -1, errcodeFromErrno(), 0);
   327     return 1;
   284     return 1;
   328 } /* __PHYSFS_platformFlush */
   285 } /* __PHYSFS_platformFlush */
   329 
   286 
   330 
   287 
   331 void __PHYSFS_platformClose(void *opaque)
   288 void __PHYSFS_platformClose(void *opaque)
   341     BAIL_IF_MACRO(remove(path) == -1, errcodeFromErrno(), 0);
   298     BAIL_IF_MACRO(remove(path) == -1, errcodeFromErrno(), 0);
   342     return 1;
   299     return 1;
   343 } /* __PHYSFS_platformDelete */
   300 } /* __PHYSFS_platformDelete */
   344 
   301 
   345 
   302 
   346 int __PHYSFS_platformStat(const char *filename, int *exists, PHYSFS_Stat *st)
   303 int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
   347 {
   304 {
   348     struct stat statbuf;
   305     struct stat statbuf;
   349 
   306 
   350     if (lstat(filename, &statbuf) == -1)
   307     BAIL_IF_MACRO(lstat(filename, &statbuf) == -1, errcodeFromErrno(), 0);
   351     {
       
   352         *exists = (errno != ENOENT);
       
   353         BAIL_MACRO(errcodeFromErrno(), 0);
       
   354     } /* if */
       
   355 
       
   356     *exists = 1;
       
   357 
   308 
   358     if (S_ISREG(statbuf.st_mode))
   309     if (S_ISREG(statbuf.st_mode))
   359     {
   310     {
   360         st->filetype = PHYSFS_FILETYPE_REGULAR;
   311         st->filetype = PHYSFS_FILETYPE_REGULAR;
   361         st->filesize = statbuf.st_size;
   312         st->filesize = statbuf.st_size;
   362     } /* if */
   313     } /* if */
   363 
   314 
   364     else if(S_ISDIR(statbuf.st_mode))
   315     else if(S_ISDIR(statbuf.st_mode))
   365     {
   316     {
   366         st->filetype = PHYSFS_FILETYPE_DIRECTORY;
   317         st->filetype = PHYSFS_FILETYPE_DIRECTORY;
       
   318         st->filesize = 0;
       
   319     } /* else if */
       
   320 
       
   321     else if(S_ISLNK(statbuf.st_mode))
       
   322     {
       
   323         st->filetype = PHYSFS_FILETYPE_SYMLINK;
   367         st->filesize = 0;
   324         st->filesize = 0;
   368     } /* else if */
   325     } /* else if */
   369 
   326 
   370     else
   327     else
   371     {
   328     {