ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/sys_unix.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/sys_unix.cpp (file contents):
Revision 1.18 by cebix, 2002-04-28T14:06:17Z vs.
Revision 1.28 by cebix, 2005-11-24T17:23:43Z

# Line 1 | Line 1
1   /*
2   *  sys_unix.cpp - System dependent routines, Unix implementation
3   *
4 < *  Basilisk II (C) 1997-2002 Christian Bauer
4 > *  Basilisk II (C) 1997-2005 Christian Bauer
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 24 | Line 24
24   #include <sys/stat.h>
25   #include <errno.h>
26  
27 + #ifdef HAVE_AVAILABILITYMACROS_H
28 + #include <AvailabilityMacros.h>
29 + #endif
30 +
31   #ifdef __linux__
32   #include <sys/mount.h>
33   #include <linux/cdrom.h>
34   #include <linux/fd.h>
35   #include <linux/major.h>
36   #include <linux/kdev_t.h>
33 #include <linux/unistd.h>
37   #include <dirent.h>
35
36 #ifdef __NR__llseek
37 _syscall5(int, _llseek, unsigned int, fd, unsigned long, hi, unsigned long, lo, loff_t *, res, unsigned int, wh);
38 #else
39 static int _llseek(unsigned int fd, unsigned long hi, unsigned long lo, loff_t *res, unsigned int wh)
40 {
41        if (hi)
42                return -1;
43        *res = lseek(fd, lo, wh);
44        if (*res == -1)
45                return -1;
46        return 0;
47 }
48 #endif
38   #endif
39  
40   #if defined(__FreeBSD__) || defined(__NetBSD__)
# Line 64 | Line 53 | static int _llseek(unsigned int fd, unsi
53  
54   // File handles are pointers to these structures
55   struct file_handle {
56 <        char *name;             // Copy of device/file name
56 >        char *name;                     // Copy of device/file name
57          int fd;
58          bool is_file;           // Flag: plain file or /dev/something?
59          bool is_floppy;         // Flag: floppy device
# Line 77 | Line 66 | struct file_handle {
66          int cdrom_cap;          // CD-ROM capability flags (only valid if is_cdrom is true)
67   #elif defined(__FreeBSD__)
68          struct ioc_capability cdrom_cap;
69 + #elif defined(__APPLE__) && defined(__MACH__)
70 +        char    *ioctl_name;    // For CDs on OS X - a device for special ioctls
71 +        int             ioctl_fd;
72   #endif
73   };
74  
# Line 121 | Line 113 | void SysMountFirstFloppy(void)
113   void SysAddFloppyPrefs(void)
114   {
115   #if defined(__linux__)
116 <        if (access("/dev/.devfsd", F_OK) < 0) {
117 <                PrefsAddString("floppy", "/dev/fd0u1440");
118 <                PrefsAddString("floppy", "/dev/fd1u1440");
119 <        } else {
120 <                DIR *fd_dir = opendir("/dev/floppy");
121 <                if (fd_dir) {
122 <                        struct dirent *floppy_dev;
123 <                        while ((floppy_dev = readdir(fd_dir)) != NULL) {
132 <                                if (strstr(floppy_dev->d_name, "u1440") != NULL) {
133 <                                        char fd_dev[20];
134 <                                        sprintf(fd_dev, "/dev/floppy/%s", floppy_dev->d_name);
135 <                                        PrefsAddString("floppy", fd_dev);
136 <                                }
116 >        DIR *fd_dir = opendir("/dev/floppy");
117 >        if (fd_dir) {
118 >                struct dirent *floppy_dev;
119 >                while ((floppy_dev = readdir(fd_dir)) != NULL) {
120 >                        if (strstr(floppy_dev->d_name, "u1440") != NULL) {
121 >                                char fd_dev[20];
122 >                                sprintf(fd_dev, "/dev/floppy/%s", floppy_dev->d_name);
123 >                                PrefsAddString("floppy", fd_dev);
124                          }
138                        closedir(fd_dir);
125                  }
126 +                closedir(fd_dir);
127 +        } else {
128 +                PrefsAddString("floppy", "/dev/fd0");
129 +                PrefsAddString("floppy", "/dev/fd1");
130          }
131   #elif defined(__NetBSD__)
132          PrefsAddString("floppy", "/dev/fd0a");
133          PrefsAddString("floppy", "/dev/fd1a");
134 + #elif defined(__APPLE__) && defined(__MACH__)
135 +  #if defined(AQUA) || defined(HAVE_FRAMEWORK_COREFOUNDATION)
136 +        extern  void DarwinAddFloppyPrefs(void);
137 +
138 +        DarwinAddFloppyPrefs();
139 +  #else
140 +        // Until I can convince the other guys that my Darwin code is useful,
141 +        // we just add something safe (a non-existant device):
142 +        PrefsAddString("floppy", "/dev/null");
143 +  #endif
144   #else
145          PrefsAddString("floppy", "/dev/fd0");
146          PrefsAddString("floppy", "/dev/fd1");
# Line 151 | Line 151 | void SysAddFloppyPrefs(void)
151   /*
152   *  This gets called when no "disk" prefs items are found
153   *  It scans for available HFS volumes and adds appropriate prefs items
154 + *      On OS X, we could do the same, but on an OS X machine I think it is
155 + *      very unlikely that any mounted volumes would contain a system which
156 + *      is old enough to boot a 68k Mac, so we just do nothing here for now.
157   */
158  
159   void SysAddDiskPrefs(void)
# Line 208 | Line 211 | void SysAddCDROMPrefs(void)
211                          closedir(cd_dir);
212                  }
213          }
214 + #elif defined(__APPLE__) && defined(__MACH__)
215 +  #if defined(AQUA) || defined(HAVE_FRAMEWORK_COREFOUNDATION)
216 +        extern  void DarwinAddCDROMPrefs(void);
217 +
218 +        DarwinAddCDROMPrefs();
219 +  #else
220 +        // Until I can convince the other guys that my Darwin code is useful,
221 +        // we just do nothing (it is safe to have no cdrom device)
222 +  #endif
223   #elif defined(__FreeBSD__) || defined(__NetBSD__)
224          PrefsAddString("cdrom", "/dev/cd0c");
225   #endif
# Line 234 | Line 246 | void SysAddSerialPrefs(void)
246   #elif defined(__NetBSD__)
247          PrefsAddString("seriala", "/dev/tty00");
248          PrefsAddString("serialb", "/dev/tty01");
249 + #elif defined(__APPLE__) && defined(__MACH__)
250 +  #if defined(AQUA) || defined(HAVE_FRAMEWORK_COREFOUNDATION)
251 +        extern  void DarwinAddSerialPrefs(void);
252 +
253 +        DarwinAddSerialPrefs();
254 +  #else
255 +        // Until I can convince the other guys that my Darwin code is useful,
256 +        // we just add something safe (non-existant devices):
257 +        PrefsAddString("seriala", "/dev/null");
258 +        PrefsAddString("serialb", "/dev/null");
259 +  #endif
260   #endif
261   }
262  
# Line 285 | Line 308 | void *Sys_open(const char *name, bool re
308   #else
309          bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0;
310   #endif
311 +        bool is_floppy = strncmp(name, "/dev/fd", 7) == 0;
312 +
313 + #if defined(__APPLE__) && defined(__MACH__)
314 +        //
315 +        // There is no set filename in /dev which is the cdrom,
316 +        // so we have to see if it is any of the devices that we found earlier
317 +        //
318 +        const char      *cdrom;
319 +        int                     tmp = 0;
320 +
321 +        while ( (cdrom = PrefsFindString("cdrom", tmp) ) != NULL )
322 +        {
323 +                if ( strcmp(name, cdrom) == 0 )
324 +                {
325 +                        is_cdrom = 1;
326 +                        read_only = 1;
327 +                        break;
328 +                }
329 +                ++tmp;
330 +        }
331 + #endif
332  
333          D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write"));
334  
# Line 317 | Line 361 | void *Sys_open(const char *name, bool re
361                  read_only = true;
362                  fd = open(name, O_RDONLY);
363          }
364 <        if (fd >= 0) {
364 >        if (fd >= 0 || is_floppy) { // Floppy open fails if there's no disk inserted
365                  file_handle *fh = new file_handle;
366                  fh->name = strdup(name);
367                  fh->fd = fd;
368                  fh->is_file = is_file;
369                  fh->read_only = read_only;
370                  fh->start_byte = 0;
371 <                fh->is_floppy = false;
372 <                fh->is_cdrom = false;
371 >                fh->is_floppy = is_floppy;
372 >                fh->is_cdrom = is_cdrom;
373                  if (fh->is_file) {
374                          // Detect disk image file layout
375                          loff_t size = 0;
332 #if defined(__linux__)
333                        _llseek(fh->fd, 0, 0, &size, SEEK_END);
334 #else
376                          size = lseek(fd, 0, SEEK_END);
336 #endif
377                          uint8 data[256];
378                          lseek(fd, 0, SEEK_SET);
379                          read(fd, data, 256);
# Line 368 | Line 408 | void *Sys_open(const char *name, bool re
408                                          fh->is_floppy = ((st.st_rdev >> 16) == 2);
409   #endif
410                                  }
411 + #if defined(__APPLE__) && defined(__MACH__)
412 +
413 +                                // In OS X, the device name is OK for sending ioctls to,
414 +                                // but not for reading raw CDROM data from.
415 +                                // (it seems to have extra data padded in)
416 +                                //
417 +                                // So, we keep the already opened fiole handle,
418 +                                // and open a slightly different file for CDROM data
419 +                                //
420 +                                if ( is_cdrom )
421 +                                {
422 +                                        fh->ioctl_name  = fh->name;
423 +                                        fh->ioctl_fd    = fh->fd;
424 +
425 +                                        fh->name = (char *) malloc(strlen(name) + 2);
426 +                                        if ( fh->name )
427 +                                        {
428 +                                                *fh->name = '\0';
429 +                                                strcat(fh->name, name);
430 +                                                strcat(fh->name, "s1");
431 +                                                fh->fd = open(fh->name, (read_only ? O_RDONLY : O_RDWR));
432 +                                                if ( fh->fd < 0 ) {
433 +                                                        printf("WARNING: Cannot open %s (%s)\n",
434 +                                                                                        fh->name, strerror(errno));
435 +                                                        return NULL;
436 +                                                }
437 +                                        }
438 +                                }
439 + #endif
440                          }
441                  }
442                  if (fh->is_floppy && first_floppy == NULL)
# Line 390 | Line 459 | void Sys_close(void *arg)
459          if (!fh)
460                  return;
461  
462 <        close(fh->fd);
462 >        if (fh->fd >= 0)
463 >                close(fh->fd);
464          if (fh->name)
465                  free(fh->name);
466          delete fh;
# Line 409 | Line 479 | size_t Sys_read(void *arg, void *buffer,
479                  return 0;
480  
481          // Seek to position
412 #if defined(__linux__)
413        loff_t pos = offset + fh->start_byte, res;
414        if (_llseek(fh->fd, pos >> 32, pos, &res, SEEK_SET) < 0)
415                return 0;
416 #else
482          if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0)
483                  return 0;
419 #endif
484  
485          // Read data
486          return read(fh->fd, buffer, length);
# Line 435 | Line 499 | size_t Sys_write(void *arg, void *buffer
499                  return 0;
500  
501          // Seek to position
438 #if defined(__linux__)
439        loff_t pos = offset + fh->start_byte, res;
440        if (_llseek(fh->fd, pos >> 32, pos, &res, SEEK_SET) < 0)
441                return 0;
442 #else
502          if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0)
503                  return 0;
445 #endif
504  
505          // Write data
506          return write(fh->fd, buffer, length);
# Line 487 | Line 545 | void SysEject(void *arg)
545  
546   #if defined(__linux__)
547          if (fh->is_floppy) {
548 <                fsync(fh->fd);
549 <                ioctl(fh->fd, FDFLUSH);
550 <                ioctl(fh->fd, FDEJECT);
551 <                close(fh->fd);  // Close and reopen so the driver will see the media change
548 >                if (fh->fd >= 0) {
549 >                        fsync(fh->fd);
550 >                        ioctl(fh->fd, FDFLUSH);
551 >                        ioctl(fh->fd, FDEJECT);
552 >                        close(fh->fd);  // Close and reopen so the driver will see the media change
553 >                }
554                  fh->fd = open(fh->name, fh->read_only ? O_RDONLY : O_RDWR);
555          } else if (fh->is_cdrom) {
556                  ioctl(fh->fd, CDROMEJECT);
# Line 505 | Line 565 | void SysEject(void *arg)
565                  close(fh->fd);  // Close and reopen so the driver will see the media change
566                  fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK);
567          }
568 + #elif defined(__APPLE__) && defined(__MACH__)
569 +        if ( fh->is_cdrom ) {
570 +
571 +                // Stolen from IOKit/storage/IOMediaBSDClient.h
572 +                #define DKIOCEJECT _IO('d', 21)
573 +
574 +                close(fh->fd);
575 +                if ( ioctl(fh->ioctl_fd, DKIOCEJECT) < 0 )
576 +                {
577 +                        printf("ioctl(DKIOCEJECT) failed on file %s: %s\n",
578 +                                                                fh->ioctl_name, strerror(errno));
579 +
580 +                        // If we are running OSX, the device may be is busy
581 +                        // due to the Finder having the disk mounted and open,
582 +                        // so we have to use another method.
583 +
584 +                        // The only problem is that this takes about 5 seconds:
585 +
586 +                        char    *cmd = (char *) malloc(30+sizeof(fh->name));
587 +
588 +                        if ( ! cmd )
589 +                                return;
590 +                        close(fh->ioctl_fd);
591 +                        sprintf(cmd, "diskutil eject %s 2>&1 >/dev/null", fh->name);
592 +                        system(cmd);
593 +                }
594 +        }
595   #endif
596   }
597  
# Line 536 | Line 623 | bool SysIsReadOnly(void *arg)
623  
624   #if defined(__linux__)
625          if (fh->is_floppy) {
626 <                struct floppy_drive_struct stat;
627 <                ioctl(fh->fd, FDGETDRVSTAT, &stat);
628 <                return !(stat.flags & FD_DISK_WRITABLE);
626 >                if (fh->fd >= 0) {
627 >                        struct floppy_drive_struct stat;
628 >                        ioctl(fh->fd, FDGETDRVSTAT, &stat);
629 >                        return !(stat.flags & FD_DISK_WRITABLE);
630 >                } else
631 >                        return true;
632          } else
633   #endif
634                  return fh->read_only;
# Line 711 | Line 801 | bool SysCDReadTOC(void *arg, uint8 *toc)
801                  *toc++ = toc_size >> 8;
802                  *toc++ = toc_size & 0xff;
803                  return true;
804 + #elif defined(__APPLE__) && defined(__MACH__) && defined(MAC_OS_X_VERSION_10_2) && defined(HAVE_FRAMEWORK_COREFOUNDATION)
805 +                extern  bool    DarwinCDReadTOC(char *name, uint8 *toc);
806 +
807 +                return  DarwinCDReadTOC(fh->name, toc);
808   #elif defined(__FreeBSD__)
809                  uint8 *p = toc + 2;
810  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines