1/* 2 This file contains some routines that are #ifdef'ed based on what 3 system you're on. Currently it supports the BeOS and Unix. It 4 could be extended to support Windows NT but their posix support 5 is such a joke that it would probably be a real pain in the arse. 6 7 THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED 8 OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR 9 NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED. 10 11 FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com). 12 13 Dominic Giampaolo 14 dbg@be.com 15*/ 16#include <stdio.h> 17#include <fcntl.h> 18#include <unistd.h> 19#include <sys/stat.h> 20 21#include "compat.h" 22 23 24int 25device_is_read_only(const char *device) 26{ 27#ifdef unix 28 return 0; /* XXXdbg should do an ioctl or something */ 29#else 30 int fd; 31 device_geometry dg; 32 33 fd = open(device, O_RDONLY); 34 if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0) 35 return 0; 36 37 close(fd); 38 39 return dg.read_only; 40#endif 41} 42 43int 44get_device_block_size(int fd) 45{ 46#ifdef unix 47 return 512; /* XXXdbg should do an ioctl or something */ 48#else 49 struct stat st; 50 device_geometry dg; 51 52 if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0) { 53 if (fstat(fd, &st) < 0 || S_ISDIR(st.st_mode)) 54 return 0; 55 56 return 512; /* just assume it's a plain old file or something */ 57 } 58 59 return dg.bytes_per_sector; 60#endif 61} 62 63fs_off_t 64get_num_device_blocks(int fd) 65{ 66#ifdef unix 67 struct stat st; 68 69 fstat(fd, &st); /* XXXdbg should be an ioctl or something */ 70 71 return st.st_size / get_device_block_size(fd); 72#else 73 struct stat st; 74 device_geometry dg; 75 76 if (ioctl(fd, B_GET_GEOMETRY, &dg) >= 0) { 77 return (fs_off_t)dg.cylinder_count * 78 (fs_off_t)dg.sectors_per_track * 79 (fs_off_t)dg.head_count; 80 } 81 82 /* if the ioctl fails, try just stat'ing in case it's a regular file */ 83 if (fstat(fd, &st) < 0) 84 return 0; 85 86 return st.st_size / get_device_block_size(fd); 87#endif 88} 89 90int 91device_is_removeable(int fd) 92{ 93#ifdef unix 94 return 0; /* XXXdbg should do an ioctl or something */ 95#else 96 device_geometry dg; 97 98 if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0) { 99 return 0; 100 } 101 102 return dg.removable; 103#endif 104} 105 106#if (defined(__BEOS__) || defined(__HAIKU__)) && !defined(USER) 107#include "scsi.h" 108#endif 109 110int 111lock_removeable_device(int fd, bool on_or_off) 112{ 113#if defined(unix) || defined(USER) 114 return 0; /* XXXdbg should do an ioctl or something */ 115#else 116 return ioctl(fd, B_SCSI_PREVENT_ALLOW, &on_or_off); 117#endif 118} 119 120 121 122 123#if (!defined(__BEOS__) && !defined(__HAIKU__)) 124ssize_t 125read_pos(int fd, fs_off_t _pos, void *data, size_t nbytes) 126{ 127 off_t pos = (off_t)_pos; 128 size_t ret; 129 130 if (lseek(fd, pos, SEEK_SET) < 0) { 131 perror("read lseek"); 132 return EINVAL; 133 } 134 135 ret = read(fd, data, nbytes); 136 137 if (ret != nbytes) { 138 printf("read_pos: wanted %d, got %d\n", nbytes, ret); 139 return -1; 140 } 141 142 return ret; 143} 144 145ssize_t 146write_pos(int fd, fs_off_t _pos, const void *data, size_t nbytes) 147{ 148 off_t pos = (off_t)_pos; 149 size_t ret; 150 151 if (lseek(fd, pos, SEEK_SET) < 0) { 152 perror("read lseek"); 153 return EINVAL; 154 } 155 156 ret = write(fd, data, nbytes); 157 158 if (ret != nbytes) { 159 printf("write_pos: wanted %d, got %d\n", nbytes, ret); 160 return -1; 161 } 162 163 return ret; 164} 165 166 167#ifdef sun /* bloody wankers */ 168#include <sys/stream.h> 169#ifdef DEF_IOV_MAX 170#define MAX_IOV DEF_IOV_MAX 171#else 172#define MAX_IOV 16 173#endif 174#else /* the rest of the world... */ 175#define MAX_IOV 8192 /* something way bigger than we'll ever use */ 176#endif 177 178ssize_t 179readv_pos(int fd, fs_off_t _pos, struct iovec *iov, int count) 180{ 181 off_t pos = (off_t)_pos; 182 size_t amt = 0; 183 ssize_t ret; 184 struct iovec *tmpiov; 185 int i, n; 186 187 if (lseek(fd, pos, SEEK_SET) < 0) { 188 perror("read lseek"); 189 return EINVAL; 190 } 191 192 i = 0; 193 tmpiov = iov; 194 while (i < count) { 195 if (i + MAX_IOV < count) 196 n = MAX_IOV; 197 else 198 n = (count - i); 199 200 ret = readv(fd, tmpiov, n); 201 amt += ret; 202 203 if (ret < 0) 204 break; 205 206 i += n; 207 tmpiov += n; 208 } 209 210 return amt; 211} 212 213ssize_t 214writev_pos(int fd, fs_off_t _pos, struct iovec *iov, int count) 215{ 216 off_t pos = (off_t)_pos; 217 size_t amt = 0; 218 ssize_t ret; 219 struct iovec *tmpiov; 220 int i, n; 221 222 if (lseek(fd, pos, SEEK_SET) < 0) { 223 perror("read lseek"); 224 return EINVAL; 225 } 226 227 i = 0; 228 tmpiov = iov; 229 while (i < count) { 230 if (i + MAX_IOV < count) 231 n = MAX_IOV; 232 else 233 n = (count - i); 234 235 ret = writev(fd, tmpiov, n); 236 amt += ret; 237 238 if (ret < 0) 239 break; 240 241 i += n; 242 tmpiov += n; 243 } 244 245 return amt; 246} 247 248 249 250#endif /* __BEOS__ */ 251 252 253#include <stdarg.h> 254 255 256#if 0 // bonefish 257void 258panic(const char *format, ...) 259{ 260 va_list ap; 261 262 va_start(ap, format); 263 vfprintf(stderr, format, ap); 264 va_end(ap); 265 266 while (TRUE) 267 ; 268} 269#endif 270 271 272#include "lock.h" 273 274int 275new_lock(lock *l, const char *name) 276{ 277 l->c = 1; 278 l->s = create_sem(0, (char *)name); 279 if (l->s <= 0) 280 return l->s; 281 return 0; 282} 283 284int 285free_lock(lock *l) 286{ 287 delete_sem(l->s); 288 289 return 0; 290} 291 292int 293new_mlock(mlock *l, long c, const char *name) 294{ 295 l->s = create_sem(c, (char *)name); 296 if (l->s <= 0) 297 return l->s; 298 return 0; 299} 300 301int 302free_mlock(mlock *l) 303{ 304 delete_sem(l->s); 305 306 return 0; 307} 308 309 310#ifdef unix 311#include <sys/time.h> 312 313bigtime_t 314system_time(void) 315{ 316 bigtime_t t; 317 struct timeval tv; 318 319 gettimeofday(&tv, NULL); 320 321 t = ((bigtime_t)tv.tv_sec * 1000000) + (bigtime_t)tv.tv_usec; 322 return t; 323} 324 325/* 326 If you're compiler/system can't deal with the version of system_time() 327 as defined above, use this one instead 328bigtime_t 329system_time(void) 330{ 331 return (bigtime_t)time(NULL); 332} 333*/ 334 335#endif /* unix */ 336 337#if (defined(__BEOS__) || defined(__HAIKU__)) 338#include <KernelExport.h> 339 340void 341dprintf(const char *format, ...) 342{ 343 va_list args; 344 345 va_start(args, format); 346 vprintf(format, args); 347 va_end(args); 348} 349 350#endif 351