1 |
|
/* |
2 |
|
* sys_unix.cpp - System dependent routines, Unix implementation |
3 |
|
* |
4 |
< |
* Basilisk II (C) 1997-2005 Christian Bauer |
4 |
> |
* Basilisk II (C) 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 |
35 |
|
#include <linux/major.h> |
36 |
|
#include <linux/kdev_t.h> |
37 |
|
#include <dirent.h> |
38 |
+ |
#include <limits.h> |
39 |
|
#endif |
40 |
|
|
41 |
|
#if defined(__FreeBSD__) || defined(__NetBSD__) |
57 |
|
#include "user_strings.h" |
58 |
|
#include "sys.h" |
59 |
|
|
60 |
+ |
#if defined(BINCUE) |
61 |
+ |
#include "bincue_unix.h" |
62 |
+ |
#endif |
63 |
+ |
|
64 |
+ |
#if defined(HAVE_LIBVHD) |
65 |
+ |
#include "vhd_unix.h" |
66 |
+ |
#endif |
67 |
+ |
|
68 |
+ |
|
69 |
|
#define DEBUG 0 |
70 |
|
#include "debug.h" |
71 |
|
|
62 |
– |
|
72 |
|
// File handles are pointers to these structures |
73 |
|
struct file_handle { |
74 |
< |
char *name; // Copy of device/file name |
74 |
> |
char *name; // Copy of device/file name |
75 |
|
int fd; |
76 |
+ |
|
77 |
|
bool is_file; // Flag: plain file or /dev/something? |
78 |
|
bool is_floppy; // Flag: floppy device |
79 |
|
bool is_cdrom; // Flag: CD-ROM device |
80 |
|
bool read_only; // Copy of Sys_open() flag |
81 |
+ |
|
82 |
|
loff_t start_byte; // Size of file header (if any) |
83 |
|
loff_t file_size; // Size of file data (only valid if is_file is true) |
84 |
+ |
|
85 |
|
bool is_media_present; // Flag: media is inserted and available |
86 |
|
|
87 |
|
#if defined(__linux__) |
89 |
|
#elif defined(__FreeBSD__) |
90 |
|
struct ioc_capability cdrom_cap; |
91 |
|
#elif defined(__APPLE__) && defined(__MACH__) |
92 |
< |
char *ioctl_name; // For CDs on OS X - a device for special ioctls |
93 |
< |
int ioctl_fd; |
92 |
> |
char *ioctl_name; // For CDs on OS X - a device for special ioctls |
93 |
> |
int ioctl_fd; |
94 |
> |
#endif |
95 |
> |
|
96 |
> |
#if defined(BINCUE) |
97 |
> |
bool is_bincue; // Flag: BIN CUE file |
98 |
> |
void *bincue_fd; |
99 |
> |
#endif |
100 |
> |
|
101 |
> |
#if defined(HAVE_LIBVHD) |
102 |
> |
bool is_vhd; // Flag: VHD file |
103 |
> |
void *vhd_fd; |
104 |
|
#endif |
105 |
|
}; |
106 |
|
|
459 |
|
|
460 |
|
void cdrom_close(file_handle *fh) |
461 |
|
{ |
462 |
+ |
|
463 |
|
if (fh->fd >= 0) { |
464 |
|
close(fh->fd); |
465 |
|
fh->fd = -1; |
518 |
|
/* |
519 |
|
* Open file/device, create new file handle (returns NULL on error) |
520 |
|
*/ |
521 |
+ |
|
522 |
+ |
static file_handle *open_filehandle(const char *name) |
523 |
+ |
{ |
524 |
+ |
file_handle *fh = new file_handle; |
525 |
+ |
memset(fh, 0, sizeof(file_handle)); |
526 |
+ |
fh->name = strdup(name); |
527 |
+ |
fh->fd = -1; |
528 |
+ |
#if defined __MACOSX__ |
529 |
+ |
fh->ioctl_fd = -1; |
530 |
+ |
fh->ioctl_name = NULL; |
531 |
+ |
#endif |
532 |
+ |
return fh; |
533 |
+ |
} |
534 |
|
|
535 |
|
void *Sys_open(const char *name, bool read_only) |
536 |
|
{ |
584 |
|
} |
585 |
|
|
586 |
|
// Open file/device |
587 |
+ |
|
588 |
+ |
#if defined(BINCUE) |
589 |
+ |
void *binfd = open_bincue(name); |
590 |
+ |
if (binfd) { |
591 |
+ |
file_handle *fh = open_filehandle(name); |
592 |
+ |
D(bug("opening %s as bincue\n", name)); |
593 |
+ |
fh->bincue_fd = binfd; |
594 |
+ |
fh->is_bincue = true; |
595 |
+ |
fh->read_only = true; |
596 |
+ |
fh->is_media_present = true; |
597 |
+ |
sys_add_file_handle(fh); |
598 |
+ |
return fh; |
599 |
+ |
} |
600 |
+ |
#endif |
601 |
+ |
|
602 |
+ |
|
603 |
+ |
#if defined(HAVE_LIBVHD) |
604 |
+ |
int vhdsize; |
605 |
+ |
void *vhdfd = vhd_unix_open(name, &vhdsize, read_only); |
606 |
+ |
if (vhdfd) { |
607 |
+ |
file_handle *fh = open_filehandle(name); |
608 |
+ |
D(bug("opening %s as vnd\n", name)); |
609 |
+ |
fh->is_vhd = true; |
610 |
+ |
fh->vhd_fd = vhdfd; |
611 |
+ |
fh->read_only = read_only; |
612 |
+ |
fh->file_size = vhdsize; |
613 |
+ |
fh->is_media_present = true; |
614 |
+ |
sys_add_file_handle(fh); |
615 |
+ |
return fh; |
616 |
+ |
} |
617 |
+ |
#endif |
618 |
+ |
|
619 |
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MACOSX__) |
620 |
|
int fd = open(name, (read_only ? O_RDONLY : O_RDWR) | (is_cdrom ? O_NONBLOCK : 0)); |
621 |
|
#else |
627 |
|
fd = open(name, O_RDONLY); |
628 |
|
} |
629 |
|
if (fd >= 0 || is_polled_media) { |
630 |
< |
file_handle *fh = new file_handle; |
563 |
< |
fh->name = strdup(name); |
630 |
> |
file_handle *fh = open_filehandle(name); |
631 |
|
fh->fd = fd; |
632 |
|
fh->is_file = is_file; |
633 |
|
fh->read_only = read_only; |
567 |
– |
fh->start_byte = 0; |
634 |
|
fh->is_floppy = is_floppy; |
635 |
|
fh->is_cdrom = is_cdrom; |
570 |
– |
fh->is_media_present = false; |
571 |
– |
#if defined __MACOSX__ |
572 |
– |
fh->ioctl_fd = -1; |
573 |
– |
fh->ioctl_name = NULL; |
574 |
– |
#endif |
636 |
|
if (fh->is_file) { |
637 |
|
fh->is_media_present = true; |
638 |
|
// Detect disk image file layout |
656 |
|
if (fh->cdrom_cap < 0) |
657 |
|
fh->cdrom_cap = 0; |
658 |
|
} |
598 |
– |
#else |
599 |
– |
fh->cdrom_cap = 0; |
659 |
|
#endif |
660 |
|
#elif defined(__FreeBSD__) |
661 |
|
fh->is_floppy = ((st.st_rdev >> 16) == 2); |
664 |
|
if (ioctl(fh->fd, CDIOCCAPABILITY, &fh->cdrom_cap) < 0) |
665 |
|
memset(&fh->cdrom_cap, 0, sizeof(fh->cdrom_cap)); |
666 |
|
} |
608 |
– |
#else |
609 |
– |
fh->cdrom_cap = 0; |
667 |
|
#endif |
668 |
|
#elif defined(__NetBSD__) |
669 |
|
fh->is_floppy = ((st.st_rdev >> 16) == 2); |
702 |
|
|
703 |
|
sys_remove_file_handle(fh); |
704 |
|
|
705 |
+ |
#if defined(HAVE_LIBVHD) |
706 |
+ |
if (fh->is_vhd) |
707 |
+ |
vhd_unix_close(fh->vhd_fd); |
708 |
+ |
#endif |
709 |
+ |
|
710 |
+ |
#if defined(BINCUE) |
711 |
+ |
if (fh->is_bincue) |
712 |
+ |
close_bincue(fh->bincue_fd); |
713 |
+ |
#endif |
714 |
+ |
|
715 |
|
if (fh->is_cdrom) |
716 |
|
cdrom_close(fh); |
717 |
|
if (fh->fd >= 0) |
733 |
|
if (!fh) |
734 |
|
return 0; |
735 |
|
|
736 |
+ |
#if defined(BINCUE) |
737 |
+ |
if (fh->is_bincue) |
738 |
+ |
return read_bincue(fh->bincue_fd, buffer, offset, length); |
739 |
+ |
#endif |
740 |
+ |
|
741 |
+ |
#if defined(HAVE_LIBVHD) |
742 |
+ |
if (fh->is_vhd) |
743 |
+ |
return vhd_unix_read(fh->vhd_fd, buffer, offset, length); |
744 |
+ |
#endif |
745 |
+ |
|
746 |
|
// Seek to position |
747 |
|
if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0) |
748 |
|
return 0; |
763 |
|
if (!fh) |
764 |
|
return 0; |
765 |
|
|
766 |
+ |
#if defined(HAVE_LIBVHD) |
767 |
+ |
if (fh->is_vhd) |
768 |
+ |
return vhd_unix_write(fh->vhd_fd, buffer, offset, length); |
769 |
+ |
#endif |
770 |
+ |
|
771 |
|
// Seek to position |
772 |
|
if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0) |
773 |
|
return 0; |
787 |
|
if (!fh) |
788 |
|
return true; |
789 |
|
|
790 |
+ |
#if defined(BINCUE) |
791 |
+ |
if (fh->is_bincue) |
792 |
+ |
return size_bincue(fh->bincue_fd); |
793 |
+ |
#endif |
794 |
+ |
|
795 |
+ |
#if defined(HAVE_LIBVHD) |
796 |
+ |
if (fh->is_vhd) |
797 |
+ |
return fh->file_size; |
798 |
+ |
#endif |
799 |
+ |
|
800 |
|
if (fh->is_file) |
801 |
|
return fh->file_size; |
802 |
|
else { |
711 |
– |
#if defined(__linux__) |
803 |
|
long blocks; |
804 |
+ |
#if defined(__linux__) |
805 |
|
if (ioctl(fh->fd, BLKGETSIZE, &blocks) < 0) |
806 |
|
return 0; |
807 |
|
D(bug(" BLKGETSIZE returns %d blocks\n", blocks)); |
930 |
|
if (!fh) |
931 |
|
return true; |
932 |
|
|
933 |
+ |
#if defined(HAVE_LIBVHD) |
934 |
+ |
if (fh->is_vhd) |
935 |
+ |
return true; |
936 |
+ |
#endif |
937 |
+ |
|
938 |
|
if (fh->is_file) |
939 |
|
return true; |
940 |
|
else if (fh->is_floppy || fh->is_cdrom) |
954 |
|
if (!fh) |
955 |
|
return false; |
956 |
|
|
957 |
+ |
#if defined(HAVE_LIBVHD) |
958 |
+ |
if (fh->is_vhd) |
959 |
+ |
return true; |
960 |
+ |
#endif |
961 |
+ |
|
962 |
|
if (fh->is_file) { |
963 |
|
return true; |
964 |
|
|
1052 |
|
if (!fh) |
1053 |
|
return false; |
1054 |
|
|
1055 |
+ |
#if defined(BINCUE) |
1056 |
+ |
if (fh->is_bincue) |
1057 |
+ |
return readtoc_bincue(fh->bincue_fd, toc); |
1058 |
+ |
#endif |
1059 |
+ |
|
1060 |
|
if (fh->is_cdrom) { |
1061 |
+ |
|
1062 |
|
#if defined(__linux__) |
1063 |
|
uint8 *p = toc + 2; |
1064 |
|
|
1199 |
|
if (!fh) |
1200 |
|
return false; |
1201 |
|
|
1202 |
+ |
#if defined(BINCUE) |
1203 |
+ |
if (fh->is_bincue) |
1204 |
+ |
return GetPosition_bincue(fh->bincue_fd, pos); |
1205 |
+ |
#endif |
1206 |
+ |
|
1207 |
|
if (fh->is_cdrom) { |
1208 |
|
#if defined(__linux__) |
1209 |
|
cdrom_subchnl chan; |
1269 |
|
if (!fh) |
1270 |
|
return false; |
1271 |
|
|
1272 |
+ |
#if defined(BINCUE) |
1273 |
+ |
if (fh->is_bincue) |
1274 |
+ |
return CDPlay_bincue(fh->bincue_fd, start_m, start_s, start_f, end_m, end_s, end_f); |
1275 |
+ |
#endif |
1276 |
+ |
|
1277 |
|
if (fh->is_cdrom) { |
1278 |
|
#if defined(__linux__) |
1279 |
|
cdrom_msf play; |
1311 |
|
if (!fh) |
1312 |
|
return false; |
1313 |
|
|
1314 |
+ |
#if defined(BINCUE) |
1315 |
+ |
if (fh->is_bincue) |
1316 |
+ |
return CDPause_bincue(fh->bincue_fd); |
1317 |
+ |
#endif |
1318 |
+ |
|
1319 |
|
if (fh->is_cdrom) { |
1320 |
|
#if defined(__linux__) |
1321 |
|
return ioctl(fh->fd, CDROMPAUSE) == 0; |
1339 |
|
if (!fh) |
1340 |
|
return false; |
1341 |
|
|
1342 |
+ |
#if defined(BINCUE) |
1343 |
+ |
if (fh->is_bincue) |
1344 |
+ |
return CDResume_bincue(fh->bincue_fd); |
1345 |
+ |
#endif |
1346 |
+ |
|
1347 |
+ |
|
1348 |
|
if (fh->is_cdrom) { |
1349 |
|
#if defined(__linux__) |
1350 |
|
return ioctl(fh->fd, CDROMRESUME) == 0; |
1368 |
|
if (!fh) |
1369 |
|
return false; |
1370 |
|
|
1371 |
+ |
#if defined(BINCUE) |
1372 |
+ |
if (fh->is_bincue) |
1373 |
+ |
return CDStop_bincue(fh->bincue_fd); |
1374 |
+ |
#endif |
1375 |
+ |
|
1376 |
+ |
|
1377 |
|
if (fh->is_cdrom) { |
1378 |
|
#if defined(__linux__) |
1379 |
|
return ioctl(fh->fd, CDROMSTOP) == 0; |