1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1992-2007 AT&T Knowledge Ventures * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Knowledge Ventures * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * * 20 ***********************************************************************/ 21 #pragma prototyped 22 23 static const char usage[] = 24 "[-?\n@(#)$Id: fds (AT&T Research) 2006-10-26 $\n]" 25 USAGE_LICENSE 26 "[+NAME?fds - list open file descriptor status]" 27 "[+DESCRIPTION?\bfds\b lists the status for each open file descriptor. " 28 "When invoked as a shell builtin it accesses the file descriptors of the " 29 "calling shell, otherwise it lists the file descriptors passed across " 30 "\bexec\b(2).]" 31 "[l:long?List file descriptor details.]" 32 "[+SEE ALSO?\blogname\b(1), \bwho\b(1), \bgetgroups\b(2)]" 33 ; 34 35 #include <cmd.h> 36 #include <ls.h> 37 38 #include "FEATURE/sockets" 39 40 #if defined(S_IFSOCK) && _sys_socket && _hdr_arpa_inet && _hdr_netinet_in && _lib_getsockname && _lib_getsockopt && _lib_inet_ntoa 41 #include <sys/socket.h> 42 #include <netinet/in.h> 43 #include <arpa/inet.h> 44 #else 45 #undef S_IFSOCK 46 #endif 47 48 #ifndef minor 49 #define minor(x) (int)((x)&0xff) 50 #endif 51 #ifndef major 52 #define major(x) (int)(((unsigned int)(x)>>8)&0xff) 53 #endif 54 55 int 56 b_fds(int argc, char** argv, void* context) 57 { 58 register char* s; 59 register int i; 60 register char* m; 61 register char* x; 62 int flags; 63 int details; 64 struct stat st; 65 #ifdef S_IFSOCK 66 struct sockaddr_in addr; 67 socklen_t len; 68 int type; 69 int prot; 70 char num[32]; 71 #endif 72 73 cmdinit(argc, argv, context, ERROR_CATALOG, 0); 74 details = 0; 75 for (;;) 76 { 77 switch (optget(argv, usage)) 78 { 79 case 'l': 80 details = opt_info.num; 81 continue; 82 case '?': 83 error(ERROR_USAGE|4, "%s", opt_info.arg); 84 continue; 85 case ':': 86 error(2, "%s", opt_info.arg); 87 continue; 88 } 89 break; 90 } 91 argv += opt_info.index; 92 if (error_info.errors || *argv) 93 error(ERROR_USAGE|4, "%s", optusage(NiL)); 94 for (i = 0; i <= OPEN_MAX; i++) 95 if (fstat(i, &st)) 96 /* not open */; 97 else if (details) 98 { 99 if ((flags = fcntl(i, F_GETFL, (char*)0)) == -1) 100 m = "--"; 101 else 102 switch (flags & (O_RDONLY|O_WRONLY|O_RDWR)) 103 { 104 case O_RDONLY: 105 m = "r-"; 106 break; 107 case O_WRONLY: 108 m = "-w"; 109 break; 110 case O_RDWR: 111 m = "rw"; 112 break; 113 default: 114 m = "??"; 115 break; 116 } 117 x = (fcntl(i, F_GETFD, (char*)0) > 0) ? "x" : "-"; 118 if (isatty(i) && (s = ttyname(i))) 119 sfprintf(sfstdout, "%02d %s%s %s %s\n", i, m, x, fmtmode(st.st_mode, 0), s); 120 #ifdef S_IFSOCK 121 else if ((len = sizeof(addr)) 122 && !getsockname(i, (struct sockaddr*)&addr, (void*)&len) 123 && len == sizeof(addr) 124 && addr.sin_family == AF_INET 125 #ifdef SO_TYPE 126 && (len = sizeof(type)) 127 && !getsockopt(i, SOL_SOCKET, SO_TYPE, (void*)&type, (void*)&len) 128 && len == sizeof(type) 129 #else 130 && !(type = 0) 131 #endif 132 #ifdef SO_PROTOTYPE 133 && (len = sizeof(prot)) 134 && (!getsockopt(i, SOL_SOCKET, SO_PROTOTYPE, (void*)&prot, (void*)&len) || !(prot = 0)) 135 #else 136 && !(prot = 0) 137 #endif 138 ) 139 { 140 if (!st.st_mode) 141 st.st_mode = S_IFSOCK|S_IRUSR|S_IWUSR; 142 s = 0; 143 switch (type) 144 { 145 case SOCK_DGRAM: 146 s = "udp"; 147 break; 148 case SOCK_STREAM: 149 if (prot == 0) 150 s = "tcp"; 151 #ifdef IPPROTO_SCTP 152 else if (prot == IPPROTO_SCTP) 153 s = "sctp"; 154 #endif 155 break; 156 } 157 if (!s) 158 sfprintf(sfstdout, s = num, "type.%d.prot.%d", type, prot); 159 sfprintf(sfstdout, "%02d %s%s %s /dev/%s/%s/%d\n", i, m, x, fmtmode(st.st_mode, 0), s, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); 160 } 161 #endif 162 else 163 sfprintf(sfstdout, "%02d %s%s %s /dev/inode/%u/%u\n", i, m, x, fmtmode(st.st_mode, 0), st.st_dev, st.st_ino); 164 } 165 else 166 sfprintf(sfstdout, "%d\n", i); 167 return 0; 168 } 169