2  * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  33 #include <sys/param.h> 
  34 #include <sys/systm.h> 
  35 #include <sys/kernel.h> 
  36 #include <sys/malloc.h> 
  37 #include <sys/proc_internal.h> 
  38 #include <sys/kauth.h> 
  39 #include <sys/file_internal.h> 
  40 #include <sys/vnode_internal.h> 
  41 #include <sys/unistd.h> 
  43 #include <sys/ioctl.h> 
  44 #include <sys/namei.h> 
  46 #include <sys/disklabel.h> 
  48 #include <sys/sysctl.h> 
  50 #include <sys/aio_kern.h> 
  52 #include <security/audit/audit.h> 
  54 #include <mach/machine.h> 
  55 #include <mach/mach_types.h> 
  56 #include <mach/vm_param.h> 
  57 #include <kern/task.h> 
  58 #include <kern/lock.h> 
  59 #include <kern/kalloc.h> 
  60 #include <vm/vm_kern.h> 
  61 #include <vm/vm_map.h> 
  62 #include <mach/host_info.h> 
  63 #include <mach/task_info.h> 
  64 #include <mach/thread_info.h> 
  65 #include <mach/vm_region.h> 
  67 #include <sys/mount_internal.h> 
  68 #include <sys/proc_info.h> 
  69 #include <sys/bsdtask_info.h> 
  70 #include <sys/kdebug.h> 
  71 #include <sys/sysproto.h> 
  72 #include <sys/msgbuf.h> 
  74 #include <sys/msgbuf.h> 
  76 #include <machine/machine_routines.h> 
  78 #include <vm/vm_protos.h> 
  86 uint64_t get_dispatchqueue_offset_from_proc(void *); 
  87 int proc_info_internal(int callnum
, int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
); 
  89 /* protos for proc_info calls */ 
  90 int proc_listpids(uint32_t type
, uint32_t tyoneinfo
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
); 
  91 int proc_pidinfo(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
); 
  92 int proc_pidfdinfo(int pid
, int flavor
,int fd
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
); 
  93 int proc_kernmsgbuf(user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
); 
  94 int proc_setcontrol(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
); 
  96 /* protos for procpidinfo calls */ 
  97 int proc_pidfdlist(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
); 
  98 int proc_pidbsdinfo(proc_t p
, struct proc_bsdinfo 
*pbsd
, int zombie
); 
  99 int proc_pidtaskinfo(proc_t p
, struct proc_taskinfo 
*ptinfo
); 
 100 int proc_pidallinfo(proc_t p
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
); 
 101 int proc_pidthreadinfo(proc_t p
, uint64_t arg
,  struct proc_threadinfo 
*pthinfo
); 
 102 int proc_pidthreadpathinfo(proc_t p
, uint64_t arg
,  struct proc_threadwithpathinfo 
*pinfo
); 
 103 int proc_pidlistthreads(proc_t p
,  user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
); 
 104 int proc_pidregioninfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
); 
 105 int proc_pidregionpathinfo(proc_t p
,  uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
); 
 106 int proc_pidvnodepathinfo(proc_t p
,  uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
); 
 107 int proc_pidpathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
); 
 108 int proc_pidworkqueueinfo(proc_t p
, struct proc_workqueueinfo 
*pwqinfo
); 
 111 /* protos for proc_pidfdinfo calls */ 
 112 int pid_vnodeinfo(vnode_t vp
, uint32_t vid
, struct fileproc 
* fp
, int closeonexec
, user_addr_t  buffer
, uint32_t buffersize
, int32_t * retval
); 
 113 int pid_vnodeinfopath(vnode_t vp
, uint32_t vid
, struct fileproc 
* fp
, int closeonexec
, user_addr_t  buffer
, uint32_t buffersize
, int32_t * retval
); 
 114 int pid_socketinfo(socket_t  so
, struct fileproc 
*fp
, int closeonexec
, user_addr_t  buffer
, uint32_t buffersize
, int32_t * retval
); 
 115 int pid_pseminfo(struct psemnode 
* psem
, struct fileproc 
* fp
,  int closeonexec
, user_addr_t  buffer
, uint32_t buffersize
, int32_t * retval
); 
 116 int pid_pshminfo(struct pshmnode 
* pshm
, struct fileproc 
* fp
,  int closeonexec
, user_addr_t  buffer
, uint32_t buffersize
, int32_t * retval
); 
 117 int pid_pipeinfo(struct pipe 
* p
, struct fileproc 
* fp
,  int closeonexec
, user_addr_t  buffer
, uint32_t buffersize
, int32_t * retval
); 
 118 int pid_kqueueinfo(struct kqueue 
* kq
, struct fileproc 
* fp
,  int closeonexec
, user_addr_t  buffer
, uint32_t buffersize
, int32_t * retval
); 
 119 int pid_atalkinfo(struct atalk  
* at
, struct fileproc 
* fp
,  int closeonexec
, user_addr_t  buffer
, uint32_t buffersize
, int32_t * retval
); 
 122 /* protos for misc */ 
 124 int fill_vnodeinfo(vnode_t vp
, struct vnode_info 
*vinfo
); 
 125 void  fill_fileinfo(struct fileproc 
* fp
, int closeonexec
, struct proc_fileinfo 
* finfo
); 
 126 static int proc_security_policy(proc_t p
); 
 127 static void munge_vinfo_stat(struct stat64 
*sbp
, struct vinfo_stat 
*vsbp
); 
 129 uint64_t get_dispatchqueue_offset_from_proc(void *p
) 
 132                 proc_t pself 
= (proc_t
)p
; 
 133                 return (pself
->p_dispatchqueue_offset
); 
 139 /***************************** proc_info ********************/ 
 142 proc_info(__unused 
struct proc 
*p
, struct proc_info_args 
* uap
, int32_t *retval
) 
 144         return(proc_info_internal(uap
->callnum
, uap
->pid
, uap
->flavor
, uap
->arg
, uap
->buffer
, uap
->buffersize
, retval
)); 
 149 proc_info_internal(int callnum
, int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t  buffersize
, int32_t * retval
) 
 153                 case 1: /* proc_listpids */ 
 154                         /* pid contains type and flavor contains typeinfo */ 
 155                         return(proc_listpids(pid
, flavor
, buffer
, buffersize
, retval
)); 
 156                 case 2: /* proc_pidinfo */ 
 157                         return(proc_pidinfo(pid
, flavor
, arg
, buffer
, buffersize
, retval
)); 
 158                 case 3: /* proc_pidfdinfo */ 
 159                         return(proc_pidfdinfo(pid
, flavor
, (int)arg
, buffer
, buffersize
, retval
)); 
 160                 case 4: /* proc_kernmsgbuf */ 
 161                         return(proc_kernmsgbuf(buffer
, buffersize
, retval
)); 
 162                 case 5: /* set on self properties  proc_setcontrol */ 
 163                         return(proc_setcontrol(pid
, flavor
, arg
, buffer
, buffersize
, retval
)); 
 172 /******************* proc_listpids routine ****************/ 
 174 proc_listpids(uint32_t type
, uint32_t typeinfo
, user_addr_t buffer
, uint32_t  buffersize
, int32_t * retval
) 
 176         int numprocs
, wantpids
; 
 184         /* if the buffer is null, return num of procs */ 
 185         if (buffer 
== (user_addr_t
)0) { 
 186                 *retval 
= ((nprocs
+20) * sizeof(int)); 
 190         if (buffersize 
< sizeof(int)) { 
 193         wantpids 
= buffersize
/sizeof(int); 
 194         numprocs 
= nprocs
+20; 
 195         if (numprocs 
> wantpids
) 
 198         kbuf 
= (char *)kalloc((vm_size_t
)(numprocs 
* sizeof(int))); 
 201         bzero(kbuf
, sizeof(int)); 
 208         LIST_FOREACH(p
, &allproc
, p_list
) { 
 212                                 if (p
->p_pgrpid 
!= (pid_t
)typeinfo
) 
 219                                 /* racy but list lock is held */ 
 220                                 if ((p
->p_flag 
& P_CONTROLT
) == 0 || 
 221                                         (p
->p_pgrp 
== NULL
) || (p
->p_pgrp
->pg_session 
== NULL
) || 
 222                                 (tp 
= SESSION_TP(p
->p_pgrp
->pg_session
)) == TTY_NULL 
|| 
 223                                 tp
->t_dev 
!= (dev_t
)typeinfo
) 
 227                                 if (p
->p_ucred 
== NULL
) 
 230                                         kauth_cred_t my_cred
; 
 233                                         my_cred 
= kauth_cred_proc_ref(p
); 
 234                                         uid 
= kauth_cred_getuid(my_cred
); 
 235                                         kauth_cred_unref(&my_cred
); 
 236                                         if (uid 
!= (uid_t
)typeinfo
) 
 241                                 if (p
->p_ucred 
== NULL
) 
 244                                         kauth_cred_t my_cred
; 
 247                                         my_cred 
= kauth_cred_proc_ref(p
); 
 248                                         uid 
= my_cred
->cr_ruid
; 
 249                                         kauth_cred_unref(&my_cred
); 
 250                                         if (uid 
!= (uid_t
)typeinfo
) 
 259                 /* Do we have permission to look into this ? */ 
 260                 if (proc_security_policy(p
) != 0) { 
 273                 LIST_FOREACH(p
, &zombproc
, p_list
) { 
 285         error 
= copyout((caddr_t
)ptr
, buffer
, n 
* sizeof(int)); 
 287                 *retval 
= (n 
* sizeof(int)); 
 288         kfree((void *)kbuf
, (vm_size_t
)(numprocs 
* sizeof(int))); 
 294 /********************************** proc_pidinfo routines ********************************/ 
 297 proc_pidfdlist(proc_t p
, user_addr_t buffer
, uint32_t  buffersize
, int32_t *retval
) 
 301                 struct proc_fdinfo 
* pfd
; 
 302                 struct fileproc 
* fp
; 
 307                 numfds 
= p
->p_fd
->fd_nfiles
;     
 309                 if (buffer 
== (user_addr_t
) 0) { 
 311                         *retval 
= (numfds 
* sizeof(struct proc_fdinfo
)); 
 315                 /* buffersize is big enough atleast for one struct */ 
 316                 needfds 
= buffersize
/sizeof(struct proc_fdinfo
); 
 318                 if (numfds 
> needfds
) 
 321                 kbuf 
= (char *)kalloc((vm_size_t
)(numfds 
* sizeof(struct proc_fdinfo
))); 
 324                 bzero(kbuf
, numfds 
* sizeof(struct proc_fdinfo
)); 
 328                 pfd 
= (struct proc_fdinfo 
*)kbuf
; 
 330                 for (n 
= 0; ((n 
< numfds
) && (n 
< p
->p_fd
->fd_nfiles
)); n
++) { 
 331                         if (((fp 
= p
->p_fd
->fd_ofiles
[n
]) != 0)  
 332                              && ((p
->p_fd
->fd_ofileflags
[n
] & UF_RESERVED
) == 0)) { 
 334                                 pfd
->proc_fdtype 
= fp
->f_fglob
->fg_type
;         
 341                 error 
= copyout(kbuf
, buffer
, count 
* sizeof(struct proc_fdinfo
)); 
 342                 kfree((void *)kbuf
, (vm_size_t
)(numfds 
* sizeof(struct proc_fdinfo
))); 
 344                         *retval 
= (count 
* sizeof(struct proc_fdinfo
)); 
 350 proc_pidbsdinfo(proc_t p
, struct proc_bsdinfo 
* pbsd
, int zombie
) 
 352         register struct tty 
*tp
; 
 353         struct  session 
*sessionp 
= NULL
; 
 355         kauth_cred_t my_cred
; 
 358         sessionp 
= proc_session(p
); 
 360         my_cred 
= kauth_cred_proc_ref(p
); 
 361         bzero(pbsd
, sizeof(struct proc_bsdinfo
)); 
 362         pbsd
->pbi_status 
= p
->p_stat
; 
 363         pbsd
->pbi_xstatus 
= p
->p_xstat
; 
 364         pbsd
->pbi_pid 
= p
->p_pid
; 
 365         pbsd
->pbi_ppid 
= p
->p_ppid
; 
 366         pbsd
->pbi_uid 
= my_cred
->cr_uid
; 
 367         pbsd
->pbi_gid 
= my_cred
->cr_gid
;  
 368         pbsd
->pbi_ruid 
=  my_cred
->cr_ruid
; 
 369         pbsd
->pbi_rgid 
= my_cred
->cr_rgid
; 
 370         pbsd
->pbi_svuid 
=  my_cred
->cr_svuid
; 
 371         pbsd
->pbi_svgid 
= my_cred
->cr_svgid
; 
 372         kauth_cred_unref(&my_cred
); 
 374         pbsd
->pbi_nice 
= p
->p_nice
; 
 375         pbsd
->pbi_start_tvsec 
= p
->p_start
.tv_sec
; 
 376         pbsd
->pbi_start_tvusec 
= p
->p_start
.tv_usec
; 
 377         bcopy(&p
->p_comm
, &pbsd
->pbi_comm
[0], MAXCOMLEN
-1); 
 378         bcopy(&p
->p_name
, &pbsd
->pbi_name
[0], 2*MAXCOMLEN
-1); 
 381         if ((p
->p_flag 
& P_SYSTEM
) == P_SYSTEM
)  
 382                 pbsd
->pbi_flags 
|= PROC_FLAG_SYSTEM
; 
 383         if ((p
->p_lflag 
& P_LTRACED
) == P_LTRACED
)  
 384                 pbsd
->pbi_flags 
|= PROC_FLAG_TRACED
; 
 385         if ((p
->p_lflag 
& P_LEXIT
) == P_LEXIT
)  
 386                 pbsd
->pbi_flags 
|= PROC_FLAG_INEXIT
; 
 387         if ((p
->p_lflag 
& P_LPPWAIT
) == P_LPPWAIT
)  
 388                 pbsd
->pbi_flags 
|= PROC_FLAG_PPWAIT
; 
 389         if ((p
->p_flag 
& P_LP64
) == P_LP64
)  
 390                 pbsd
->pbi_flags 
|= PROC_FLAG_LP64
; 
 391         if ((p
->p_flag 
& P_CONTROLT
) == P_CONTROLT
)  
 392                 pbsd
->pbi_flags 
|= PROC_FLAG_CONTROLT
; 
 393         if ((p
->p_flag 
& P_THCWD
) == P_THCWD
)  
 394                 pbsd
->pbi_flags 
|= PROC_FLAG_THCWD
; 
 396         if (sessionp 
!= SESSION_NULL
) { 
 397                 if (SESS_LEADER(p
, sessionp
)) 
 398                         pbsd
->pbi_flags 
|= PROC_FLAG_SLEADER
; 
 399                 if (sessionp
->s_ttyvp
) 
 400                         pbsd
->pbi_flags 
|= PROC_FLAG_CTTY
; 
 404         switch(PROC_CONTROL_STATE(p
)) { 
 406                         pbsd
->pbi_flags 
|= PROC_FLAG_PC_THROTTLE
; 
 409                         pbsd
->pbi_flags 
|= PROC_FLAG_PC_SUSP
; 
 412                         pbsd
->pbi_flags 
|= PROC_FLAG_PC_KILL
; 
 416         switch(PROC_ACTION_STATE(p
)) { 
 418                         pbsd
->pbi_flags 
|= PROC_FLAG_PA_THROTTLE
; 
 421                         pbsd
->pbi_flags 
|= PROC_FLAG_PA_SUSP
; 
 426                 pbsd
->pbi_nfiles 
= p
->p_fd
->fd_nfiles
; 
 427         if (pg 
!= PGRP_NULL
) { 
 428                 pbsd
->pbi_pgid 
= p
->p_pgrpid
; 
 429                 pbsd
->pbi_pjobc 
= pg
->pg_jobc
; 
 430                 if ((p
->p_flag 
& P_CONTROLT
) && (sessionp 
!= SESSION_NULL
) && (tp 
= SESSION_TP(sessionp
))) { 
 431                         pbsd
->e_tdev 
= tp
->t_dev
; 
 432                         pbsd
->e_tpgid 
= sessionp
->s_ttypgrpid
; 
 435         if (sessionp 
!= SESSION_NULL
) 
 436                 session_rele(sessionp
); 
 445 proc_pidtaskinfo(proc_t p
, struct proc_taskinfo 
* ptinfo
) 
 451         bzero(ptinfo
, sizeof(struct proc_taskinfo
)); 
 452         fill_taskprocinfo(task
, (struct proc_taskinfo_internal 
*)ptinfo
); 
 460 proc_pidthreadinfo(proc_t p
, uint64_t arg
,  struct proc_threadinfo 
*pthinfo
) 
 463         uint64_t threadaddr 
= (uint64_t)arg
; 
 465         bzero(pthinfo
, sizeof(struct proc_threadinfo
)); 
 467         error 
= fill_taskthreadinfo(p
->task
, threadaddr
, (struct proc_threadinfo_internal 
*)pthinfo
, NULL
, NULL
); 
 476 bsd_getthreadname(void *uth
, char *buffer
) 
 478         struct uthread 
*ut 
= (struct uthread 
*)uth
; 
 480                 bcopy(ut
->pth_name
,buffer
,MAXTHREADNAMESIZE
); 
 484 bsd_threadcdir(void * uth
, void *vptr
, int *vidp
) 
 486         struct uthread 
* ut 
= (struct uthread 
*)uth
; 
 488         vnode_t 
*vpp 
= (vnode_t 
*)vptr
; 
 502 proc_pidthreadpathinfo(proc_t p
, uint64_t arg
,  struct proc_threadwithpathinfo 
*pinfo
) 
 507         uint64_t threadaddr 
= (uint64_t)arg
; 
 510         bzero(pinfo
, sizeof(struct proc_threadwithpathinfo
)); 
 512         error 
= fill_taskthreadinfo(p
->task
, threadaddr
, (struct proc_threadinfo_internal 
*)&pinfo
->pt
, (void *)&vp
, &vid
); 
 516         if ((vp 
!= NULLVP
) && ((vnode_getwithvid(vp
, vid
)) == 0)) { 
 517                 error 
= fill_vnodeinfo(vp
, &pinfo
->pvip
.vip_vi
) ; 
 520                         vn_getpath(vp
, &pinfo
->pvip
.vip_path
[0], &count
); 
 521                         pinfo
->pvip
.vip_path
[MAXPATHLEN
-1] = 0; 
 531 proc_pidlistthreads(proc_t p
,  user_addr_t buffer
, uint32_t  buffersize
, int32_t *retval
) 
 540         count 
= buffersize
/(sizeof(uint64_t)); 
 541         numthreads 
= get_numthreads(p
->task
); 
 545         if (numthreads 
> count
) 
 548         kbuf 
= (void *)kalloc(numthreads 
* sizeof(uint64_t)); 
 551         bzero(kbuf
, numthreads 
* sizeof(uint64_t)); 
 553         ret 
= fill_taskthreadlist(p
->task
, kbuf
, numthreads
); 
 555         error 
= copyout(kbuf
, buffer
, ret
); 
 556         kfree(kbuf
, numthreads 
* sizeof(uint64_t)); 
 565 proc_pidregioninfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, __unused 
uint32_t  buffersize
, int32_t *retval
) 
 567         struct proc_regioninfo preginfo
; 
 570         bzero(&preginfo
, sizeof(struct proc_regioninfo
)); 
 571         ret 
= fill_procregioninfo( p
->task
, arg
, (struct proc_regioninfo_internal 
*)&preginfo
, (uintptr_t *)0, (uint32_t *)0); 
 574         error 
= copyout(&preginfo
, buffer
, sizeof(struct proc_regioninfo
)); 
 576                 *retval 
= sizeof(struct proc_regioninfo
); 
 582 proc_pidregionpathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, __unused 
uint32_t  buffersize
, int32_t *retval
) 
 584         struct proc_regionwithpathinfo preginfo
; 
 586         uintptr_t vnodeaddr
= 0; 
 591         bzero(&preginfo
, sizeof(struct proc_regionwithpathinfo
)); 
 593         ret 
= fill_procregioninfo( p
->task
, arg
, (struct proc_regioninfo_internal 
*)&preginfo
.prp_prinfo
, (uintptr_t *)&vnodeaddr
, (uint32_t *)&vnodeid
); 
 597                 vp 
= (vnode_t
)vnodeaddr
; 
 598                 if ((vnode_getwithvid(vp
, vnodeid
)) == 0) { 
 599                         /* FILL THE VNODEINFO */ 
 600                         error 
= fill_vnodeinfo(vp
, &preginfo
.prp_vip
.vip_vi
); 
 602                         vn_getpath(vp
, &preginfo
.prp_vip
.vip_path
[0], &count
); 
 603                         /* Always make sure it is null terminated */ 
 604                         preginfo
.prp_vip
.vip_path
[MAXPATHLEN
-1] = 0; 
 608         error 
= copyout(&preginfo
, buffer
, sizeof(struct proc_regionwithpathinfo
)); 
 610                 *retval 
= sizeof(struct proc_regionwithpathinfo
); 
 615  * Path is relative to current process directory; may different from current 
 619 proc_pidvnodepathinfo(proc_t p
, __unused 
uint64_t arg
, user_addr_t buffer
, __unused 
uint32_t  buffersize
, int32_t *retval
) 
 621         struct proc_vnodepathinfo pvninfo
; 
 623         vnode_t vncdirvp 
= NULLVP
; 
 625         vnode_t vnrdirvp 
= NULLVP
; 
 629         bzero(&pvninfo
, sizeof(struct proc_vnodepathinfo
)); 
 632         if (p
->p_fd
->fd_cdir
) { 
 633                 vncdirvp 
= p
->p_fd
->fd_cdir
; 
 634                 vncdirid 
= p
->p_fd
->fd_cdir
->v_id
; 
 636         if (p
->p_fd
->fd_rdir
) { 
 637                 vnrdirvp 
= p
->p_fd
->fd_rdir
; 
 638                 vnrdirid 
= p
->p_fd
->fd_rdir
->v_id
; 
 642         if (vncdirvp 
!= NULLVP
) { 
 643                 if ((error 
= vnode_getwithvid(vncdirvp
, vncdirid
)) == 0) { 
 644                         /* FILL THE VNODEINFO */ 
 645                         error 
= fill_vnodeinfo(vncdirvp
, &pvninfo
.pvi_cdir
.vip_vi
); 
 648                                 vn_getpath(vncdirvp
, &pvninfo
.pvi_cdir
.vip_path
[0], &count
); 
 649                                 pvninfo
.pvi_cdir
.vip_path
[MAXPATHLEN
-1] = 0; 
 657         if ((error 
== 0) && (vnrdirvp 
!= NULLVP
)) { 
 658                 if ((error 
= vnode_getwithvid(vnrdirvp
, vnrdirid
)) == 0) { 
 659                         /* FILL THE VNODEINFO */ 
 660                         error 
= fill_vnodeinfo(vnrdirvp
, &pvninfo
.pvi_rdir
.vip_vi
); 
 663                                 vn_getpath(vnrdirvp
, &pvninfo
.pvi_rdir
.vip_path
[0], &count
); 
 664                                 pvninfo
.pvi_rdir
.vip_path
[MAXPATHLEN
-1] = 0; 
 672                 error 
= copyout(&pvninfo
, buffer
, sizeof(struct proc_vnodepathinfo
)); 
 674                         *retval 
= sizeof(struct proc_vnodepathinfo
); 
 681 proc_pidpathinfo(proc_t p
, __unused 
uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, __unused 
int32_t *retval
) 
 685         vnode_t nvp 
= NULLVP
; 
 686         int len 
= buffersize
;  
 694         buf 
= (char *)kalloc(buffersize
); 
 699         vid 
= vnode_vid(tvp
); 
 700         error 
= vnode_getwithvid(tvp
, vid
); 
 702                 error 
= vn_getpath_fsenter(tvp
, buf
, &len
); 
 705                         error 
= vnode_lookup(buf
, 0, &nvp
, vfs_context_current());  
 706                         if ((error 
== 0) && ( nvp 
!= NULLVP
)) 
 709                                 error 
= copyout(buf
, buffer
, len
); 
 713         kfree(buf
, buffersize
); 
 719 proc_pidworkqueueinfo(proc_t p
, struct proc_workqueueinfo 
*pwqinfo
) 
 723         bzero(pwqinfo
, sizeof(struct proc_workqueueinfo
)); 
 725         error 
= fill_procworkqueue(p
, pwqinfo
); 
 732 /********************************** proc_pidinfo ********************************/ 
 736 proc_pidinfo(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t  buffersize
, int32_t * retval
) 
 738         struct proc 
* p 
= PROC_NULL
; 
 747                 case PROC_PIDLISTFDS
: 
 748                         size 
= PROC_PIDLISTFD_SIZE
; 
 749                         if (buffer 
== (user_addr_t
)0) 
 752                 case PROC_PIDTBSDINFO
: 
 753                         size 
= PROC_PIDTBSDINFO_SIZE
; 
 755                 case PROC_PIDTASKINFO
: 
 756                         size 
= PROC_PIDTASKINFO_SIZE
; 
 758                 case PROC_PIDTASKALLINFO
: 
 759                         size 
= PROC_PIDTASKALLINFO_SIZE
; 
 761                 case PROC_PIDTHREADINFO
: 
 762                         size 
= PROC_PIDTHREADINFO_SIZE
; 
 764                 case PROC_PIDLISTTHREADS
: 
 765                         size 
= PROC_PIDLISTTHREADS_SIZE
; 
 767                 case PROC_PIDREGIONINFO
: 
 768                         size 
= PROC_PIDREGIONINFO_SIZE
; 
 770                 case PROC_PIDREGIONPATHINFO
: 
 771                         size 
= PROC_PIDREGIONPATHINFO_SIZE
; 
 773                 case PROC_PIDVNODEPATHINFO
: 
 774                         size 
= PROC_PIDVNODEPATHINFO_SIZE
; 
 776                 case PROC_PIDTHREADPATHINFO
: 
 777                         size 
= PROC_PIDTHREADPATHINFO_SIZE
; 
 779                 case PROC_PIDPATHINFO
: 
 782                 case PROC_PIDWORKQUEUEINFO
: 
 783                         /* kernel does not have workq info */ 
 787                                 size 
= PROC_PIDWORKQUEUEINFO_SIZE
; 
 793         if (buffersize 
< size
)  
 796         if ((flavor 
== PROC_PIDPATHINFO
) && (buffersize 
> PROC_PIDPATHINFO_MAXSIZE
)) { 
 800         if ((flavor 
!= PROC_PIDTBSDINFO
) && (flavor 
!= PROC_PIDPATHINFO
)) { 
 801                 if ((p 
= proc_find(pid
)) == PROC_NULL
) { 
 807                                 /* Do we have permission to look into this ? */ 
 808                                 if ((error 
= proc_security_policy(p
)) != 0) { 
 814                 case PROC_PIDLISTFDS
: { 
 815                         error 
= proc_pidfdlist(p
, buffer
, buffersize
, retval
); 
 819                 case PROC_PIDTBSDINFO
: { 
 820                         struct proc_bsdinfo pbsd
; 
 826                         if (p 
== PROC_NULL
) { 
 836                         /* Do we have permission to look into this ? */ 
 837                         if ((error 
= proc_security_policy(p
)) != 0) { 
 842                         error 
= proc_pidbsdinfo(p
, &pbsd
, zombie
); 
 846                                 error 
= copyout(&pbsd
, buffer
, sizeof(struct proc_bsdinfo
)); 
 848                                         *retval 
= sizeof(struct proc_bsdinfo
); 
 853                 case PROC_PIDTASKINFO
: { 
 854                         struct proc_taskinfo ptinfo
; 
 856                         error 
=  proc_pidtaskinfo(p
, &ptinfo
); 
 858                                 error 
= copyout(&ptinfo
, buffer
, sizeof(struct proc_taskinfo
)); 
 860                                         *retval 
= sizeof(struct proc_taskinfo
); 
 865                 case PROC_PIDTASKALLINFO
: { 
 866                 struct proc_taskallinfo pall
; 
 868                         error 
= proc_pidbsdinfo(p
, &pall
.pbsd
, 0); 
 869                         error 
=  proc_pidtaskinfo(p
, &pall
.ptinfo
); 
 871                                 error 
= copyout(&pall
, buffer
, sizeof(struct proc_taskallinfo
)); 
 873                                         *retval 
= sizeof(struct proc_taskallinfo
); 
 878                 case PROC_PIDTHREADINFO
:{ 
 879                 struct proc_threadinfo pthinfo
; 
 881                         error  
= proc_pidthreadinfo(p
,  arg
, &pthinfo
); 
 883                                 error 
= copyout(&pthinfo
, buffer
, sizeof(struct proc_threadinfo
)); 
 885                                         *retval 
= sizeof(struct proc_threadinfo
); 
 890                 case PROC_PIDLISTTHREADS
:{ 
 891                         error 
=  proc_pidlistthreads(p
,  buffer
, buffersize
, retval
); 
 895                 case PROC_PIDREGIONINFO
:{ 
 896                         error 
=  proc_pidregioninfo(p
,  arg
, buffer
, buffersize
, retval
); 
 901                 case PROC_PIDREGIONPATHINFO
:{ 
 902                         error 
=  proc_pidregionpathinfo(p
, arg
, buffer
, buffersize
, retval
); 
 906                 case PROC_PIDVNODEPATHINFO
:{ 
 907                         error 
=  proc_pidvnodepathinfo(p
, arg
, buffer
, buffersize
, retval
); 
 912                 case PROC_PIDTHREADPATHINFO
:{ 
 913                 struct proc_threadwithpathinfo pinfo
; 
 915                         error  
= proc_pidthreadpathinfo(p
,  arg
, &pinfo
); 
 917                                 error 
= copyout((caddr_t
)&pinfo
, buffer
, sizeof(struct proc_threadwithpathinfo
)); 
 919                                                 *retval 
= sizeof(struct proc_threadwithpathinfo
); 
 924                 case PROC_PIDPATHINFO
: { 
 926                         if (p 
== PROC_NULL
) { 
 931                         error 
=  proc_pidpathinfo(p
, arg
, buffer
, buffersize
, retval
); 
 936                 case PROC_PIDWORKQUEUEINFO
:{ 
 937                 struct proc_workqueueinfo pwqinfo
; 
 939                         error  
= proc_pidworkqueueinfo(p
, &pwqinfo
); 
 941                                 error 
= copyout(&pwqinfo
, buffer
, sizeof(struct proc_workqueueinfo
)); 
 943                                         *retval 
= sizeof(struct proc_workqueueinfo
); 
 960 pid_vnodeinfo(vnode_t vp
, uint32_t vid
, struct fileproc 
* fp
, int closeonexec
, user_addr_t  buffer
, __unused 
uint32_t buffersize
, int32_t * retval
)  
 962         struct vnode_fdinfo vfi
; 
 965         if ((error 
= vnode_getwithvid(vp
, vid
)) != 0) { 
 968         bzero(&vfi
, sizeof(struct vnode_fdinfo
)); 
 969         fill_fileinfo(fp
, closeonexec
, &vfi
.pfi
); 
 970         error 
= fill_vnodeinfo(vp
, &vfi
.pvi
); 
 973                 error 
= copyout((caddr_t
)&vfi
, buffer
, sizeof(struct vnode_fdinfo
)); 
 975                         *retval 
= sizeof(struct vnode_fdinfo
); 
 981 pid_vnodeinfopath(vnode_t vp
, uint32_t vid
, struct fileproc 
* fp
, int closeonexec
, user_addr_t  buffer
, __unused 
uint32_t buffersize
, int32_t * retval
)  
 983         struct vnode_fdinfowithpath vfip
; 
 986         if ((error 
= vnode_getwithvid(vp
, vid
)) != 0) { 
 989         bzero(&vfip
, sizeof(struct vnode_fdinfowithpath
)); 
 990         fill_fileinfo(fp
, closeonexec
, &vfip
.pfi
); 
 991         error 
= fill_vnodeinfo(vp
, &vfip
.pvip
.vip_vi
) ; 
 994                 vn_getpath(vp
, &vfip
.pvip
.vip_path
[0], &count
); 
 995                 vfip
.pvip
.vip_path
[MAXPATHLEN
-1] = 0; 
 997                 error 
= copyout((caddr_t
)&vfip
, buffer
, sizeof(struct vnode_fdinfowithpath
)); 
 999                         *retval 
= sizeof(struct vnode_fdinfowithpath
); 
1006 fill_fileinfo(struct fileproc 
* fp
, int closeonexec
, struct proc_fileinfo 
* fproc
) 
1008                 fproc
->fi_openflags 
= fp
->f_fglob
->fg_flag
; 
1009                 fproc
->fi_status 
= 0; 
1010                 fproc
->fi_offset 
= fp
->f_fglob
->fg_offset
; 
1011                 fproc
->fi_type 
= fp
->f_fglob
->fg_type
; 
1012                 if (fp
->f_fglob
->fg_count
) 
1013                         fproc
->fi_status 
|= PROC_FP_SHARED
; 
1014                 if (closeonexec 
!= 0) 
1015                         fproc
->fi_status 
|= PROC_FP_CLEXEC
; 
1021 fill_vnodeinfo(vnode_t vp
, struct vnode_info 
*vinfo
) 
1023                 vfs_context_t context
; 
1027                 context 
= vfs_context_create((vfs_context_t
)0); 
1028                 error 
= vn_stat(vp
, &sb
, NULL
, 1, context
); 
1029                 (void)vfs_context_rele(context
); 
1031                 munge_vinfo_stat(&sb
, &vinfo
->vi_stat
); 
1036                 if (vp
->v_mount 
!= dead_mountp
) { 
1037                         vinfo
->vi_fsid 
= vp
->v_mount
->mnt_vfsstat
.f_fsid
; 
1039                         vinfo
->vi_fsid
.val
[0] = 0; 
1040                         vinfo
->vi_fsid
.val
[1] = 0; 
1042                 vinfo
->vi_type 
= vp
->v_type
; 
1048 pid_socketinfo(socket_t so
, struct fileproc 
*fp
, int closeonexec
, user_addr_t  buffer
, __unused 
uint32_t buffersize
, int32_t * retval
) 
1051         struct socket_fdinfo s
; 
1054         bzero(&s
, sizeof(struct socket_fdinfo
)); 
1055         fill_fileinfo(fp
, closeonexec
, &s
.pfi
); 
1056         if ((error 
= fill_socketinfo(so
, &s
.psi
)) == 0) { 
1057                 if ((error 
= copyout(&s
, buffer
, sizeof(struct socket_fdinfo
))) == 0) 
1058                                 *retval 
= sizeof(struct socket_fdinfo
); 
1068 pid_pseminfo(struct psemnode 
*psem
, struct fileproc 
*fp
,  int closeonexec
, user_addr_t  buffer
, __unused 
uint32_t buffersize
, int32_t * retval
) 
1070         struct psem_fdinfo pseminfo
; 
1073         bzero(&pseminfo
, sizeof(struct psem_fdinfo
)); 
1074         fill_fileinfo(fp
, closeonexec
, &pseminfo
.pfi
); 
1076         if ((error 
= fill_pseminfo(psem
, &pseminfo
.pseminfo
)) == 0) { 
1077                 if ((error 
= copyout(&pseminfo
, buffer
, sizeof(struct psem_fdinfo
))) == 0) 
1078                                 *retval 
= sizeof(struct psem_fdinfo
); 
1085 pid_pshminfo(struct pshmnode 
*pshm
, struct fileproc 
*fp
,  int closeonexec
, user_addr_t  buffer
, __unused 
uint32_t buffersize
, int32_t * retval
) 
1087         struct pshm_fdinfo pshminfo
; 
1090         bzero(&pshminfo
, sizeof(struct pshm_fdinfo
)); 
1091         fill_fileinfo(fp
, closeonexec
, &pshminfo
.pfi
); 
1093         if ((error 
= fill_pshminfo(pshm
, &pshminfo
.pshminfo
)) == 0) { 
1094                 if ((error 
= copyout(&pshminfo
, buffer
, sizeof(struct pshm_fdinfo
))) == 0) 
1095                                 *retval 
= sizeof(struct pshm_fdinfo
); 
1102 pid_pipeinfo(struct pipe 
*  p
, struct fileproc 
*fp
,  int closeonexec
, user_addr_t  buffer
, __unused 
uint32_t buffersize
, int32_t * retval
) 
1104         struct pipe_fdinfo pipeinfo
; 
1107         bzero(&pipeinfo
, sizeof(struct pipe_fdinfo
)); 
1108         fill_fileinfo(fp
, closeonexec
, &pipeinfo
.pfi
); 
1109         if ((error 
= fill_pipeinfo(p
, &pipeinfo
.pipeinfo
)) == 0) { 
1110                 if ((error 
= copyout(&pipeinfo
, buffer
, sizeof(struct pipe_fdinfo
))) == 0) 
1111                                 *retval 
= sizeof(struct pipe_fdinfo
); 
1118 pid_kqueueinfo(struct kqueue 
* kq
, struct fileproc 
*fp
,  int closeonexec
, user_addr_t  buffer
, __unused 
uint32_t buffersize
, int32_t * retval
) 
1120         struct kqueue_fdinfo kqinfo
; 
1123         bzero(&kqinfo
, sizeof(struct kqueue_fdinfo
)); 
1125         fill_fileinfo(fp
, closeonexec
, &kqinfo
.pfi
); 
1127         if ((error 
= fill_kqueueinfo(kq
, &kqinfo
.kqueueinfo
)) == 0) { 
1128                 if ((error 
= copyout(&kqinfo
, buffer
, sizeof(struct kqueue_fdinfo
))) == 0) 
1129                                 *retval 
= sizeof(struct kqueue_fdinfo
); 
1136 pid_atalkinfo(__unused 
struct atalk 
* at
, __unused 
struct fileproc 
*fp
,  __unused 
int closeonexec
, __unused user_addr_t  buffer
, __unused 
uint32_t buffersize
, __unused 
int32_t * retval
) 
1143 /************************** proc_pidfdinfo routine ***************************/ 
1145 proc_pidfdinfo(int pid
, int flavor
,  int fd
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
) 
1148         int error 
= ENOTSUP
; 
1149         struct fileproc 
* fp
; 
1151         int closeonexec 
= 0; 
1154                 case PROC_PIDFDVNODEINFO
: 
1155                         size 
= PROC_PIDFDVNODEINFO_SIZE
; 
1157                 case PROC_PIDFDVNODEPATHINFO
: 
1158                         size 
= PROC_PIDFDVNODEPATHINFO_SIZE
; 
1160                 case PROC_PIDFDSOCKETINFO
: 
1161                         size 
= PROC_PIDFDSOCKETINFO_SIZE
; 
1163                 case PROC_PIDFDPSEMINFO
: 
1164                         size 
= PROC_PIDFDPSEMINFO_SIZE
; 
1166                 case PROC_PIDFDPSHMINFO
: 
1167                         size 
= PROC_PIDFDPSHMINFO_SIZE
; 
1169                 case PROC_PIDFDPIPEINFO
: 
1170                         size 
= PROC_PIDFDPIPEINFO_SIZE
; 
1172                 case PROC_PIDFDKQUEUEINFO
: 
1173                         size 
= PROC_PIDFDKQUEUEINFO_SIZE
; 
1175                 case PROC_PIDFDATALKINFO
: 
1176                         size 
= PROC_PIDFDATALKINFO_SIZE
; 
1184         if (buffersize 
< size
) 
1187         if ((p 
= proc_find(pid
)) == PROC_NULL
) { 
1191         /* Do we have permission to look into this ? */ 
1192         if ((error 
= proc_security_policy(p
)) != 0) { 
1197                 case PROC_PIDFDVNODEINFO
: { 
1201                         if ((error 
= fp_getfvpandvid(p
, fd
, &fp
,  &vp
, &vid
)) !=0) { 
1204                         /* no need to be under the fdlock */ 
1205                         closeonexec 
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
; 
1206                         error 
=  pid_vnodeinfo(vp
, vid
, fp
, closeonexec
, buffer
, buffersize
, retval
); 
1210                 case PROC_PIDFDVNODEPATHINFO
: { 
1214                         if ((error 
= fp_getfvpandvid(p
, fd
, &fp
,  &vp
, &vid
)) !=0) { 
1218                         /* no need to be under the fdlock */ 
1219                         closeonexec 
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
; 
1220                         error 
=  pid_vnodeinfopath(vp
, vid
, fp
, closeonexec
, buffer
, buffersize
, retval
); 
1224                 case PROC_PIDFDSOCKETINFO
: { 
1227                         if ((error 
= fp_getfsock(p
, fd
, &fp
,  &so
)) !=0) { 
1230                         /* no need to be under the fdlock */ 
1231                         closeonexec 
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
; 
1232                         error 
=  pid_socketinfo(so
, fp
, closeonexec
, buffer
, buffersize
, retval
); 
1236                 case PROC_PIDFDPSEMINFO
: { 
1237                         struct psemnode 
* psem
; 
1239                         if ((error 
= fp_getfpsem(p
, fd
, &fp
,  &psem
)) !=0) { 
1242                         /* no need to be under the fdlock */ 
1243                         closeonexec 
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
; 
1244                         error 
=  pid_pseminfo(psem
, fp
, closeonexec
, buffer
, buffersize
, retval
); 
1248                 case PROC_PIDFDPSHMINFO
: { 
1249                         struct pshmnode 
* pshm
; 
1251                         if ((error 
= fp_getfpshm(p
, fd
, &fp
,  &pshm
)) !=0) { 
1254                         /* no need to be under the fdlock */ 
1255                         closeonexec 
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
; 
1256                         error 
=  pid_pshminfo(pshm
, fp
, closeonexec
, buffer
, buffersize
, retval
); 
1260                 case PROC_PIDFDPIPEINFO
: { 
1261                         struct pipe 
* cpipe
; 
1263                         if ((error 
= fp_getfpipe(p
, fd
, &fp
,  &cpipe
)) !=0) { 
1266                         /* no need to be under the fdlock */ 
1267                         closeonexec 
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
; 
1268                         error 
=  pid_pipeinfo(cpipe
, fp
, closeonexec
, buffer
, buffersize
, retval
); 
1272                 case PROC_PIDFDKQUEUEINFO
: { 
1275                         if ((error 
= fp_getfkq(p
, fd
, &fp
,  &kq
)) !=0) { 
1278                         /* no need to be under the fdlock */ 
1279                         closeonexec 
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
; 
1280                         error 
=  pid_kqueueinfo(kq
, fp
, closeonexec
, buffer
, buffersize
, retval
); 
1285                 case PROC_PIDFDATALKINFO
: { 
1288                         if ((error 
= fp_getfatalk(p
, fd
, &fp
,  &at
)) !=0) { 
1292                         /* no need to be under the fdlock */ 
1293                         closeonexec 
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
; 
1294                         error 
=  pid_atalkinfo(at
, fp
, closeonexec
, buffer
, buffersize
, retval
); 
1305         fp_drop(p
, fd
, fp 
, 0);          
1314 proc_security_policy(proc_t p
) 
1316         kauth_cred_t my_cred
; 
1319         my_cred 
= kauth_cred_proc_ref(p
); 
1320         uid 
= kauth_cred_getuid(my_cred
) ; 
1321         kauth_cred_unref(&my_cred
); 
1323         if ((uid 
!= kauth_cred_getuid(kauth_cred_get()))  
1324                 && suser(kauth_cred_get(), (u_short 
*)0)) { 
1332 proc_kernmsgbuf(user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
) 
1334         if (suser(kauth_cred_get(), (u_short 
*)0) == 0) { 
1335                 return(log_dmesg(buffer
, buffersize
, retval
)); 
1340 /* ********* process control sets on self only */ 
1342 proc_setcontrol(int pid
, int flavor
, uint64_t arg
, __unused user_addr_t buffer
, __unused 
uint32_t buffersize
, __unused 
int32_t * retval
) 
1344         struct proc 
* pself 
= PROC_NULL
; 
1346         uint32_t pcontrol 
= (uint32_t)arg
; 
1349         pself 
= current_proc(); 
1350         if (pid 
!= pself
->p_pid
) 
1353         if (pcontrol 
> P_PCMAX
) 
1357                 case PROC_SELFSET_PCONTROL
: { 
1359                         /* reset existing control setting while retaining action state */ 
1360                         pself
->p_pcaction 
&= PROC_ACTION_MASK
; 
1361                         /* set new control state */ 
1362                         pself
->p_pcaction 
|= pcontrol
; 
1376  * copy stat64 structure into vinfo_stat structure. 
1379 munge_vinfo_stat(struct stat64 
*sbp
, struct vinfo_stat 
*vsbp
) 
1381         bzero(vsbp
, sizeof(struct vinfo_stat
)); 
1383         vsbp
->vst_dev 
= sbp
->st_dev
; 
1384         vsbp
->vst_mode 
= sbp
->st_mode
; 
1385         vsbp
->vst_nlink 
= sbp
->st_nlink
; 
1386         vsbp
->vst_ino 
= sbp
->st_ino
; 
1387         vsbp
->vst_uid 
= sbp
->st_uid
; 
1388         vsbp
->vst_gid 
= sbp
->st_gid
; 
1389         vsbp
->vst_atime 
= sbp
->st_atimespec
.tv_sec
; 
1390         vsbp
->vst_atimensec 
= sbp
->st_atimespec
.tv_nsec
; 
1391         vsbp
->vst_mtime 
= sbp
->st_mtimespec
.tv_sec
; 
1392         vsbp
->vst_mtimensec 
= sbp
->st_mtimespec
.tv_nsec
; 
1393         vsbp
->vst_ctime 
= sbp
->st_ctimespec
.tv_sec
; 
1394         vsbp
->vst_ctimensec 
= sbp
->st_ctimespec
.tv_nsec
; 
1395         vsbp
->vst_birthtime 
= sbp
->st_birthtimespec
.tv_sec
; 
1396         vsbp
->vst_birthtimensec 
= sbp
->st_birthtimespec
.tv_nsec
; 
1397         vsbp
->vst_size 
= sbp
->st_size
; 
1398         vsbp
->vst_blocks 
= sbp
->st_blocks
; 
1399         vsbp
->vst_blksize 
= sbp
->st_blksize
; 
1400         vsbp
->vst_flags 
= sbp
->st_flags
; 
1401         vsbp
->vst_gen 
= sbp
->st_gen
; 
1402         vsbp
->vst_rdev 
= sbp
->st_rdev
; 
1403         vsbp
->vst_qspare
[0] = sbp
->st_qspare
[0]; 
1404         vsbp
->vst_qspare
[1] = sbp
->st_qspare
[1];