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.4 by cebix, 1999-10-15T14:50:38Z vs.
Revision 1.26 by gbeauche, 2005-08-01T05:23:02Z

# Line 1 | Line 1
1   /*
2   *  sys_unix.cpp - System dependent routines, Unix implementation
3   *
4 < *  Basilisk II (C) 1997-1999 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>
37 < #include <linux/unistd.h>
33 <
34 < #ifdef __NR__llseek
35 < _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh);
36 < #else
37 < static int _llseek(uint fd, ulong hi, ulong lo, loff_t *res, uint wh)
38 < {
39 <        if (hi)
40 <                return -1;
41 <        *res = lseek(fd, lo, wh);
42 <        if (*res == -1)
43 <                return -1;
44 <        return 0;
45 < }
46 < #endif
37 > #include <dirent.h>
38   #endif
39  
40   #if defined(__FreeBSD__) || defined(__NetBSD__)
# Line 75 | 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 119 | Line 113 | void SysMountFirstFloppy(void)
113   void SysAddFloppyPrefs(void)
114   {
115   #if defined(__linux__)
116 <        PrefsAddString("floppy", "/dev/fd0H1440");
117 <        PrefsAddString("floppy", "/dev/fd1H1440");
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) {
124 >                                if (strstr(floppy_dev->d_name, "u1440") != NULL) {
125 >                                        char fd_dev[20];
126 >                                        sprintf(fd_dev, "/dev/floppy/%s", floppy_dev->d_name);
127 >                                        PrefsAddString("floppy", fd_dev);
128 >                                }
129 >                        }
130 >                        closedir(fd_dir);
131 >                }
132 >        }
133   #elif defined(__NetBSD__)
134          PrefsAddString("floppy", "/dev/fd0a");
135          PrefsAddString("floppy", "/dev/fd1a");
136 + #elif defined(__APPLE__) && defined(__MACH__)
137 +  #if defined(AQUA) || defined(HAVE_FRAMEWORK_COREFOUNDATION)
138 +        extern  void DarwinAddFloppyPrefs(void);
139 +
140 +        DarwinAddFloppyPrefs();
141 +  #else
142 +        // Until I can convince the other guys that my Darwin code is useful,
143 +        // we just add something safe (a non-existant device):
144 +        PrefsAddString("floppy", "/dev/null");
145 +  #endif
146   #else
147          PrefsAddString("floppy", "/dev/fd0");
148          PrefsAddString("floppy", "/dev/fd1");
# Line 134 | Line 153 | void SysAddFloppyPrefs(void)
153   /*
154   *  This gets called when no "disk" prefs items are found
155   *  It scans for available HFS volumes and adds appropriate prefs items
156 + *      On OS X, we could do the same, but on an OS X machine I think it is
157 + *      very unlikely that any mounted volumes would contain a system which
158 + *      is old enough to boot a 68k Mac, so we just do nothing here for now.
159   */
160  
161   void SysAddDiskPrefs(void)
# Line 145 | Line 167 | void SysAddDiskPrefs(void)
167                  while(fgets(line, 255, f)) {
168                          // Read line
169                          int len = strlen(line);
170 <                        if (len == 0)
170 >                        if (len == 0 || line[0] == '#')
171                                  continue;
172                          line[len-1] = 0;
173  
# Line 175 | Line 197 | void SysAddCDROMPrefs(void)
197                  return;
198  
199   #if defined(__linux__)
200 <        PrefsAddString("cdrom", "/dev/cdrom");
201 < #elif defined(__FreeBSD__)
200 >        if (access("/dev/.devfsd", F_OK) < 0)
201 >                PrefsAddString("cdrom", "/dev/cdrom");
202 >        else {
203 >                DIR *cd_dir = opendir("/dev/cdroms");
204 >                if (cd_dir) {
205 >                        struct dirent *cdrom_dev;
206 >                        while ((cdrom_dev = readdir(cd_dir)) != NULL) {
207 >                                if (strcmp(cdrom_dev->d_name, ".") != 0 && strcmp(cdrom_dev->d_name, "..") != 0) {
208 >                                        char cd_dev[20];
209 >                                        sprintf(cd_dev, "/dev/cdroms/%s", cdrom_dev->d_name);
210 >                                        PrefsAddString("cdrom", cd_dev);
211 >                                }
212 >                        }
213 >                        closedir(cd_dir);
214 >                }
215 >        }
216 > #elif defined(__APPLE__) && defined(__MACH__)
217 >  #if defined(AQUA) || defined(HAVE_FRAMEWORK_COREFOUNDATION)
218 >        extern  void DarwinAddCDROMPrefs(void);
219 >
220 >        DarwinAddCDROMPrefs();
221 >  #else
222 >        // Until I can convince the other guys that my Darwin code is useful,
223 >        // we just do nothing (it is safe to have no cdrom device)
224 >  #endif
225 > #elif defined(__FreeBSD__) || defined(__NetBSD__)
226          PrefsAddString("cdrom", "/dev/cd0c");
181 #elif defined(__NetBSD__)
182        PrefsAddString("cdrom", "/dev/cd0d");
227   #endif
228   }
229  
# Line 191 | Line 235 | void SysAddCDROMPrefs(void)
235   void SysAddSerialPrefs(void)
236   {
237   #if defined(__linux__)
238 <        PrefsAddString("seriala", "/dev/ttyS0");
239 <        PrefsAddString("serialb", "/dev/ttyS1");
238 >        if (access("/dev/.devfsd", F_OK) < 0) {
239 >                PrefsAddString("seriala", "/dev/ttyS0");
240 >                PrefsAddString("serialb", "/dev/ttyS1");
241 >        } else {
242 >                PrefsAddString("seriala", "/dev/tts/0");
243 >                PrefsAddString("serialb", "/dev/tts/1");
244 >        }
245   #elif defined(__FreeBSD__)
246          PrefsAddString("seriala", "/dev/cuaa0");
247          PrefsAddString("serialb", "/dev/cuaa1");
248   #elif defined(__NetBSD__)
249          PrefsAddString("seriala", "/dev/tty00");
250          PrefsAddString("serialb", "/dev/tty01");
251 + #elif defined(__APPLE__) && defined(__MACH__)
252 +  #if defined(AQUA) || defined(HAVE_FRAMEWORK_COREFOUNDATION)
253 +        extern  void DarwinAddSerialPrefs(void);
254 +
255 +        DarwinAddSerialPrefs();
256 +  #else
257 +        // Until I can convince the other guys that my Darwin code is useful,
258 +        // we just add something safe (non-existant devices):
259 +        PrefsAddString("seriala", "/dev/null");
260 +        PrefsAddString("serialb", "/dev/null");
261 +  #endif
262   #endif
263   }
264  
# Line 251 | Line 311 | void *Sys_open(const char *name, bool re
311          bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0;
312   #endif
313  
314 + #if defined(__APPLE__) && defined(__MACH__)
315 +        //
316 +        // There is no set filename in /dev which is the cdrom,
317 +        // so we have to see if it is any of the devices that we found earlier
318 +        //
319 +        const char      *cdrom;
320 +        int                     tmp = 0;
321 +
322 +        while ( (cdrom = PrefsFindString("cdrom", tmp) ) != NULL )
323 +        {
324 +                if ( strcmp(name, cdrom) == 0 )
325 +                {
326 +                        is_cdrom = 1;
327 +                        read_only = 1;
328 +                        break;
329 +                }
330 +                ++tmp;
331 +        }
332 + #endif
333 +
334          D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write"));
335  
336          // Check if write access is allowed, set read-only flag if not
# Line 272 | Line 352 | void *Sys_open(const char *name, bool re
352          }
353  
354          // Open file/device
355 < #if defined(__linux__)
355 > #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
356          int fd = open(name, (read_only ? O_RDONLY : O_RDWR) | (is_cdrom ? O_NONBLOCK : 0));
357   #else
358          int fd = open(name, read_only ? O_RDONLY : O_RDWR);
# Line 294 | Line 374 | void *Sys_open(const char *name, bool re
374                  if (fh->is_file) {
375                          // Detect disk image file layout
376                          loff_t size = 0;
297 #if defined(__linux__)
298                        _llseek(fh->fd, 0, 0, &size, SEEK_END);
299 #else
377                          size = lseek(fd, 0, SEEK_END);
301 #endif
378                          uint8 data[256];
379                          lseek(fd, 0, SEEK_SET);
380                          read(fd, data, 256);
# Line 333 | Line 409 | void *Sys_open(const char *name, bool re
409                                          fh->is_floppy = ((st.st_rdev >> 16) == 2);
410   #endif
411                                  }
412 + #if defined(__APPLE__) && defined(__MACH__)
413 +
414 +                                // In OS X, the device name is OK for sending ioctls to,
415 +                                // but not for reading raw CDROM data from.
416 +                                // (it seems to have extra data padded in)
417 +                                //
418 +                                // So, we keep the already opened fiole handle,
419 +                                // and open a slightly different file for CDROM data
420 +                                //
421 +                                if ( is_cdrom )
422 +                                {
423 +                                        fh->ioctl_name  = fh->name;
424 +                                        fh->ioctl_fd    = fh->fd;
425 +
426 +                                        fh->name = (char *) malloc(strlen(name) + 2);
427 +                                        if ( fh->name )
428 +                                        {
429 +                                                *fh->name = '\0';
430 +                                                strcat(fh->name, name);
431 +                                                strcat(fh->name, "s1");
432 +                                                fh->fd = open(fh->name, (read_only ? O_RDONLY : O_RDWR));
433 +                                                if ( fh->fd < 0 ) {
434 +                                                        printf("WARNING: Cannot open %s (%s)\n",
435 +                                                                                        fh->name, strerror(errno));
436 +                                                        return NULL;
437 +                                                }
438 +                                        }
439 +                                }
440 + #endif
441                          }
442                  }
443                  if (fh->is_floppy && first_floppy == NULL)
# Line 374 | Line 479 | size_t Sys_read(void *arg, void *buffer,
479                  return 0;
480  
481          // Seek to position
377 #if defined(__linux__)
378        loff_t pos = offset + fh->start_byte, res;
379        if (_llseek(fh->fd, pos >> 32, pos, &res, SEEK_SET) < 0)
380                return 0;
381 #else
482          if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0)
483                  return 0;
384 #endif
484  
485          // Read data
486          return read(fh->fd, buffer, length);
# Line 400 | Line 499 | size_t Sys_write(void *arg, void *buffer
499                  return 0;
500  
501          // Seek to position
403 #if defined(__linux__)
404        loff_t pos = offset + fh->start_byte, res;
405        if (_llseek(fh->fd, pos >> 32, pos, &res, SEEK_SET) < 0)
406                return 0;
407 #else
502          if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0)
503                  return 0;
410 #endif
504  
505          // Write data
506          return write(fh->fd, buffer, length);
# Line 428 | Line 521 | loff_t SysGetFileSize(void *arg)
521                  return fh->file_size;
522          else {
523   #if defined(__linux__)
524 <                loff_t pos = 0;
525 <                _llseek(fh->fd, 0, 0, &pos, SEEK_END);
526 <                return pos - fh->start_byte;
524 >                long blocks;
525 >                if (ioctl(fh->fd, BLKGETSIZE, &blocks) < 0)
526 >                        return 0;
527 >                D(bug(" BLKGETSIZE returns %d blocks\n", blocks));
528 >                return (loff_t)blocks * 512;
529   #else
530                  return lseek(fh->fd, 0, SEEK_END) - fh->start_byte;
531   #endif
# Line 453 | Line 548 | void SysEject(void *arg)
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
552 +                fh->fd = open(fh->name, fh->read_only ? O_RDONLY : O_RDWR);
553          } else if (fh->is_cdrom) {
554                  ioctl(fh->fd, CDROMEJECT);
555                  close(fh->fd);  // Close and reopen so the driver will see the media change
# Line 461 | Line 558 | void SysEject(void *arg)
558   #elif defined(__FreeBSD__) || defined(__NetBSD__)
559          if (fh->is_floppy) {
560                  fsync(fh->fd);
464                //ioctl(fh->fd, FDFLUSH);
465                //ioctl(fh->fd, FDEJECT);
561          } else if (fh->is_cdrom) {
562                  ioctl(fh->fd, CDIOCEJECT);
563                  close(fh->fd);  // Close and reopen so the driver will see the media change
564                  fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK);
565          }
566 + #elif defined(__APPLE__) && defined(__MACH__)
567 +        if ( fh->is_cdrom ) {
568 +
569 +                // Stolen from IOKit/storage/IOMediaBSDClient.h
570 +                #define DKIOCEJECT _IO('d', 21)
571 +
572 +                close(fh->fd);
573 +                if ( ioctl(fh->ioctl_fd, DKIOCEJECT) < 0 )
574 +                {
575 +                        printf("ioctl(DKIOCEJECT) failed on file %s: %s\n",
576 +                                                                fh->ioctl_name, strerror(errno));
577 +
578 +                        // If we are running OSX, the device may be is busy
579 +                        // due to the Finder having the disk mounted and open,
580 +                        // so we have to use another method.
581 +
582 +                        // The only problem is that this takes about 5 seconds:
583 +
584 +                        char    *cmd = (char *) malloc(30+sizeof(fh->name));
585 +
586 +                        if ( ! cmd )
587 +                                return;
588 +                        close(fh->ioctl_fd);
589 +                        sprintf(cmd, "diskutil eject %s 2>&1 >/dev/null", fh->name);
590 +                        system(cmd);
591 +                }
592 +        }
593   #endif
594   }
595  
# Line 544 | Line 666 | bool SysIsDiskInserted(void *arg)
666          } else if (fh->is_floppy) {
667                  char block[512];
668                  lseek(fh->fd, 0, SEEK_SET);
669 <                return read(fh->fd, block, 512) == 512;
669 >                ssize_t actual = read(fh->fd, block, 512);
670 >                if (actual < 0) {
671 >                        close(fh->fd);  // Close and reopen so the driver will see the media change
672 >                        fh->fd = open(fh->name, fh->read_only ? O_RDONLY : O_RDWR);
673 >                        actual = read(fh->fd, block, 512);
674 >                }
675 >                return actual == 512;
676          } else if (fh->is_cdrom) {
677 + #ifdef CDROM_MEDIA_CHANGED
678 +                if (fh->cdrom_cap & CDC_MEDIA_CHANGED) {
679 +                        // If we don't do this, all attempts to read from a disc fail
680 +                        // once the tray has been opened (altough the TOC reads fine).
681 +                        // Can somebody explain this to me?
682 +                        if (ioctl(fh->fd, CDROM_MEDIA_CHANGED) == 1) {
683 +                                close(fh->fd);
684 +                                fh->fd = open(fh->name, O_RDONLY | O_NONBLOCK);
685 +                        }
686 +                }
687 + #endif
688   #ifdef CDROM_DRIVE_STATUS
689                  if (fh->cdrom_cap & CDC_DRIVE_STATUS) {
690                          return ioctl(fh->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK;
# Line 657 | Line 796 | bool SysCDReadTOC(void *arg, uint8 *toc)
796                  *toc++ = toc_size >> 8;
797                  *toc++ = toc_size & 0xff;
798                  return true;
799 + #elif defined(__APPLE__) && defined(__MACH__) && defined(MAC_OS_X_VERSION_10_2) && defined(HAVE_FRAMEWORK_COREFOUNDATION)
800 +                extern  bool    DarwinCDReadTOC(char *name, uint8 *toc);
801 +
802 +                return  DarwinCDReadTOC(fh->name, toc);
803   #elif defined(__FreeBSD__)
804                  uint8 *p = toc + 2;
805  
# Line 727 | Line 870 | bool SysCDReadTOC(void *arg, uint8 *toc)
870                  *toc++ = toc_size >> 8;
871                  *toc++ = toc_size & 0xff;
872                  return true;
873 + #else
874 +                return false;
875   #endif
876          } else
877                  return false;
# Line 790 | Line 935 | bool SysCDGetPosition(void *arg, uint8 *
935                  *pos++ = chan.data->what.position.reladdr.msf.second;
936                  *pos++ = chan.data->what.position.reladdr.msf.frame;
937                  return true;
938 + #else
939 +                return false;
940   #endif
941          } else
942                  return false;
# Line 825 | Line 972 | bool SysCDPlay(void *arg, uint8 start_m,
972                  play.end_s = end_s;
973                  play.end_f = end_f;
974                  return ioctl(fh->fd, CDIOCPLAYMSF, &play) == 0;
975 + #else
976 +                return false;
977   #endif
978          } else
979                  return false;
# Line 846 | Line 995 | bool SysCDPause(void *arg)
995                  return ioctl(fh->fd, CDROMPAUSE) == 0;
996   #elif defined(__FreeBSD__) || defined(__NetBSD__)
997                  return ioctl(fh->fd, CDIOCPAUSE) == 0;
998 + #else
999 +                return false;
1000   #endif
1001          } else
1002                  return false;
# Line 867 | Line 1018 | bool SysCDResume(void *arg)
1018                  return ioctl(fh->fd, CDROMRESUME) == 0;
1019   #elif defined(__FreeBSD__) || defined(__NetBSD__)
1020                  return ioctl(fh->fd, CDIOCRESUME) == 0;
1021 + #else
1022 +                return false;
1023   #endif
1024          } else
1025                  return false;
# Line 888 | Line 1041 | bool SysCDStop(void *arg, uint8 lead_out
1041                  return ioctl(fh->fd, CDROMSTOP) == 0;
1042   #elif defined(__FreeBSD__) || defined(__NetBSD__)
1043                  return ioctl(fh->fd, CDIOCSTOP) == 0;
1044 + #else
1045 +                return false;
1046   #endif
1047          } else
1048                  return false;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines