Commit 7674e7bf08c0be8e6872f8602e2d875b3efb6903
1 parent
c747cd1f
BSD cdrom device access fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1412 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
39 additions
and
3 deletions
block.c
| @@ -24,6 +24,14 @@ | @@ -24,6 +24,14 @@ | ||
| 24 | #include "vl.h" | 24 | #include "vl.h" |
| 25 | #include "block_int.h" | 25 | #include "block_int.h" |
| 26 | 26 | ||
| 27 | +#ifdef _BSD | ||
| 28 | +#include <sys/types.h> | ||
| 29 | +#include <sys/stat.h> | ||
| 30 | +#include <sys/ioctl.h> | ||
| 31 | +#include <sys/queue.h> | ||
| 32 | +#include <sys/disk.h> | ||
| 33 | +#endif | ||
| 34 | + | ||
| 27 | static BlockDriverState *bdrv_first; | 35 | static BlockDriverState *bdrv_first; |
| 28 | static BlockDriver *first_drv; | 36 | static BlockDriver *first_drv; |
| 29 | 37 | ||
| @@ -88,18 +96,33 @@ static void get_tmp_filename(char *filename, int size) | @@ -88,18 +96,33 @@ static void get_tmp_filename(char *filename, int size) | ||
| 88 | } | 96 | } |
| 89 | #endif | 97 | #endif |
| 90 | 98 | ||
| 99 | +/* XXX: force raw format if block or character device ? It would | ||
| 100 | + simplify the BSD case */ | ||
| 91 | static BlockDriver *find_image_format(const char *filename) | 101 | static BlockDriver *find_image_format(const char *filename) |
| 92 | { | 102 | { |
| 93 | int fd, ret, score, score_max; | 103 | int fd, ret, score, score_max; |
| 94 | BlockDriver *drv1, *drv; | 104 | BlockDriver *drv1, *drv; |
| 95 | - uint8_t buf[1024]; | 105 | + uint8_t *buf; |
| 106 | + size_t bufsize = 1024; | ||
| 96 | 107 | ||
| 97 | fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE); | 108 | fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE); |
| 98 | if (fd < 0) | 109 | if (fd < 0) |
| 99 | return NULL; | 110 | return NULL; |
| 100 | - ret = read(fd, buf, sizeof(buf)); | 111 | +#ifdef DIOCGSECTORSIZE |
| 112 | + { | ||
| 113 | + unsigned int sectorsize = 512; | ||
| 114 | + if (!ioctl(fd, DIOCGSECTORSIZE, §orsize) && | ||
| 115 | + sectorsize > bufsize) | ||
| 116 | + bufsize = sectorsize; | ||
| 117 | + } | ||
| 118 | +#endif | ||
| 119 | + buf = malloc(bufsize); | ||
| 120 | + if (!buf) | ||
| 121 | + return NULL; | ||
| 122 | + ret = read(fd, buf, bufsize); | ||
| 101 | if (ret < 0) { | 123 | if (ret < 0) { |
| 102 | close(fd); | 124 | close(fd); |
| 125 | + free(buf); | ||
| 103 | return NULL; | 126 | return NULL; |
| 104 | } | 127 | } |
| 105 | close(fd); | 128 | close(fd); |
| @@ -113,6 +136,7 @@ static BlockDriver *find_image_format(const char *filename) | @@ -113,6 +136,7 @@ static BlockDriver *find_image_format(const char *filename) | ||
| 113 | drv = drv1; | 136 | drv = drv1; |
| 114 | } | 137 | } |
| 115 | } | 138 | } |
| 139 | + free(buf); | ||
| 116 | return drv; | 140 | return drv; |
| 117 | } | 141 | } |
| 118 | 142 | ||
| @@ -532,7 +556,19 @@ static int raw_open(BlockDriverState *bs, const char *filename) | @@ -532,7 +556,19 @@ static int raw_open(BlockDriverState *bs, const char *filename) | ||
| 532 | return -1; | 556 | return -1; |
| 533 | bs->read_only = 1; | 557 | bs->read_only = 1; |
| 534 | } | 558 | } |
| 535 | - size = lseek(fd, 0, SEEK_END); | 559 | +#ifdef _BSD |
| 560 | + { | ||
| 561 | + struct stat sb; | ||
| 562 | + if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) { | ||
| 563 | +#ifdef DIOCGMEDIASIZE | ||
| 564 | + if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) | ||
| 565 | +#endif | ||
| 566 | + size = lseek(fd, 0LL, SEEK_END); | ||
| 567 | + } else | ||
| 568 | +#endif | ||
| 569 | + { | ||
| 570 | + size = lseek(fd, 0, SEEK_END); | ||
| 571 | + } | ||
| 536 | #ifdef _WIN32 | 572 | #ifdef _WIN32 |
| 537 | /* On Windows hosts it can happen that we're unable to get file size | 573 | /* On Windows hosts it can happen that we're unable to get file size |
| 538 | for CD-ROM raw device (it's inherent limitation of the CDFS driver). */ | 574 | for CD-ROM raw device (it's inherent limitation of the CDFS driver). */ |