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 | 24 | #include "vl.h" |
25 | 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 | 35 | static BlockDriverState *bdrv_first; |
28 | 36 | static BlockDriver *first_drv; |
29 | 37 | |
... | ... | @@ -88,18 +96,33 @@ static void get_tmp_filename(char *filename, int size) |
88 | 96 | } |
89 | 97 | #endif |
90 | 98 | |
99 | +/* XXX: force raw format if block or character device ? It would | |
100 | + simplify the BSD case */ | |
91 | 101 | static BlockDriver *find_image_format(const char *filename) |
92 | 102 | { |
93 | 103 | int fd, ret, score, score_max; |
94 | 104 | BlockDriver *drv1, *drv; |
95 | - uint8_t buf[1024]; | |
105 | + uint8_t *buf; | |
106 | + size_t bufsize = 1024; | |
96 | 107 | |
97 | 108 | fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE); |
98 | 109 | if (fd < 0) |
99 | 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 | 123 | if (ret < 0) { |
102 | 124 | close(fd); |
125 | + free(buf); | |
103 | 126 | return NULL; |
104 | 127 | } |
105 | 128 | close(fd); |
... | ... | @@ -113,6 +136,7 @@ static BlockDriver *find_image_format(const char *filename) |
113 | 136 | drv = drv1; |
114 | 137 | } |
115 | 138 | } |
139 | + free(buf); | |
116 | 140 | return drv; |
117 | 141 | } |
118 | 142 | |
... | ... | @@ -532,7 +556,19 @@ static int raw_open(BlockDriverState *bs, const char *filename) |
532 | 556 | return -1; |
533 | 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 | 572 | #ifdef _WIN32 |
537 | 573 | /* On Windows hosts it can happen that we're unable to get file size |
538 | 574 | for CD-ROM raw device (it's inherent limitation of the CDFS driver). */ | ... | ... |