コード例 #1
0
ファイル: sys_beos.cpp プロジェクト: Na1w/sheepshear
void *Sys_open(const char *name, bool read_only)
{
	static bool published_all = false;
	bool is_file = (strstr(name, "/dev/") != name);

	D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write"));

	// Print warning message and eventually unmount drive when this is an HFS volume mounted under BeOS (double mounting will corrupt the volume)
	char mount_name[B_FILE_NAME_LENGTH];
	if (!is_file && !read_only && is_drive_mounted(name, mount_name)) {
		char str[256 + B_FILE_NAME_LENGTH];
		sprintf(str, GetString(STR_VOLUME_IS_MOUNTED_WARN), mount_name);
		WarningAlert(str);
#warning TODO: unmount disk!
#if 0
		if (unmount(mount_name) != 0) {
			sprintf(str, GetString(STR_CANNOT_UNMOUNT_WARN), mount_name);
			WarningAlert(str);
			return NULL;
		}
#endif
	}

	int fd = open(name, read_only ? O_RDONLY : O_RDWR);
	if (fd < 0 && !published_all) {
		// Open failed, create all device nodes and try again, but only the first time
		system("mountvolume -publishall");
		published_all = true;
		fd = open(name, read_only ? O_RDONLY : O_RDWR);
	}
	if (fd >= 0) {
		file_handle *fh = new file_handle;
		fh->name = strdup(name);
		fh->fd = fd;
		fh->is_file = is_file;
		fh->read_only = read_only;
		fh->start_byte = 0;
		if (fh->is_file) {
			// Detect disk image file layout
			loff_t size = lseek(fd, 0, SEEK_END);
			uint8 data[256];
			lseek(fd, 0, SEEK_SET);
			read(fd, data, 256);
			FileDiskLayout(size, data, fh->start_byte, fh->file_size);
		}

		// Enqueue file handle
		fh->next = NULL;
		file_handle *q = first_file_handle;
		if (q) {
			while (q->next)
				q = q->next;
			q->next = fh;
		} else
			first_file_handle = fh;
		return fh;
	} else
		return NULL;
}
コード例 #2
0
ファイル: sys_unix.cpp プロジェクト: tycho/sheepshaver
void *Sys_open(const char *name, bool read_only)
{
	bool is_file = strncmp(name, "/dev/", 5) != 0;
#if defined(__FreeBSD__)
	                // SCSI                             IDE
	bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0 || strncmp(name, "/dev/acd", 8) == 0;
#else
	bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0;
#endif
	bool is_floppy = strncmp(name, "/dev/fd", 7) == 0;

	bool is_polled_media = strncmp(name, "/dev/poll/", 10) == 0;
	if (is_floppy) // Floppy open fails if there's no disk inserted
		is_polled_media = true;

#if defined __MACOSX__
	// There is no set filename in /dev which is the cdrom,
	// so we have to see if it is any of the devices that we found earlier
	{
		int index = 0;
		const char *str;
		while ((str = PrefsFindString("cdrom", index++)) != NULL) {
			if (is_polled_media || strcmp(str, name) == 0) {
				is_cdrom = true;
				read_only = true;
				break;
			}
		}
	}
#endif

	D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write"));

	// Check if write access is allowed, set read-only flag if not
	if (!read_only && access(name, W_OK))
		read_only = true;

	// Print warning message and eventually unmount drive when this is an HFS volume mounted under Linux (double mounting will corrupt the volume)
	char mount_name[256];
	if (!is_file && !read_only && is_drive_mounted(name, mount_name)) {
		char str[512];
		sprintf(str, GetString(STR_VOLUME_IS_MOUNTED_WARN), mount_name);
		WarningAlert(str);
		sprintf(str, "umount %s", mount_name);
		if (system(str)) {
			sprintf(str, GetString(STR_CANNOT_UNMOUNT_WARN), mount_name, strerror(errno));
			WarningAlert(str);
			return NULL;
		}
	}

	// Open file/device

#if defined(BINCUE)
	void *binfd = open_bincue(name);
	if (binfd) {
		su_file_handle *fh = open_filehandle(name);
		D(bug("opening %s as bincue\n", name));
		fh->bincue_fd = binfd;
		fh->is_bincue = true;
		fh->read_only = true;
		fh->is_media_present = true;
		sys_add_su_file_handle(fh);
		return fh;
	}
#endif


#if defined(HAVE_LIBVHD)
	int vhdsize;
	void *vhdfd = vhd_unix_open(name, &vhdsize, read_only);
	if (vhdfd) {
		su_file_handle *fh = open_filehandle(name);
		D(bug("opening %s as vnd\n", name));
		fh->is_vhd = true;
		fh->vhd_fd = vhdfd; 
		fh->read_only = read_only;
		fh->file_size = vhdsize;
		fh->is_media_present = true;
		sys_add_su_file_handle(fh);
		return fh;
	}
#endif

#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MACOSX__)
	int fd = open(name, (read_only ? O_RDONLY : O_RDWR) | (is_cdrom ? O_NONBLOCK : 0));
#else
	int fd = open(name, read_only ? O_RDONLY : O_RDWR);
#endif
	if (fd < 0 && !read_only) {
		// Read-write failed, try read-only
		read_only = true;
		fd = open(name, O_RDONLY);
	}
	if (fd >= 0 || is_polled_media) {
		su_file_handle *fh = open_filehandle(name);
		fh->fd = fd;
		fh->is_file = is_file;
		fh->read_only = read_only;
		fh->is_floppy = is_floppy;
		fh->is_cdrom = is_cdrom;
		if (fh->is_file) {
			fh->is_media_present = true;
			// Detect disk image file layout
			loff_t size = 0;
			size = lseek(fd, 0, SEEK_END);
			uint8 data[256];
			lseek(fd, 0, SEEK_SET);
			read(fd, data, 256);
			FileDiskLayout(size, data, fh->start_byte, fh->file_size);
		} else {
			struct stat st;
			if (fstat(fd, &st) == 0) {
				fh->is_media_present = true;
				if (S_ISBLK(st.st_mode)) {
					fh->is_cdrom = is_cdrom;
#if defined(__linux__)
					fh->is_floppy = (MAJOR(st.st_rdev) == FLOPPY_MAJOR);
#ifdef CDROM_GET_CAPABILITY
					if (is_cdrom) {
						fh->cdrom_cap = ioctl(fh->fd, CDROM_GET_CAPABILITY);
						if (fh->cdrom_cap < 0)
							fh->cdrom_cap = 0;
					}
#endif
#elif defined(__FreeBSD__)
					fh->is_floppy = ((st.st_rdev >> 16) == 2);
#ifdef CDIOCCAPABILITY
					if (is_cdrom) {
						if (ioctl(fh->fd, CDIOCCAPABILITY, &fh->cdrom_cap) < 0)
							memset(&fh->cdrom_cap, 0, sizeof(fh->cdrom_cap));
					}
#endif
#elif defined(__NetBSD__)
					fh->is_floppy = ((st.st_rdev >> 16) == 2);
#endif
				}
#if defined __MACOSX__
				if (is_cdrom) {
					fh->is_cdrom = true;
					fh->is_floppy = false;
					if (cdrom_open_1(fh))
						fh->is_media_present = true;
				}
#endif
			}