Commit 7674e7bf08c0be8e6872f8602e2d875b3efb6903

Authored by bellard
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
@@ -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, &sectorsize) &&
  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). */