misc/libphysfs/platform_beos.cpp
changeset 13881 99b265e0d1d0
parent 13880 5f819b90d479
child 13882 b172a5d40eee
equal deleted inserted replaced
13880:5f819b90d479 13881:99b265e0d1d0
     1 /*
       
     2  * BeOS platform-dependent support routines for PhysicsFS.
       
     3  *
       
     4  * Please see the file LICENSE.txt in the source's root directory.
       
     5  *
       
     6  *  This file written by Ryan C. Gordon.
       
     7  */
       
     8 
       
     9 #define __PHYSICSFS_INTERNAL__
       
    10 #include "physfs_platforms.h"
       
    11 
       
    12 #ifdef PHYSFS_PLATFORM_BEOS
       
    13 
       
    14 #ifdef PHYSFS_PLATFORM_HAIKU
       
    15 #include <os/kernel/OS.h>
       
    16 #include <os/app/Roster.h>
       
    17 #include <os/storage/Volume.h>
       
    18 #include <os/storage/VolumeRoster.h>
       
    19 #include <os/storage/Directory.h>
       
    20 #include <os/storage/Entry.h>
       
    21 #include <os/storage/Path.h>
       
    22 #include <os/kernel/fs_info.h>
       
    23 #include <os/device/scsi.h>
       
    24 #include <os/support/Locker.h>
       
    25 #else
       
    26 #include <be/kernel/OS.h>
       
    27 #include <be/app/Roster.h>
       
    28 #include <be/storage/Volume.h>
       
    29 #include <be/storage/VolumeRoster.h>
       
    30 #include <be/storage/Directory.h>
       
    31 #include <be/storage/Entry.h>
       
    32 #include <be/storage/Path.h>
       
    33 #include <be/kernel/fs_info.h>
       
    34 #include <be/device/scsi.h>
       
    35 #include <be/support/Locker.h>
       
    36 #endif
       
    37 
       
    38 #include <errno.h>
       
    39 #include <unistd.h>
       
    40 
       
    41 #include "physfs_internal.h"
       
    42 
       
    43 int __PHYSFS_platformInit(void)
       
    44 {
       
    45     return 1;  /* always succeed. */
       
    46 } /* __PHYSFS_platformInit */
       
    47 
       
    48 
       
    49 int __PHYSFS_platformDeinit(void)
       
    50 {
       
    51     return 1;  /* always succeed. */
       
    52 } /* __PHYSFS_platformDeinit */
       
    53 
       
    54 
       
    55 static char *getMountPoint(const char *devname, char *buf, size_t bufsize)
       
    56 {
       
    57     BVolumeRoster mounts;
       
    58     BVolume vol;
       
    59 
       
    60     mounts.Rewind();
       
    61     while (mounts.GetNextVolume(&vol) == B_NO_ERROR)
       
    62     {
       
    63         fs_info fsinfo;
       
    64         fs_stat_dev(vol.Device(), &fsinfo);
       
    65         if (strcmp(devname, fsinfo.device_name) == 0)
       
    66         {
       
    67             BDirectory directory;
       
    68             BEntry entry;
       
    69             BPath path;
       
    70             const char *str;
       
    71 
       
    72             if ( (vol.GetRootDirectory(&directory) < B_OK) ||
       
    73                  (directory.GetEntry(&entry) < B_OK) ||
       
    74                  (entry.GetPath(&path) < B_OK) ||
       
    75                  ( (str = path.Path()) == NULL) )
       
    76                 return NULL;
       
    77 
       
    78             strncpy(buf, str, bufsize-1);
       
    79             buf[bufsize-1] = '\0';
       
    80             return buf;
       
    81         } /* if */
       
    82     } /* while */
       
    83 
       
    84     return NULL;
       
    85 } /* getMountPoint */
       
    86 
       
    87 
       
    88     /*
       
    89      * This function is lifted from Simple Directmedia Layer (SDL):
       
    90      *  https://www.libsdl.org/  ... this is zlib-licensed code, too.
       
    91      */
       
    92 static void tryDir(const char *d, PHYSFS_StringCallback callback, void *data)
       
    93 {
       
    94     BDirectory dir;
       
    95     dir.SetTo(d);
       
    96     if (dir.InitCheck() != B_NO_ERROR)
       
    97         return;
       
    98 
       
    99     dir.Rewind();
       
   100     BEntry entry;
       
   101     while (dir.GetNextEntry(&entry) >= 0)
       
   102     {
       
   103         BPath path;
       
   104         const char *name;
       
   105         entry_ref e;
       
   106 
       
   107         if (entry.GetPath(&path) != B_NO_ERROR)
       
   108             continue;
       
   109 
       
   110         name = path.Path();
       
   111 
       
   112         if (entry.GetRef(&e) != B_NO_ERROR)
       
   113             continue;
       
   114 
       
   115         if (entry.IsDirectory())
       
   116         {
       
   117             if (strcmp(e.name, "floppy") != 0)
       
   118                 tryDir(name, callback, data);
       
   119             continue;
       
   120         } /* if */
       
   121 
       
   122         if (strcmp(e.name, "raw") != 0)  /* ignore partitions. */
       
   123             continue;
       
   124 
       
   125         const int devfd = open(name, O_RDONLY);
       
   126         if (devfd < 0)
       
   127             continue;
       
   128 
       
   129         device_geometry g;
       
   130         const int rc = ioctl(devfd, B_GET_GEOMETRY, &g, sizeof (g));
       
   131         close(devfd);
       
   132         if (rc < 0)
       
   133             continue;
       
   134 
       
   135         if (g.device_type != B_CD)
       
   136             continue;
       
   137 
       
   138         char mntpnt[B_FILE_NAME_LENGTH];
       
   139         if (getMountPoint(name, mntpnt, sizeof (mntpnt)))
       
   140             callback(data, mntpnt);
       
   141     } /* while */
       
   142 } /* tryDir */
       
   143 
       
   144 
       
   145 void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
       
   146 {
       
   147     tryDir("/dev/disk", cb, data);
       
   148 } /* __PHYSFS_platformDetectAvailableCDs */
       
   149 
       
   150 
       
   151 static team_id getTeamID(void)
       
   152 {
       
   153     thread_info info;
       
   154     thread_id tid = find_thread(NULL);
       
   155     get_thread_info(tid, &info);
       
   156     return info.team;
       
   157 } /* getTeamID */
       
   158 
       
   159 
       
   160 char *__PHYSFS_platformCalcBaseDir(const char *argv0)
       
   161 {
       
   162     image_info info;
       
   163     int32 cookie = 0;
       
   164 
       
   165     while (get_next_image_info(0, &cookie, &info) == B_OK)
       
   166     {
       
   167         if (info.type == B_APP_IMAGE)
       
   168             break;
       
   169     } /* while */
       
   170 
       
   171     BEntry entry(info.name, true);
       
   172     BPath path;
       
   173     status_t rc = entry.GetPath(&path);  /* (path) now has binary's path. */
       
   174     assert(rc == B_OK);
       
   175     rc = path.GetParent(&path); /* chop filename, keep directory. */
       
   176     assert(rc == B_OK);
       
   177     const char *str = path.Path();
       
   178     assert(str != NULL);
       
   179     const size_t len = strlen(str);
       
   180     char *retval = (char *) allocator.Malloc(len + 2);
       
   181     BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
       
   182     strcpy(retval, str);
       
   183     retval[len] = '/';
       
   184     retval[len+1] = '\0';
       
   185     return retval;
       
   186 } /* __PHYSFS_platformCalcBaseDir */
       
   187 
       
   188 
       
   189 char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
       
   190 {
       
   191     const char *userdir = __PHYSFS_getUserDir();
       
   192     const char *append = "config/settings/";
       
   193     const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2;
       
   194     char *retval = allocator.Malloc(len);
       
   195     BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
       
   196     snprintf(retval, len, "%s%s%s/", userdir, append, app);
       
   197     return retval;
       
   198 } /* __PHYSFS_platformCalcPrefDir */
       
   199 
       
   200 
       
   201 void *__PHYSFS_platformGetThreadID(void)
       
   202 {
       
   203     return (void *) find_thread(NULL);
       
   204 } /* __PHYSFS_platformGetThreadID */
       
   205 
       
   206 
       
   207 void *__PHYSFS_platformCreateMutex(void)
       
   208 {
       
   209     return new BLocker("PhysicsFS lock", true);
       
   210 } /* __PHYSFS_platformCreateMutex */
       
   211 
       
   212 
       
   213 void __PHYSFS_platformDestroyMutex(void *mutex)
       
   214 {
       
   215     delete ((BLocker *) mutex);
       
   216 } /* __PHYSFS_platformDestroyMutex */
       
   217 
       
   218 
       
   219 int __PHYSFS_platformGrabMutex(void *mutex)
       
   220 {
       
   221     return ((BLocker *) mutex)->Lock() ? 1 : 0;
       
   222 } /* __PHYSFS_platformGrabMutex */
       
   223 
       
   224 
       
   225 void __PHYSFS_platformReleaseMutex(void *mutex)
       
   226 {
       
   227     ((BLocker *) mutex)->Unlock();
       
   228 } /* __PHYSFS_platformReleaseMutex */
       
   229 
       
   230 
       
   231 int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
       
   232 {
       
   233     return 0;  /* just use malloc() and friends. */
       
   234 } /* __PHYSFS_platformSetDefaultAllocator */
       
   235 
       
   236 #endif  /* PHYSFS_PLATFORM_BEOS */
       
   237 
       
   238 /* end of beos.cpp ... */
       
   239