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_RESOLVE_BENEATH = 0x1000; 172 #pragma D binding "1.1" O_RESOLVE_BENEATH 173 inline int O_EVTONLY = 0x8000; 174 #pragma D binding "1.1" O_EVTONLY 175 inline int O_NOCTTY = 0x20000; 176 #pragma D binding "1.1" O_NOCTTY 177 inline int O_DIRECTORY = 0x100000; 178 #pragma D binding "1.1" O_DIRECTORY 179 inline int O_SYMLINK = 0x200000; 180 #pragma D binding "1.1" O_SYMLINK 181 inline int O_NOFOLLOW_ANY = 0x20000000; 182 #pragma D binding "1.1" O_NOFOLLOW_ANY 183 184 /* From bsd/sys/file_internal.h */ 185 inline int DTYPE_VNODE = 1; 186 #pragma D binding "1.1" DTYPE_VNODE 187 inline int DTYPE_SOCKET = 2; 188 #pragma D binding "1.1" DTYPE_SOCKET 189 inline int DTYPE_PSXSHM = 3; 190 #pragma D binding "1.1" DTYPE_PSXSHM 191 inline int DTYPE_PSXSEM = 4; 192 #pragma D binding "1.1" DTYPE_PSXSEM 193 inline int DTYPE_KQUEUE = 5; 194 #pragma D binding "1.1" DTYPE_KQUEUE 195 inline int DTYPE_PIPE = 6; 196 #pragma D binding "1.1" DTYPE_PIPE 197 inline int DTYPE_FSEVENTS = 7; 198 #pragma D binding "1.1" DTYPE_FSEVENTS 199 200 #pragma D binding "1.1" translator 201 translator fileinfo_t < struct fileglob *F > { 202 fi_name = (F == NULL) ? "<none>" : 203 F->fg_ops->fo_type == DTYPE_VNODE ? 204 ((struct vnode *)F->fg_data)->v_name == NULL ? "<unknown (NULL v_name)>" : ((struct vnode *)F->fg_data)->v_name : 205 F->fg_ops->fo_type == DTYPE_SOCKET ? "<socket>" : 206 F->fg_ops->fo_type == DTYPE_PSXSHM ? "<shared memory>" : 207 F->fg_ops->fo_type == DTYPE_PSXSEM ? "<semaphore>" : 208 F->fg_ops->fo_type == DTYPE_KQUEUE ? "<kqueue>" : 209 F->fg_ops->fo_type == DTYPE_PIPE ? "<pipe>" : 210 F->fg_ops->fo_type == DTYPE_FSEVENTS ? "<fsevents>" : "<unknown (BAD fo_type)>"; 211 212 fi_dirname = (F == NULL) ? "<none>" : 213 F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" : 214 ((struct vnode *)F->fg_data)->v_parent == NULL ? "<unknown (NULL v_parent)>" : 215 (((struct vnode *)F->fg_data)->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : 216 ((struct vnode *)F->fg_data)->v_parent->v_name); 217 218 fi_pathname = (F == NULL) ? "<none>" : 219 F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" : 220 strjoin("??/", 221 strjoin(((struct vnode *)F->fg_data)->v_parent == NULL ? "<unknown (NULL v_parent)>" : 222 (((struct vnode *)F->fg_data)->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : 223 ((struct vnode *)F->fg_data)->v_parent->v_name), 224 strjoin("/", 225 ((struct vnode *)F->fg_data)->v_name == NULL ? "<unknown (NULL v_name)>" : 226 ((struct vnode *)F->fg_data)->v_name))); 227 228 fi_offset = (F == NULL) ? 0 : 229 F->fg_offset; 230 231 fi_fs = (F == NULL) ? "<none>" : 232 F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" : 233 ((struct vnode *)F->fg_data)->v_mount->mnt_vtable->vfc_name; 234 235 fi_mount = (F == NULL) ? "<none>" : 236 F->fg_ops->fo_type != DTYPE_VNODE ? "<unknown (not a vnode)>" : 237 ((struct vnode *)F->fg_data)->v_mount->mnt_vnodecovered == NULL ? "/" : 238 ((struct vnode *)F->fg_data)->v_mount->mnt_vnodecovered->v_name; 239 240 fi_oflags = (F == NULL) ? 0 : 241 F->fg_flag - 1; /* Subtract one to map FREAD/FWRITE bitfield to O_RD/WR open() flags. */ 242 }; 243 244 inline fileinfo_t fds[int fd] = xlate <fileinfo_t> ( 245 (fd >= 0 && fd < curproc->p_fd.fd_afterlast) ? 246 (struct fileglob *)(curproc->p_fd.fd_ofiles[fd]->fp_glob) : 247 (struct fileglob *)NULL); 248 249 #pragma D attributes Stable/Stable/Common fds 250 #pragma D binding "1.1" fds 251 252 #pragma D binding "1.2" translator 253 translator fileinfo_t < struct vnode *V > { 254 fi_name = V->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_name; 255 256 fi_dirname = V->v_parent == NULL ? "<unknown (NULL v_parent)>" : 257 (V->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_parent->v_name); 258 259 fi_pathname = strjoin("??/", 260 strjoin(V->v_parent == NULL ? "<unknown (NULL v_parent)>" : 261 (V->v_parent->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_parent->v_name), 262 strjoin("/", 263 V->v_name == NULL ? "<unknown (NULL v_name)>" : V->v_name))); 264 265 fi_fs = V->v_mount->mnt_vtable->vfc_name; 266 267 fi_mount = V->v_mount->mnt_vnodecovered == NULL ? "/" : V->v_mount->mnt_vnodecovered->v_name; 268 }; 269 270