]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (c) 2007 Apple, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * The contents of this file constitute Original Code as defined in and | |
7 | * are subject to the Apple Public Source License Version 1.1 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
11 | * | |
12 | * This Original Code and all software distributed under the License are | |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
19 | * | |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | ||
23 | #pragma D depends_on library darwin.d | |
24 | #pragma D depends_on module mach_kernel | |
25 | #pragma D depends_on provider io | |
26 | ||
27 | inline int B_WRITE = 0x0000; | |
28 | #pragma D binding "1.0" B_WRITE | |
29 | inline int B_READ = 0x0001; | |
30 | #pragma D binding "1.0" B_READ | |
31 | inline int B_ASYNC = 0x0002; | |
32 | #pragma D binding "1.0" B_ASYNC | |
33 | inline int B_NOCACHE = 0x0004; | |
34 | #pragma D binding "1.0" B_NOCACHE | |
35 | inline int B_DELWRI = 0x0008; | |
36 | #pragma D binding "1.0" B_DELWRI | |
37 | inline int B_LOCKED = 0x0010; | |
38 | #pragma D binding "1.0" B_LOCKED | |
39 | inline int B_PHYS = 0x0020; | |
40 | #pragma D binding "1.0" B_PHYS | |
41 | inline int B_CLUSTER = 0x0040; | |
42 | #pragma D binding "1.0" B_CLUSTER | |
43 | inline int B_PAGEIO = 0x0080; | |
44 | #pragma D binding "1.0" B_PAGEIO | |
45 | inline int B_META = 0x0100; | |
46 | #pragma D binding "1.0" B_META | |
47 | inline int B_RAW = 0x0200; | |
48 | #pragma D binding "1.0" B_RAW | |
49 | inline int B_FUA = 0x0400; | |
50 | #pragma D binding "1.0" B_FUA | |
51 | inline int B_PASSIVE = 0x0800; | |
52 | #pragma D binding "1.0" B_PASSIVE | |
53 | ||
54 | typedef struct bufinfo { | |
55 | int b_flags; /* buffer status */ | |
56 | size_t b_bcount; /* number of bytes */ | |
57 | caddr_t b_addr; /* buffer address */ | |
58 | uint64_t b_lblkno; /* block # on device */ | |
59 | uint64_t b_blkno; /* expanded block # on device */ | |
60 | size_t b_resid; /* # of bytes not transferred */ | |
61 | size_t b_bufsize; /* size of allocated buffer */ | |
62 | caddr_t b_iodone; /* I/O completion routine */ | |
63 | int b_error; /* expanded error field */ | |
64 | dev_t b_edev; /* extended device */ | |
65 | } bufinfo_t; | |
66 | ||
67 | #pragma D binding "1.0" translator | |
68 | translator bufinfo_t < struct buf *B > { | |
69 | b_flags = B->b_flags; | |
70 | b_addr = (caddr_t)B->b_datap; | |
71 | b_bcount = B->b_bcount; | |
72 | b_lblkno = B->b_lblkno; | |
73 | b_blkno = B->b_blkno; | |
74 | b_resid = B->b_resid; | |
75 | b_bufsize = B->b_bufsize; | |
76 | b_iodone = (caddr_t)B->b_iodone; | |
77 | b_error = B->b_error; | |
78 | b_edev = B->b_dev; | |
79 | }; | |
80 | ||
81 | typedef struct devinfo { | |
82 | int dev_major; /* major number */ | |
83 | int dev_minor; /* minor number */ | |
84 | int dev_instance; /* instance number */ | |
85 | string dev_name; /* name of device */ | |
86 | string dev_statname; /* name of device + instance/minor */ | |
87 | string dev_pathname; /* pathname of device */ | |
88 | } devinfo_t; | |
89 | ||
90 | #pragma D binding "1.0" translator | |
91 | translator devinfo_t < struct buf *B > { | |
92 | dev_major = getmajor(B->b_dev); | |
93 | dev_minor = getminor(B->b_dev); | |
94 | dev_instance = getminor(B->b_dev); | |
95 | dev_name = "??"; /* XXX */ | |
96 | dev_statname = "??"; /* XXX */ | |
97 | dev_pathname = "??"; /* XXX */ | |
98 | }; | |
99 | ||
100 | typedef off_t offset_t; | |
101 | ||
102 | typedef struct fileinfo { | |
103 | string fi_name; /* name (basename of fi_pathname) */ | |
104 | string fi_dirname; /* directory (dirname of fi_pathname) */ | |
105 | string fi_pathname; /* full pathname */ | |
106 | offset_t fi_offset; /* offset within file */ | |
107 | string fi_fs; /* filesystem */ | |
108 | string fi_mount; /* mount point of file system */ | |
109 | int fi_oflags; /* open(2) flags for file descriptor */ | |
110 | } fileinfo_t; | |
111 | ||
112 | #pragma D binding "1.0" translator | |
113 | translator fileinfo_t < struct buf *B > { | |
114 | fi_name = B->b_vp->v_name == NULL ? "<unknown (NULL v_name)>" : B->b_vp->v_name; | |
115 | ||
116 | fi_dirname = B->b_vp->v_parent == NULL ? "<unknown (NULL v_parent)>" : | |
117 | (B->b_vp->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : B->b_vp->v_parent->v_name); | |
118 | ||
119 | fi_pathname = strjoin("??/", | |
120 | strjoin(B->b_vp->v_parent == NULL ? "<unknown (NULL v_parent)>" : | |
121 | (B->b_vp->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : B->b_vp->v_parent->v_name), | |
122 | strjoin("/", | |
123 | B->b_vp->v_name == NULL ? "<unknown (NULL v_name)>" : B->b_vp->v_name))); | |
124 | ||
125 | fi_offset = B->b_upl == NULL ? -1 : ((upl_t)B->b_upl)->u_offset; | |
126 | ||
127 | fi_fs = B->b_vp->v_mount->mnt_vtable->vfc_name; | |
128 | ||
129 | fi_mount = B->b_vp->v_mount->mnt_vnodecovered == NULL ? "/" : B->b_vp->v_mount->mnt_vnodecovered->v_name; | |
130 | ||
131 | fi_oflags = 0; | |
132 | }; | |
133 | ||
134 | /* | |
135 | * The following inline constants can be used to examine fi_oflags when using | |
136 | * the fds[] array or a translated fileglob *. Note that the various open | |
137 | * flags behave as a bit-field *except* for O_RDONLY, O_WRONLY, and O_RDWR. | |
138 | * To test the open mode, you write code similar to that used with the fcntl(2) | |
139 | * F_GET[X]FL command, such as: if ((fi_oflags & O_ACCMODE) == O_WRONLY). | |
140 | */ | |
141 | inline int O_ACCMODE = 0x0003; | |
142 | #pragma D binding "1.1" O_ACCMODE | |
143 | ||
144 | inline int O_RDONLY = 0x0000; | |
145 | #pragma D binding "1.1" O_RDONLY | |
146 | inline int O_WRONLY = 0x0001; | |
147 | #pragma D binding "1.1" O_WRONLY | |
148 | inline int O_RDWR = 0x0002; | |
149 | #pragma D binding "1.1" O_RDWR | |
150 | ||
151 | inline int O_NONBLOCK = 0x0004; | |
152 | #pragma D binding "1.1" O_NONBLOCK | |
153 | inline int O_APPEND = 0x0008; | |
154 | #pragma D binding "1.1" O_APPEND | |
155 | inline int O_SHLOCK = 0x0010; | |
156 | #pragma D binding "1.1" O_SHLOCK | |
157 | inline int O_EXLOCK = 0x0020; | |
158 | #pragma D binding "1.1" O_EXLOCK | |
159 | inline int O_ASYNC = 0x0040; | |
160 | #pragma D binding "1.1" O_ASYNC | |
161 | inline int O_SYNC = 0x0080; | |
162 | #pragma D binding "1.1" O_SYNC | |
163 | inline int O_NOFOLLOW = 0x0100; | |
164 | #pragma D binding "1.1" O_NOFOLLOW | |
165 | inline int O_CREAT = 0x0200; | |
166 | #pragma D binding "1.1" O_CREAT | |
167 | inline int O_TRUNC = 0x0400; | |
168 | #pragma D binding "1.1" O_TRUNC | |
169 | inline int O_EXCL = 0x0800; | |
170 | #pragma D binding "1.1" O_EXCL | |
171 | inline int O_EVTONLY = 0x8000; | |
172 | #pragma D binding "1.1" O_EVTONLY | |
173 | inline int O_NOCTTY = 0x20000; | |
174 | #pragma D binding "1.1" O_NOCTTY | |
175 | inline int O_DIRECTORY = 0x100000; | |
176 | #pragma D binding "1.1" O_DIRECTORY | |
177 | inline int O_SYMLINK = 0x200000; | |
178 | #pragma D binding "1.1" O_SYMLINK | |
179 | inline int O_NOFOLLOW_ANY = 0x20000000; | |
180 | #pragma D binding "1.1" O_NOFOLLOW_ANY | |
181 | ||
182 | /* From bsd/sys/file_internal.h */ | |
183 | inline int DTYPE_VNODE = 1; | |
184 | #pragma D binding "1.1" DTYPE_VNODE | |
185 | inline int DTYPE_SOCKET = 2; | |
186 | #pragma D binding "1.1" DTYPE_SOCKET | |
187 | inline int DTYPE_PSXSHM = 3; | |
188 | #pragma D binding "1.1" DTYPE_PSXSHM | |
189 | inline int DTYPE_PSXSEM = 4; | |
190 | #pragma D binding "1.1" DTYPE_PSXSEM | |
191 | inline int DTYPE_KQUEUE = 5; | |
192 | #pragma D binding "1.1" DTYPE_KQUEUE | |
193 | inline int DTYPE_PIPE = 6; | |
194 | #pragma D binding "1.1" DTYPE_PIPE | |
195 | inline int DTYPE_FSEVENTS = 7; | |
196 | #pragma D binding "1.1" DTYPE_FSEVENTS | |
197 | ||
198 | #pragma D binding "1.1" translator | |
199 | translator fileinfo_t < struct fileglob *F > { | |
200 | fi_name = (F == NULL) ? "<none>" : | |
201 | F->fg_ops->fo_type == DTYPE_VNODE ? | |
202 | ((struct vnode *)F->fg_data)->v_name == NULL ? "<unknown (NULL v_name)>" : ((struct vnode *)F->fg_data)->v_name : | |
203 | F->fg_ops->fo_type == DTYPE_SOCKET ? "<socket>" : | |
204 | F->fg_ops->fo_type == DTYPE_PSXSHM ? "<shared memory>" : | |
205 | F->fg_ops->fo_type == DTYPE_PSXSEM ? "<semaphore>" : | |
206 | F->fg_ops->fo_type == DTYPE_KQUEUE ? "<kqueue>" : | |
207 | F->fg_ops->fo_type == DTYPE_PIPE ? "<pipe>" : | |
208 | F->fg_ops->fo_type == DTYPE_FSEVENTS ? "<fsevents>" : "<unknown (BAD fo_type)>"; | |
209 | ||
210 | fi_dirname = (F == NULL) ? "<none>" : | |
211 | F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" : | |
212 | ((struct vnode *)F->fg_data)->v_parent == NULL ? "<unknown (NULL v_parent)>" : | |
213 | (((struct vnode *)F->fg_data)->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : | |
214 | ((struct vnode *)F->fg_data)->v_parent->v_name); | |
215 | ||
216 | fi_pathname = (F == NULL) ? "<none>" : | |
217 | F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" : | |
218 | strjoin("??/", | |
219 | strjoin(((struct vnode *)F->fg_data)->v_parent == NULL ? "<unknown (NULL v_parent)>" : | |
220 | (((struct vnode *)F->fg_data)->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : | |
221 | ((struct vnode *)F->fg_data)->v_parent->v_name), | |
222 | strjoin("/", | |
223 | ((struct vnode *)F->fg_data)->v_name == NULL ? "<unknown (NULL v_name)>" : | |
224 | ((struct vnode *)F->fg_data)->v_name))); | |
225 | ||
226 | fi_offset = (F == NULL) ? 0 : | |
227 | F->fg_offset; | |
228 | ||
229 | fi_fs = (F == NULL) ? "<none>" : | |
230 | F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" : | |
231 | ((struct vnode *)F->fg_data)->v_mount->mnt_vtable->vfc_name; | |
232 | ||
233 | fi_mount = (F == NULL) ? "<none>" : | |
234 | F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" : | |
235 | ((struct vnode *)F->fg_data)->v_mount->mnt_vnodecovered == NULL ? "/" : | |
236 | ((struct vnode *)F->fg_data)->v_mount->mnt_vnodecovered->v_name; | |
237 | ||
238 | fi_oflags = (F == NULL) ? 0 : | |
239 | F->fg_flag - 1; /* Subtract one to map FREAD/FWRITE bitfield to O_RD/WR open() flags. */ | |
240 | }; | |
241 | ||
242 | inline fileinfo_t fds[int fd] = xlate <fileinfo_t> ( | |
243 | (fd >= 0 && fd <= curproc->p_fd->fd_lastfile) ? | |
244 | (struct fileglob *)(curproc->p_fd->fd_ofiles[fd]->fp_glob) : | |
245 | (struct fileglob *)NULL); | |
246 | ||
247 | #pragma D attributes Stable/Stable/Common fds | |
248 | #pragma D binding "1.1" fds | |
249 | ||
250 | #pragma D binding "1.2" translator | |
251 | translator fileinfo_t < struct vnode *V > { | |
252 | fi_name = V->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_name; | |
253 | ||
254 | fi_dirname = V->v_parent == NULL ? "<unknown (NULL v_parent)>" : | |
255 | (V->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_parent->v_name); | |
256 | ||
257 | fi_pathname = strjoin("??/", | |
258 | strjoin(V->v_parent == NULL ? "<unknown (NULL v_parent)>" : | |
259 | (V->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_parent->v_name), | |
260 | strjoin("/", | |
261 | V->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_name))); | |
262 | ||
263 | fi_fs = V->v_mount->mnt_vtable->vfc_name; | |
264 | ||
265 | fi_mount = V->v_mount->mnt_vnodecovered == NULL ? "/" : V->v_mount->mnt_vnodecovered->v_name; | |
266 | }; | |
267 |