1174199Srwatson/*- 2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3330449Seadler * 4224859Srwatson * Copyright (c) 2007-2011 Robert N. M. Watson 5287486Sallanjude * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> 6174199Srwatson * All rights reserved. 7174199Srwatson * 8174199Srwatson * Redistribution and use in source and binary forms, with or without 9174199Srwatson * modification, are permitted provided that the following conditions 10174199Srwatson * are met: 11174199Srwatson * 1. Redistributions of source code must retain the above copyright 12174199Srwatson * notice, this list of conditions and the following disclaimer. 13174199Srwatson * 2. Redistributions in binary form must reproduce the above copyright 14174199Srwatson * notice, this list of conditions and the following disclaimer in the 15174199Srwatson * documentation and/or other materials provided with the distribution. 16174199Srwatson * 17174199Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18174199Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19174199Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20174199Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21174199Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22174199Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23174199Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24174199Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25174199Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26174199Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27174199Srwatson * SUCH DAMAGE. 28174199Srwatson * 29174199Srwatson * $FreeBSD: stable/11/usr.bin/procstat/procstat_files.c 341779 2018-12-10 01:39:40Z kib $ 30174199Srwatson */ 31174199Srwatson 32186567Srwatson#include <sys/param.h> 33263234Srwatson#include <sys/capsicum.h> 34174199Srwatson#include <sys/socket.h> 35174199Srwatson#include <sys/sysctl.h> 36174199Srwatson#include <sys/un.h> 37174199Srwatson#include <sys/user.h> 38174199Srwatson 39174199Srwatson#include <netinet/in.h> 40174199Srwatson 41174199Srwatson#include <arpa/inet.h> 42174199Srwatson 43200462Sdelphij#include <err.h> 44221807Sstas#include <libprocstat.h> 45174199Srwatson#include <inttypes.h> 46174199Srwatson#include <stdio.h> 47174199Srwatson#include <stdlib.h> 48174199Srwatson#include <string.h> 49174199Srwatson 50174199Srwatson#include "procstat.h" 51174199Srwatson 52174199Srwatsonstatic const char * 53174199Srwatsonprotocol_to_string(int domain, int type, int protocol) 54174199Srwatson{ 55174199Srwatson 56174199Srwatson switch (domain) { 57174199Srwatson case AF_INET: 58174199Srwatson case AF_INET6: 59174199Srwatson switch (protocol) { 60174199Srwatson case IPPROTO_TCP: 61174199Srwatson return ("TCP"); 62174199Srwatson case IPPROTO_UDP: 63174199Srwatson return ("UDP"); 64174199Srwatson case IPPROTO_ICMP: 65174530Srwatson return ("ICM"); 66174199Srwatson case IPPROTO_RAW: 67174199Srwatson return ("RAW"); 68174199Srwatson case IPPROTO_SCTP: 69174530Srwatson return ("SCT"); 70174530Srwatson case IPPROTO_DIVERT: 71174530Srwatson return ("IPD"); 72174199Srwatson default: 73174530Srwatson return ("IP?"); 74174199Srwatson } 75174199Srwatson 76174199Srwatson case AF_LOCAL: 77174199Srwatson switch (type) { 78174199Srwatson case SOCK_STREAM: 79174530Srwatson return ("UDS"); 80174199Srwatson case SOCK_DGRAM: 81174530Srwatson return ("UDD"); 82174199Srwatson default: 83174530Srwatson return ("UD?"); 84174199Srwatson } 85174199Srwatson default: 86174530Srwatson return ("?"); 87174199Srwatson } 88174199Srwatson} 89174199Srwatson 90174199Srwatsonstatic void 91174199Srwatsonaddr_to_string(struct sockaddr_storage *ss, char *buffer, int buflen) 92174199Srwatson{ 93174199Srwatson char buffer2[INET6_ADDRSTRLEN]; 94174199Srwatson struct sockaddr_in6 *sin6; 95174199Srwatson struct sockaddr_in *sin; 96174199Srwatson struct sockaddr_un *sun; 97174199Srwatson 98174199Srwatson switch (ss->ss_family) { 99174199Srwatson case AF_LOCAL: 100174199Srwatson sun = (struct sockaddr_un *)ss; 101174199Srwatson if (strlen(sun->sun_path) == 0) 102174199Srwatson strlcpy(buffer, "-", buflen); 103174199Srwatson else 104174199Srwatson strlcpy(buffer, sun->sun_path, buflen); 105174199Srwatson break; 106174199Srwatson 107174199Srwatson case AF_INET: 108174199Srwatson sin = (struct sockaddr_in *)ss; 109174199Srwatson snprintf(buffer, buflen, "%s:%d", inet_ntoa(sin->sin_addr), 110174199Srwatson ntohs(sin->sin_port)); 111174199Srwatson break; 112174199Srwatson 113174199Srwatson case AF_INET6: 114174199Srwatson sin6 = (struct sockaddr_in6 *)ss; 115174199Srwatson if (inet_ntop(AF_INET6, &sin6->sin6_addr, buffer2, 116174199Srwatson sizeof(buffer2)) != NULL) 117174199Srwatson snprintf(buffer, buflen, "%s.%d", buffer2, 118174199Srwatson ntohs(sin6->sin6_port)); 119174199Srwatson else 120267886Sdelphij strlcpy(buffer, "-", buflen); 121174199Srwatson break; 122174199Srwatson 123174199Srwatson default: 124174199Srwatson strlcpy(buffer, "", buflen); 125174199Srwatson break; 126174199Srwatson } 127174199Srwatson} 128174199Srwatson 129224859Srwatsonstatic struct cap_desc { 130255219Spjd uint64_t cd_right; 131224859Srwatson const char *cd_desc; 132224859Srwatson} cap_desc[] = { 133224859Srwatson /* General file I/O. */ 134224859Srwatson { CAP_READ, "rd" }, 135224859Srwatson { CAP_WRITE, "wr" }, 136247602Spjd { CAP_SEEK, "se" }, 137224859Srwatson { CAP_MMAP, "mm" }, 138247602Spjd { CAP_CREATE, "cr" }, 139224859Srwatson { CAP_FEXECVE, "fe" }, 140224859Srwatson { CAP_FSYNC, "fy" }, 141224859Srwatson { CAP_FTRUNCATE, "ft" }, 142224859Srwatson 143224859Srwatson /* VFS methods. */ 144247602Spjd { CAP_FCHDIR, "cd" }, 145224859Srwatson { CAP_FCHFLAGS, "cf" }, 146224859Srwatson { CAP_FCHMOD, "cm" }, 147224859Srwatson { CAP_FCHOWN, "cn" }, 148224859Srwatson { CAP_FCNTL, "fc" }, 149247602Spjd { CAP_FLOCK, "fl" }, 150224859Srwatson { CAP_FPATHCONF, "fp" }, 151224859Srwatson { CAP_FSCK, "fk" }, 152224859Srwatson { CAP_FSTAT, "fs" }, 153224859Srwatson { CAP_FSTATFS, "sf" }, 154224859Srwatson { CAP_FUTIMES, "fu" }, 155287209Sed { CAP_LINKAT_SOURCE, "ls" }, 156287209Sed { CAP_LINKAT_TARGET, "lt" }, 157247602Spjd { CAP_MKDIRAT, "md" }, 158247602Spjd { CAP_MKFIFOAT, "mf" }, 159247602Spjd { CAP_MKNODAT, "mn" }, 160287209Sed { CAP_RENAMEAT_SOURCE, "rs" }, 161287209Sed { CAP_RENAMEAT_TARGET, "rt" }, 162247602Spjd { CAP_SYMLINKAT, "sl" }, 163247602Spjd { CAP_UNLINKAT, "un" }, 164224859Srwatson 165247602Spjd /* Lookups - used to constrain *at() calls. */ 166224859Srwatson { CAP_LOOKUP, "lo" }, 167224859Srwatson 168224859Srwatson /* Extended attributes. */ 169224859Srwatson { CAP_EXTATTR_GET, "eg" }, 170224859Srwatson { CAP_EXTATTR_SET, "es" }, 171224859Srwatson { CAP_EXTATTR_DELETE, "ed" }, 172224859Srwatson { CAP_EXTATTR_LIST, "el" }, 173224859Srwatson 174224859Srwatson /* Access Control Lists. */ 175224859Srwatson { CAP_ACL_GET, "ag" }, 176224859Srwatson { CAP_ACL_SET, "as" }, 177224859Srwatson { CAP_ACL_DELETE, "ad" }, 178224859Srwatson { CAP_ACL_CHECK, "ac" }, 179224859Srwatson 180224859Srwatson /* Socket operations. */ 181224859Srwatson { CAP_ACCEPT, "at" }, 182224859Srwatson { CAP_BIND, "bd" }, 183224859Srwatson { CAP_CONNECT, "co" }, 184224859Srwatson { CAP_GETPEERNAME, "pn" }, 185224859Srwatson { CAP_GETSOCKNAME, "sn" }, 186224859Srwatson { CAP_GETSOCKOPT, "gs" }, 187224859Srwatson { CAP_LISTEN, "ln" }, 188224859Srwatson { CAP_PEELOFF, "pf" }, 189224859Srwatson { CAP_SETSOCKOPT, "ss" }, 190224859Srwatson { CAP_SHUTDOWN, "sh" }, 191224859Srwatson 192224859Srwatson /* Mandatory Access Control. */ 193224859Srwatson { CAP_MAC_GET, "mg" }, 194224859Srwatson { CAP_MAC_SET, "ms" }, 195224859Srwatson 196224859Srwatson /* Methods on semaphores. */ 197224859Srwatson { CAP_SEM_GETVALUE, "sg" }, 198224859Srwatson { CAP_SEM_POST, "sp" }, 199224859Srwatson { CAP_SEM_WAIT, "sw" }, 200224859Srwatson 201224859Srwatson /* Event monitoring and posting. */ 202258181Spjd { CAP_EVENT, "ev" }, 203258181Spjd { CAP_KQUEUE_EVENT, "ke" }, 204258181Spjd { CAP_KQUEUE_CHANGE, "kc" }, 205224859Srwatson 206224859Srwatson /* Strange and powerful rights that should not be given lightly. */ 207224859Srwatson { CAP_IOCTL, "io" }, 208224859Srwatson { CAP_TTYHOOK, "ty" }, 209224859Srwatson 210246644Spjd /* Process management via process descriptors. */ 211224859Srwatson { CAP_PDGETPID, "pg" }, 212246644Spjd { CAP_PDWAIT, "pw" }, 213224859Srwatson { CAP_PDKILL, "pk" }, 214247602Spjd 215247667Spjd /* 216247667Spjd * Rights that allow to use bindat(2) and connectat(2) syscalls on a 217247667Spjd * directory descriptor. 218247667Spjd */ 219247667Spjd { CAP_BINDAT, "ba" }, 220247667Spjd { CAP_CONNECTAT, "ca" }, 221247667Spjd 222247602Spjd /* Aliases and defines that combine multiple rights. */ 223247602Spjd { CAP_PREAD, "prd" }, 224247602Spjd { CAP_PWRITE, "pwr" }, 225247602Spjd 226247602Spjd { CAP_MMAP_R, "mmr" }, 227247602Spjd { CAP_MMAP_W, "mmw" }, 228247602Spjd { CAP_MMAP_X, "mmx" }, 229247602Spjd { CAP_MMAP_RW, "mrw" }, 230247602Spjd { CAP_MMAP_RX, "mrx" }, 231247602Spjd { CAP_MMAP_WX, "mwx" }, 232247602Spjd { CAP_MMAP_RWX, "mma" }, 233247602Spjd 234247602Spjd { CAP_RECV, "re" }, 235247602Spjd { CAP_SEND, "sd" }, 236247602Spjd 237247602Spjd { CAP_SOCK_CLIENT, "scl" }, 238247602Spjd { CAP_SOCK_SERVER, "ssr" }, 239224859Srwatson}; 240307697Saraujostatic const u_int cap_desc_count = nitems(cap_desc); 241224859Srwatson 242224859Srwatsonstatic u_int 243255219Spjdwidth_capability(cap_rights_t *rightsp) 244224859Srwatson{ 245224859Srwatson u_int count, i, width; 246224859Srwatson 247224859Srwatson count = 0; 248224859Srwatson width = 0; 249224859Srwatson for (i = 0; i < cap_desc_count; i++) { 250255219Spjd if (cap_rights_is_set(rightsp, cap_desc[i].cd_right)) { 251224859Srwatson width += strlen(cap_desc[i].cd_desc); 252224859Srwatson if (count) 253224859Srwatson width++; 254224859Srwatson count++; 255224859Srwatson } 256224859Srwatson } 257224859Srwatson return (width); 258224859Srwatson} 259224859Srwatson 260224859Srwatsonstatic void 261255219Spjdprint_capability(cap_rights_t *rightsp, u_int capwidth) 262224859Srwatson{ 263224859Srwatson u_int count, i, width; 264224859Srwatson 265224859Srwatson count = 0; 266224859Srwatson width = 0; 267255219Spjd for (i = width_capability(rightsp); i < capwidth; i++) { 268255219Spjd if (i != 0) 269287486Sallanjude xo_emit(" "); 270224859Srwatson else 271287486Sallanjude xo_emit("-"); 272224859Srwatson } 273287486Sallanjude xo_open_list("capabilities"); 274224859Srwatson for (i = 0; i < cap_desc_count; i++) { 275255219Spjd if (cap_rights_is_set(rightsp, cap_desc[i].cd_right)) { 276287486Sallanjude xo_emit("{D:/%s}{l:capabilities/%s}", count ? "," : "", 277287486Sallanjude cap_desc[i].cd_desc); 278224859Srwatson width += strlen(cap_desc[i].cd_desc); 279224859Srwatson if (count) 280224859Srwatson width++; 281224859Srwatson count++; 282224859Srwatson } 283224859Srwatson } 284287486Sallanjude xo_close_list("capabilities"); 285224859Srwatson} 286224859Srwatson 287174199Srwatsonvoid 288221807Sstasprocstat_files(struct procstat *procstat, struct kinfo_proc *kipp) 289247602Spjd{ 290221807Sstas struct sockstat sock; 291221807Sstas struct filestat_list *head; 292221807Sstas struct filestat *fst; 293174199Srwatson const char *str; 294221807Sstas struct vnstat vn; 295224859Srwatson u_int capwidth, width; 296221807Sstas int error; 297287486Sallanjude char src_addr[PATH_MAX]; 298287486Sallanjude char dst_addr[PATH_MAX]; 299174199Srwatson 300224859Srwatson /* 301224859Srwatson * To print the header in capability mode, we need to know the width 302224859Srwatson * of the widest capability string. Even if we get no processes 303224859Srwatson * back, we will print the header, so we defer aborting due to a lack 304224859Srwatson * of processes until after the header logic. 305224859Srwatson */ 306224859Srwatson capwidth = 0; 307224859Srwatson head = procstat_getfiles(procstat, kipp, 0); 308224859Srwatson if (head != NULL && Cflag) { 309224859Srwatson STAILQ_FOREACH(fst, head, next) { 310255219Spjd width = width_capability(&fst->fs_cap_rights); 311224859Srwatson if (width > capwidth) 312224859Srwatson capwidth = width; 313224859Srwatson } 314224859Srwatson if (capwidth < strlen("CAPABILITIES")) 315224859Srwatson capwidth = strlen("CAPABILITIES"); 316224859Srwatson } 317174199Srwatson 318224859Srwatson if (!hflag) { 319224859Srwatson if (Cflag) 320287486Sallanjude xo_emit("{T:/%5s %-16s %5s %1s %-8s %-*s " 321287486Sallanjude "%-3s %-12s}\n", "PID", "COMM", "FD", "T", 322224859Srwatson "FLAGS", capwidth, "CAPABILITIES", "PRO", 323224859Srwatson "NAME"); 324224859Srwatson else 325287486Sallanjude xo_emit("{T:/%5s %-16s %5s %1s %1s %-8s " 326287486Sallanjude "%3s %7s %-3s %-12s}\n", "PID", "COMM", "FD", "T", 327224859Srwatson "V", "FLAGS", "REF", "OFFSET", "PRO", "NAME"); 328224859Srwatson } 329224859Srwatson 330221807Sstas if (head == NULL) 331186315Smarcus return; 332287486Sallanjude xo_emit("{ek:process_id/%5d/%d}", kipp->ki_pid); 333287486Sallanjude xo_emit("{e:command/%-16s/%s}", kipp->ki_comm); 334287486Sallanjude xo_open_list("files"); 335221807Sstas STAILQ_FOREACH(fst, head, next) { 336287486Sallanjude xo_open_instance("files"); 337287486Sallanjude xo_emit("{dk:process_id/%5d/%d} ", kipp->ki_pid); 338287486Sallanjude xo_emit("{d:command/%-16s/%s} ", kipp->ki_comm); 339221807Sstas if (fst->fs_uflags & PS_FST_UFLAG_CTTY) 340287486Sallanjude xo_emit("{P: }{:fd/%s} ", "ctty"); 341221807Sstas else if (fst->fs_uflags & PS_FST_UFLAG_CDIR) 342287486Sallanjude xo_emit("{P: }{:fd/%s} ", "cwd"); 343221807Sstas else if (fst->fs_uflags & PS_FST_UFLAG_JAIL) 344287486Sallanjude xo_emit("{P: }{:fd/%s} ", "jail"); 345221807Sstas else if (fst->fs_uflags & PS_FST_UFLAG_RDIR) 346287486Sallanjude xo_emit("{P: }{:fd/%s} ", "root"); 347221807Sstas else if (fst->fs_uflags & PS_FST_UFLAG_TEXT) 348287486Sallanjude xo_emit("{P: }{:fd/%s} ", "text"); 349221807Sstas else if (fst->fs_uflags & PS_FST_UFLAG_TRACE) 350287486Sallanjude xo_emit("{:fd/%s} ", "trace"); 351221807Sstas else 352287486Sallanjude xo_emit("{:fd/%5d} ", fst->fs_fd); 353176124Smarcus 354221807Sstas switch (fst->fs_type) { 355221807Sstas case PS_FST_TYPE_VNODE: 356174199Srwatson str = "v"; 357287486Sallanjude xo_emit("{eq:fd_type/vnode}"); 358174199Srwatson break; 359174199Srwatson 360221807Sstas case PS_FST_TYPE_SOCKET: 361174199Srwatson str = "s"; 362287486Sallanjude xo_emit("{eq:fd_type/socket}"); 363174199Srwatson break; 364174199Srwatson 365221807Sstas case PS_FST_TYPE_PIPE: 366174199Srwatson str = "p"; 367287486Sallanjude xo_emit("{eq:fd_type/pipe}"); 368174199Srwatson break; 369174199Srwatson 370221807Sstas case PS_FST_TYPE_FIFO: 371174199Srwatson str = "f"; 372287486Sallanjude xo_emit("{eq:fd_type/fifo}"); 373174199Srwatson break; 374174199Srwatson 375221807Sstas case PS_FST_TYPE_KQUEUE: 376174199Srwatson str = "k"; 377287486Sallanjude xo_emit("{eq:fd_type/kqueue}"); 378174199Srwatson break; 379174199Srwatson 380221807Sstas case PS_FST_TYPE_CRYPTO: 381174199Srwatson str = "c"; 382287486Sallanjude xo_emit("{eq:fd_type/crypto}"); 383174199Srwatson break; 384174199Srwatson 385221807Sstas case PS_FST_TYPE_MQUEUE: 386174199Srwatson str = "m"; 387287486Sallanjude xo_emit("{eq:fd_type/mqueue}"); 388174199Srwatson break; 389174199Srwatson 390221807Sstas case PS_FST_TYPE_SHM: 391175515Srwatson str = "h"; 392287486Sallanjude xo_emit("{eq:fd_type/shm}"); 393175515Srwatson break; 394175515Srwatson 395221807Sstas case PS_FST_TYPE_PTS: 396181905Sed str = "t"; 397287486Sallanjude xo_emit("{eq:fd_type/pts}"); 398181905Sed break; 399181905Sed 400221807Sstas case PS_FST_TYPE_SEM: 401180059Sjhb str = "e"; 402287486Sallanjude xo_emit("{eq:fd_type/sem}"); 403180059Sjhb break; 404180059Sjhb 405332567Strasz case PS_FST_TYPE_PROCDESC: 406332567Strasz str = "P"; 407332567Strasz xo_emit("{eq:fd_type/procdesc}"); 408332567Strasz break; 409332567Strasz 410341779Skib case PS_FST_TYPE_DEV: 411341779Skib str = "D"; 412341779Skib xo_emit("{eq:fd_type/dev}"); 413341779Skib break; 414341779Skib 415221807Sstas case PS_FST_TYPE_NONE: 416287486Sallanjude str = "?"; 417287486Sallanjude xo_emit("{eq:fd_type/none}"); 418287486Sallanjude break; 419287486Sallanjude 420221807Sstas case PS_FST_TYPE_UNKNOWN: 421174199Srwatson default: 422174199Srwatson str = "?"; 423287486Sallanjude xo_emit("{eq:fd_type/unknown}"); 424174199Srwatson break; 425174199Srwatson } 426287486Sallanjude xo_emit("{d:fd_type/%1s/%s} ", str); 427224859Srwatson if (!Cflag) { 428224859Srwatson str = "-"; 429224859Srwatson if (fst->fs_type == PS_FST_TYPE_VNODE) { 430224859Srwatson error = procstat_get_vnode_info(procstat, fst, 431224859Srwatson &vn, NULL); 432224859Srwatson switch (vn.vn_type) { 433224859Srwatson case PS_FST_VTYPE_VREG: 434224859Srwatson str = "r"; 435287486Sallanjude xo_emit("{eq:vode_type/regular}"); 436224859Srwatson break; 437174199Srwatson 438224859Srwatson case PS_FST_VTYPE_VDIR: 439224859Srwatson str = "d"; 440287486Sallanjude xo_emit("{eq:vode_type/directory}"); 441224859Srwatson break; 442174199Srwatson 443224859Srwatson case PS_FST_VTYPE_VBLK: 444224859Srwatson str = "b"; 445287486Sallanjude xo_emit("{eq:vode_type/block}"); 446224859Srwatson break; 447174199Srwatson 448224859Srwatson case PS_FST_VTYPE_VCHR: 449224859Srwatson str = "c"; 450287486Sallanjude xo_emit("{eq:vode_type/character}"); 451224859Srwatson break; 452174199Srwatson 453224859Srwatson case PS_FST_VTYPE_VLNK: 454224859Srwatson str = "l"; 455287486Sallanjude xo_emit("{eq:vode_type/link}"); 456224859Srwatson break; 457174199Srwatson 458224859Srwatson case PS_FST_VTYPE_VSOCK: 459224859Srwatson str = "s"; 460287486Sallanjude xo_emit("{eq:vode_type/socket}"); 461224859Srwatson break; 462174199Srwatson 463224859Srwatson case PS_FST_VTYPE_VFIFO: 464224859Srwatson str = "f"; 465287486Sallanjude xo_emit("{eq:vode_type/fifo}"); 466224859Srwatson break; 467174199Srwatson 468224859Srwatson case PS_FST_VTYPE_VBAD: 469224859Srwatson str = "x"; 470287486Sallanjude xo_emit("{eq:vode_type/revoked_device}"); 471224859Srwatson break; 472174199Srwatson 473224859Srwatson case PS_FST_VTYPE_VNON: 474287486Sallanjude str = "?"; 475287486Sallanjude xo_emit("{eq:vode_type/non}"); 476287486Sallanjude break; 477287486Sallanjude 478224859Srwatson case PS_FST_VTYPE_UNKNOWN: 479224859Srwatson default: 480224859Srwatson str = "?"; 481287486Sallanjude xo_emit("{eq:vode_type/unknown}"); 482224859Srwatson break; 483224859Srwatson } 484174199Srwatson } 485287486Sallanjude xo_emit("{d:vnode_type/%1s/%s} ", str); 486174199Srwatson } 487287486Sallanjude 488287486Sallanjude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_READ ? 489287486Sallanjude "r" : "-"); 490287486Sallanjude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_WRITE ? 491287486Sallanjude "w" : "-"); 492287486Sallanjude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_APPEND ? 493287486Sallanjude "a" : "-"); 494287486Sallanjude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_ASYNC ? 495287486Sallanjude "s" : "-"); 496287486Sallanjude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_SYNC ? 497287486Sallanjude "f" : "-"); 498287486Sallanjude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_NONBLOCK ? 499287486Sallanjude "n" : "-"); 500287486Sallanjude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_DIRECT ? 501287486Sallanjude "d" : "-"); 502287486Sallanjude xo_emit("{d:/%s}", fst->fs_fflags & PS_FST_FFLAG_HASLOCK ? 503287486Sallanjude "l" : "-"); 504287486Sallanjude xo_emit(" "); 505287486Sallanjude xo_open_list("fd_flags"); 506287486Sallanjude if (fst->fs_fflags & PS_FST_FFLAG_READ) 507287486Sallanjude xo_emit("{elq:fd_flags/read}"); 508287486Sallanjude if (fst->fs_fflags & PS_FST_FFLAG_WRITE) 509287486Sallanjude xo_emit("{elq:fd_flags/write}"); 510287486Sallanjude if (fst->fs_fflags & PS_FST_FFLAG_APPEND) 511287486Sallanjude xo_emit("{elq:fd_flags/append}"); 512287486Sallanjude if (fst->fs_fflags & PS_FST_FFLAG_ASYNC) 513287486Sallanjude xo_emit("{elq:fd_flags/async}"); 514287486Sallanjude if (fst->fs_fflags & PS_FST_FFLAG_SYNC) 515287486Sallanjude xo_emit("{elq:fd_flags/fsync}"); 516287486Sallanjude if (fst->fs_fflags & PS_FST_FFLAG_NONBLOCK) 517287486Sallanjude xo_emit("{elq:fd_flags/nonblocking}"); 518287486Sallanjude if (fst->fs_fflags & PS_FST_FFLAG_DIRECT) 519287486Sallanjude xo_emit("{elq:fd_flags/direct_io}"); 520287486Sallanjude if (fst->fs_fflags & PS_FST_FFLAG_HASLOCK) 521287486Sallanjude xo_emit("{elq:fd_flags/lock_held}"); 522287486Sallanjude xo_close_list("fd_flags"); 523287486Sallanjude 524224859Srwatson if (!Cflag) { 525224859Srwatson if (fst->fs_ref_count > -1) 526287486Sallanjude xo_emit("{:ref_count/%3d/%d} ", 527287486Sallanjude fst->fs_ref_count); 528224859Srwatson else 529287486Sallanjude xo_emit("{q:ref_count/%3c/%c} ", '-'); 530224859Srwatson if (fst->fs_offset > -1) 531287486Sallanjude xo_emit("{:offset/%7jd/%jd} ", 532287486Sallanjude (intmax_t)fst->fs_offset); 533224859Srwatson else 534287486Sallanjude xo_emit("{q:offset/%7c/%c} ", '-'); 535224859Srwatson } 536224859Srwatson if (Cflag) { 537255219Spjd print_capability(&fst->fs_cap_rights, capwidth); 538287486Sallanjude xo_emit(" "); 539224859Srwatson } 540221807Sstas switch (fst->fs_type) { 541221807Sstas case PS_FST_TYPE_SOCKET: 542287486Sallanjude error = procstat_get_socket_info(procstat, fst, &sock, 543287486Sallanjude NULL); 544221807Sstas if (error != 0) 545221807Sstas break; 546287486Sallanjude xo_emit("{:protocol/%-3s/%s} ", 547221807Sstas protocol_to_string(sock.dom_family, 548221807Sstas sock.type, sock.proto)); 549174199Srwatson /* 550174199Srwatson * While generally we like to print two addresses, 551174199Srwatson * local and peer, for sockets, it turns out to be 552174199Srwatson * more useful to print the first non-nul address for 553174199Srwatson * local sockets, as typically they aren't bound and 554174199Srwatson * connected, and the path strings can get long. 555174199Srwatson */ 556221807Sstas if (sock.dom_family == AF_LOCAL) { 557174199Srwatson struct sockaddr_un *sun = 558221807Sstas (struct sockaddr_un *)&sock.sa_local; 559174199Srwatson 560174199Srwatson if (sun->sun_path[0] != 0) 561287486Sallanjude addr_to_string(&sock.sa_local, 562287486Sallanjude src_addr, sizeof(src_addr)); 563174199Srwatson else 564287486Sallanjude addr_to_string(&sock.sa_peer, 565287486Sallanjude src_addr, sizeof(src_addr)); 566287486Sallanjude xo_emit("{:path/%s}", src_addr); 567174199Srwatson } else { 568287486Sallanjude addr_to_string(&sock.sa_local, src_addr, 569287486Sallanjude sizeof(src_addr)); 570287486Sallanjude addr_to_string(&sock.sa_peer, dst_addr, 571287486Sallanjude sizeof(dst_addr)); 572287486Sallanjude xo_emit("{:path/%s %s}", src_addr, dst_addr); 573174199Srwatson } 574174199Srwatson break; 575174199Srwatson 576174199Srwatson default: 577287486Sallanjude xo_emit("{:protocol/%-3s/%s} ", "-"); 578287486Sallanjude xo_emit("{:path/%-18s/%s}", fst->fs_path != NULL ? 579287486Sallanjude fst->fs_path : "-"); 580174199Srwatson } 581174199Srwatson 582287486Sallanjude xo_emit("\n"); 583287486Sallanjude xo_close_instance("files"); 584174199Srwatson } 585287486Sallanjude xo_close_list("files"); 586240081Strociny procstat_freefiles(procstat, head); 587174199Srwatson} 588