forked from thecoshman/http
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild-ioctl.c
51 lines (46 loc) · 1.31 KB
/
build-ioctl.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// SPDX-License-Identifier: 0BSD
// Derived from https://git.sr.ht/~nabijaczleweli/voreutils/tree/02bcd701febb555147b67e0fa7fdc1504fe3cca2/item/cmd/wc.cpp#L155-177
#include <inttypes.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#if __linux__
#include <linux/fs.h>
#elif __OpenBSD__
#include <sys/disklabel.h>
#include <sys/dkio.h>
#elif __has_include(<sys/disk.h>) // NetBSD, FreeBSD
#include <sys/disk.h>
#include <sys/disklabel.h>
#include <sys/types.h>
#elif __has_include(<sys/vtoc.h>) // illumos
#include <stropts.h>
#include <sys/dkio.h>
#include <sys/vtoc.h>
#endif
extern uint64_t http_blkgetsize(int fd);
uint64_t http_blkgetsize(int fd) {
int ret = -1;
#ifdef BLKGETSIZE64 // Linux
uint64_t sz;
ret = ioctl(fd, BLKGETSIZE64, &sz);
#elif defined(DIOCGMEDIASIZE) // NetBSD disk(9), FreeBSD disk(4)
off_t sz;
ret = ioctl(fd, DIOCGMEDIASIZE, &sz);
#elif defined(DIOCGDINFO) // OpenBSD
struct disklabel dl;
ret = ioctl(fd, DIOCGDINFO, &dl);
uint64_t sz = DL_GETDSIZE(&dl);
if(__builtin_mul_overflow(sz, dl.d_secsize, &sz))
ret = -1;
#elif defined(DKIOCGMEDIAINFO) // illumos
struct dk_minfo mi;
ret = ioctl(fd, DKIOCGMEDIAINFO, &mi);
uint64_t sz = mi.dki_capacity;
if(__builtin_mul_overflow(sz, mi.dki_lbsize, &sz))
ret = -1;
#endif
if(ret == -1)
return -1;
else
return sz;
}