summaryrefslogtreecommitdiff
path: root/sysutils/diskscrub/patches/patch-src_getsize.c
blob: 7ee186f5a71e2f6972141c0395839dfa80afb354 (plain)
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
$NetBSD: patch-src_getsize.c,v 1.1 2013/12/11 19:07:47 prlw1 Exp $

- Make unimplemented getsize() function match prototype in getsize.h.
- Use ioctl names (feature tests) rather than OS names.
  XXX for SIOC_CAPACITY consider using SIOC_STORAGE_CAPACITY.
- Implement getsize() based on DIOCGDISKINFO ioctl.

--- src/getsize.c.orig	2013-12-11 17:24:25.000000000 +0000
+++ src/getsize.c
@@ -36,16 +36,35 @@
 #include <stdlib.h>
 #include <libgen.h>
 #include <string.h>
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#if HAVE_LINUX_FS_H
+#include <linux/fs.h>
+#endif
+#if HAVE_SYS_DEVINFO_H
+#include <sys/devinfo.h>
+#endif
+#if HAVE_SYS_DISK_H
+#include <sys/disk.h>
+#endif
+#if HAVE_SYS_DKIO_H
+#include <sys/dkio.h>
+#endif
+#if HAVE_SYS_SCSI_H
+#include <sys/scsi.h>
+#endif
 
 #include "getsize.h"
 
 extern char *prog;
 
-#if defined(linux)
+#if defined (BLKGETSIZE) && defined(BLKGETSIZE64)
 /* scrub-1.7 tested linux 2.6.11-1.1369_FC4 */
 /* scrub-1.8 tested Fedora Core 5 */
-#include <sys/ioctl.h>
-#include <linux/fs.h>
 #include <sys/utsname.h>
 typedef unsigned long long u64; /* for BLKGETSIZE64 (slackware) */
 
@@ -86,11 +105,8 @@ error:
     return -1;
 }
 
-#elif defined(__FreeBSD__)
+#elif defined(DIOCGMEDIASIZE)
 /* scrub-1.7 tested freebsd 5.3-RELEASE-p5 */
-#include <sys/ioctl.h>
-#include <sys/disk.h>
-
 int
 getsize(char *path, off_t *sizep)
 {
@@ -111,10 +127,8 @@ error:
     return -1;
 }
 
-#elif defined(sun)
+#elif defined(DKIOCGMEDIAINFO)
 /* scrub-1.7 tested solaris 5.9 */
-#include <sys/ioctl.h>
-#include <sys/dkio.h>
 #include <sys/vtoc.h>
 
 int
@@ -137,11 +151,8 @@ error:
     return -1;
 }
 
-#elif defined(__APPLE__)
+#elif defined(DKIOCGETBLOCKSIZE) && defined(DKIOCGETBLOCKCOUNT)
 /* scrub-1.7 tested OS X 7.9.0 */
-#include <stdint.h>
-#include <sys/ioctl.h>
-#include <sys/disk.h>
 
 int
 getsize(char *path, off_t *sizep)
@@ -165,11 +176,10 @@ error:
         (void)close(fd);
     return -1;
 }
-#elif defined(_AIX)
+
+#elif defined(IOCINFO)
 /* scrub-1.7 tested AIX 5.1 and 5.3 */
 /* scrub-1.8 tested AIX 5.2 */
-#include <sys/ioctl.h>
-#include <sys/devinfo.h>
 
 int
 getsize(char *path, off_t *sizep)
@@ -202,10 +212,10 @@ error:
         (void)close(fd);
     return -1;
 }
-#elif defined (__hpux)
+
+#elif defined (SIOC_CAPACITY)
 
 #include <stropts.h>
-#include <sys/scsi.h>
 
 int
 getsize(char *path, off_t *sizep)
@@ -227,11 +237,43 @@ error:
     return -1;
 }
 
+#elif defined(DIOCGDISKINFO)
+
+int
+getsize(char *path, off_t *sizep)
+{
+    int fd;
+    prop_dictionary_t disk_dict, geom_dict;
+    uint64_t secperunit;
+    uint32_t secsize;
+
+    fd = open(path, O_RDONLY);
+    if (fd == -1)
+        return -1;
+
+    if (prop_dictionary_recv_ioctl(fd, DIOCGDISKINFO, &disk_dict) != 0)
+        return -1;
+    if (close(fd) == -1)
+        return -1;
+
+    geom_dict = prop_dictionary_get(disk_dict, "geometry");
+    if (geom_dict == NULL)
+        return -1;
+
+    if (!prop_dictionary_get_uint64(geom_dict, "sectors-per-unit", &secperunit))
+        return -1;
+    if (!prop_dictionary_get_uint32(geom_dict, "sector-size",      &secsize))
+        return -1;
+    *sizep = secperunit * secsize;
+
+    return 0;
+}
+
 #else
 /* Unimplemented!  Scrub will tell user to use -s.
  */
-off_t 
-getsize(char *path)
+int
+getsize(char *path, off_t *sizep)
 {
     errno = ENOSYS;
     return -1;