14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1992-2010 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 78462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * Glenn Fowler <gsf@research.att.com> * 184887Schin * David Korn <dgk@research.att.com> * 194887Schin * * 204887Schin ***********************************************************************/ 214887Schin #pragma prototyped 224887Schin 234887Schin static const char usage[] = 2410898Sroland.mainz@nrubsig.org "[-?\n@(#)$Id: fds (AT&T Research) 2009-09-09 $\n]" 254887Schin USAGE_LICENSE 264887Schin "[+NAME?fds - list open file descriptor status]" 274887Schin "[+DESCRIPTION?\bfds\b lists the status for each open file descriptor. " 284887Schin "When invoked as a shell builtin it accesses the file descriptors of the " 294887Schin "calling shell, otherwise it lists the file descriptors passed across " 304887Schin "\bexec\b(2).]" 314887Schin "[l:long?List file descriptor details.]" 3210898Sroland.mainz@nrubsig.org "[u:unit?Write output to \afd\a.]#[fd]" 338462SApril.Chin@Sun.COM "[+SEE ALSO?\blogname\b(1), \bwho\b(1), \bgetgroups\b(2), \bgetsockname\b(2), \bgetsockopts\b(2)]" 344887Schin ; 354887Schin 364887Schin #include <cmd.h> 374887Schin #include <ls.h> 384887Schin 394887Schin #include "FEATURE/sockets" 404887Schin 414887Schin #if defined(S_IFSOCK) && _sys_socket && _hdr_arpa_inet && _hdr_netinet_in && _lib_getsockname && _lib_getsockopt && _lib_inet_ntoa 424887Schin #include <sys/socket.h> 434887Schin #include <netinet/in.h> 444887Schin #include <arpa/inet.h> 454887Schin #else 464887Schin #undef S_IFSOCK 474887Schin #endif 484887Schin 494887Schin #ifndef minor 504887Schin #define minor(x) (int)((x)&0xff) 514887Schin #endif 524887Schin #ifndef major 534887Schin #define major(x) (int)(((unsigned int)(x)>>8)&0xff) 544887Schin #endif 554887Schin 568462SApril.Chin@Sun.COM #undef getconf 578462SApril.Chin@Sun.COM #define getconf(x) strtol(astconf(x,NiL,NiL),NiL,0) 588462SApril.Chin@Sun.COM 598462SApril.Chin@Sun.COM #ifdef S_IFSOCK 608462SApril.Chin@Sun.COM 618462SApril.Chin@Sun.COM typedef struct NV_s 628462SApril.Chin@Sun.COM { 638462SApril.Chin@Sun.COM const char* name; 648462SApril.Chin@Sun.COM int value; 658462SApril.Chin@Sun.COM } NV_t; 668462SApril.Chin@Sun.COM 678462SApril.Chin@Sun.COM static const NV_t family[] = 688462SApril.Chin@Sun.COM { 698462SApril.Chin@Sun.COM #ifdef AF_LOCAL 708462SApril.Chin@Sun.COM "pipe", AF_LOCAL, 718462SApril.Chin@Sun.COM #endif 728462SApril.Chin@Sun.COM #ifdef AF_UNIX 738462SApril.Chin@Sun.COM "pipe", AF_UNIX, 748462SApril.Chin@Sun.COM #endif 758462SApril.Chin@Sun.COM #ifdef AF_FILE 768462SApril.Chin@Sun.COM "FILE", AF_FILE, 778462SApril.Chin@Sun.COM #endif 788462SApril.Chin@Sun.COM #ifdef AF_INET 798462SApril.Chin@Sun.COM "INET", AF_INET, 808462SApril.Chin@Sun.COM #endif 818462SApril.Chin@Sun.COM #ifdef AF_AX25 828462SApril.Chin@Sun.COM "AX25", AF_AX25, 838462SApril.Chin@Sun.COM #endif 848462SApril.Chin@Sun.COM #ifdef AF_IPX 858462SApril.Chin@Sun.COM "IPX", AF_IPX, 868462SApril.Chin@Sun.COM #endif 878462SApril.Chin@Sun.COM #ifdef AF_APPLETALK 888462SApril.Chin@Sun.COM "APPLETALK", AF_APPLETALK, 898462SApril.Chin@Sun.COM #endif 908462SApril.Chin@Sun.COM #ifdef AF_NETROM 918462SApril.Chin@Sun.COM "NETROM", AF_NETROM, 928462SApril.Chin@Sun.COM #endif 938462SApril.Chin@Sun.COM #ifdef AF_BRIDGE 948462SApril.Chin@Sun.COM "BRIDGE", AF_BRIDGE, 958462SApril.Chin@Sun.COM #endif 968462SApril.Chin@Sun.COM #ifdef AF_ATMPVC 978462SApril.Chin@Sun.COM "ATMPVC", AF_ATMPVC, 988462SApril.Chin@Sun.COM #endif 998462SApril.Chin@Sun.COM #ifdef AF_X25 1008462SApril.Chin@Sun.COM "X25", AF_X25, 1018462SApril.Chin@Sun.COM #endif 1028462SApril.Chin@Sun.COM #ifdef AF_INET6 1038462SApril.Chin@Sun.COM "INET6", AF_INET6, 1048462SApril.Chin@Sun.COM #endif 1058462SApril.Chin@Sun.COM #ifdef AF_ROSE 1068462SApril.Chin@Sun.COM "ROSE", AF_ROSE, 1078462SApril.Chin@Sun.COM #endif 1088462SApril.Chin@Sun.COM #ifdef AF_DECnet 1098462SApril.Chin@Sun.COM "DECnet", AF_DECnet, 1108462SApril.Chin@Sun.COM #endif 1118462SApril.Chin@Sun.COM #ifdef AF_NETBEUI 1128462SApril.Chin@Sun.COM "NETBEUI", AF_NETBEUI, 1138462SApril.Chin@Sun.COM #endif 1148462SApril.Chin@Sun.COM #ifdef AF_SECURITY 1158462SApril.Chin@Sun.COM "SECURITY", AF_SECURITY, 1168462SApril.Chin@Sun.COM #endif 1178462SApril.Chin@Sun.COM #ifdef AF_KEY 1188462SApril.Chin@Sun.COM "KEY", AF_KEY, 1198462SApril.Chin@Sun.COM #endif 1208462SApril.Chin@Sun.COM #ifdef AF_NETLINK 1218462SApril.Chin@Sun.COM "NETLINK", AF_NETLINK, 1228462SApril.Chin@Sun.COM #endif 1238462SApril.Chin@Sun.COM #ifdef AF_ROUTE 1248462SApril.Chin@Sun.COM "ROUTE", AF_ROUTE, 1258462SApril.Chin@Sun.COM #endif 1268462SApril.Chin@Sun.COM #ifdef AF_PACKET 1278462SApril.Chin@Sun.COM "PACKET", AF_PACKET, 1288462SApril.Chin@Sun.COM #endif 1298462SApril.Chin@Sun.COM #ifdef AF_ASH 1308462SApril.Chin@Sun.COM "ASH", AF_ASH, 1318462SApril.Chin@Sun.COM #endif 1328462SApril.Chin@Sun.COM #ifdef AF_ECONET 1338462SApril.Chin@Sun.COM "ECONET", AF_ECONET, 1348462SApril.Chin@Sun.COM #endif 1358462SApril.Chin@Sun.COM #ifdef AF_ATMSVC 1368462SApril.Chin@Sun.COM "ATMSVC", AF_ATMSVC, 1378462SApril.Chin@Sun.COM #endif 1388462SApril.Chin@Sun.COM #ifdef AF_SNA 1398462SApril.Chin@Sun.COM "SNA", AF_SNA, 1408462SApril.Chin@Sun.COM #endif 1418462SApril.Chin@Sun.COM #ifdef AF_IRDA 1428462SApril.Chin@Sun.COM "IRDA", AF_IRDA, 1438462SApril.Chin@Sun.COM #endif 1448462SApril.Chin@Sun.COM #ifdef AF_PPPOX 1458462SApril.Chin@Sun.COM "PPPOX", AF_PPPOX, 1468462SApril.Chin@Sun.COM #endif 1478462SApril.Chin@Sun.COM #ifdef AF_WANPIPE 1488462SApril.Chin@Sun.COM "WANPIPE", AF_WANPIPE, 1498462SApril.Chin@Sun.COM #endif 1508462SApril.Chin@Sun.COM #ifdef AF_BLUETOOTH 1518462SApril.Chin@Sun.COM "BLUETOOTH", AF_BLUETOOTH, 1528462SApril.Chin@Sun.COM #endif 1538462SApril.Chin@Sun.COM 0 1548462SApril.Chin@Sun.COM }; 1558462SApril.Chin@Sun.COM 1568462SApril.Chin@Sun.COM #endif 1578462SApril.Chin@Sun.COM 1584887Schin int 1594887Schin b_fds(int argc, char** argv, void* context) 1604887Schin { 1614887Schin register char* s; 1624887Schin register int i; 1634887Schin register char* m; 1644887Schin register char* x; 1654887Schin int flags; 1664887Schin int details; 1678462SApril.Chin@Sun.COM int open_max; 16810898Sroland.mainz@nrubsig.org int unit; 16910898Sroland.mainz@nrubsig.org Sfio_t* sp; 1704887Schin struct stat st; 1714887Schin #ifdef S_IFSOCK 1724887Schin struct sockaddr_in addr; 1738462SApril.Chin@Sun.COM char* a; 1748462SApril.Chin@Sun.COM unsigned char* b; 1758462SApril.Chin@Sun.COM unsigned char* e; 1768462SApril.Chin@Sun.COM socklen_t addrlen; 1774887Schin socklen_t len; 1784887Schin int type; 1798462SApril.Chin@Sun.COM int port; 1804887Schin int prot; 1818462SApril.Chin@Sun.COM char num[64]; 1828462SApril.Chin@Sun.COM char fam[64]; 18310898Sroland.mainz@nrubsig.org #ifdef INET6_ADDRSTRLEN 18410898Sroland.mainz@nrubsig.org char nam[256]; 18510898Sroland.mainz@nrubsig.org #endif 1864887Schin #endif 1874887Schin 1884887Schin cmdinit(argc, argv, context, ERROR_CATALOG, 0); 1894887Schin details = 0; 19010898Sroland.mainz@nrubsig.org unit = 1; 1914887Schin for (;;) 1924887Schin { 1934887Schin switch (optget(argv, usage)) 1944887Schin { 1954887Schin case 'l': 1964887Schin details = opt_info.num; 1974887Schin continue; 19810898Sroland.mainz@nrubsig.org case 'u': 19910898Sroland.mainz@nrubsig.org unit = opt_info.num; 20010898Sroland.mainz@nrubsig.org continue; 2014887Schin case '?': 2024887Schin error(ERROR_USAGE|4, "%s", opt_info.arg); 2034887Schin continue; 2044887Schin case ':': 2054887Schin error(2, "%s", opt_info.arg); 2064887Schin continue; 2074887Schin } 2084887Schin break; 2094887Schin } 2104887Schin argv += opt_info.index; 2114887Schin if (error_info.errors || *argv) 2124887Schin error(ERROR_USAGE|4, "%s", optusage(NiL)); 2138462SApril.Chin@Sun.COM if ((open_max = getconf("OPEN_MAX")) <= 0) 2148462SApril.Chin@Sun.COM open_max = OPEN_MAX; 21510898Sroland.mainz@nrubsig.org if (unit == 1) 21610898Sroland.mainz@nrubsig.org sp = sfstdout; 21710898Sroland.mainz@nrubsig.org else if (fstat(unit, &st) || !(sp = sfnew(NiL, NiL, SF_UNBOUND, unit, SF_WRITE))) 21810898Sroland.mainz@nrubsig.org error(ERROR_SYSTEM|3, "%d: cannot write to file descriptor"); 2198462SApril.Chin@Sun.COM for (i = 0; i <= open_max; i++) 2208462SApril.Chin@Sun.COM { 2214887Schin if (fstat(i, &st)) 2228462SApril.Chin@Sun.COM { 2238462SApril.Chin@Sun.COM /* not open */ 2248462SApril.Chin@Sun.COM continue; 2258462SApril.Chin@Sun.COM } 2268462SApril.Chin@Sun.COM if (!details) 2274887Schin { 22810898Sroland.mainz@nrubsig.org sfprintf(sp, "%d\n", i); 2298462SApril.Chin@Sun.COM continue; 2308462SApril.Chin@Sun.COM } 2318462SApril.Chin@Sun.COM if ((flags = fcntl(i, F_GETFL, (char*)0)) == -1) 2328462SApril.Chin@Sun.COM m = "--"; 2338462SApril.Chin@Sun.COM else 2348462SApril.Chin@Sun.COM switch (flags & (O_RDONLY|O_WRONLY|O_RDWR)) 2358462SApril.Chin@Sun.COM { 2368462SApril.Chin@Sun.COM case O_RDONLY: 2378462SApril.Chin@Sun.COM m = "r-"; 2388462SApril.Chin@Sun.COM break; 2398462SApril.Chin@Sun.COM case O_WRONLY: 2408462SApril.Chin@Sun.COM m = "-w"; 2418462SApril.Chin@Sun.COM break; 2428462SApril.Chin@Sun.COM case O_RDWR: 2438462SApril.Chin@Sun.COM m = "rw"; 2448462SApril.Chin@Sun.COM break; 2458462SApril.Chin@Sun.COM default: 2468462SApril.Chin@Sun.COM m = "??"; 2478462SApril.Chin@Sun.COM break; 2488462SApril.Chin@Sun.COM } 2498462SApril.Chin@Sun.COM x = (fcntl(i, F_GETFD, (char*)0) > 0) ? "x" : "-"; 2508462SApril.Chin@Sun.COM if (isatty(i) && (s = ttyname(i))) 2518462SApril.Chin@Sun.COM { 25210898Sroland.mainz@nrubsig.org sfprintf(sp, "%02d %s%s %s %s\n", i, m, x, fmtmode(st.st_mode, 0), s); 2538462SApril.Chin@Sun.COM continue; 2548462SApril.Chin@Sun.COM } 2558462SApril.Chin@Sun.COM #ifdef S_IFSOCK 2568462SApril.Chin@Sun.COM addrlen = sizeof(addr); 2578462SApril.Chin@Sun.COM memset(&addr, 0, addrlen); 2588462SApril.Chin@Sun.COM if (!getsockname(i, (struct sockaddr*)&addr, (void*)&addrlen)) 2598462SApril.Chin@Sun.COM { 2608462SApril.Chin@Sun.COM type = 0; 2618462SApril.Chin@Sun.COM prot = 0; 2628462SApril.Chin@Sun.COM #ifdef SO_TYPE 2638462SApril.Chin@Sun.COM len = sizeof(type); 2648462SApril.Chin@Sun.COM if (getsockopt(i, SOL_SOCKET, SO_TYPE, (void*)&type, (void*)&len)) 2658462SApril.Chin@Sun.COM type = -1; 2668462SApril.Chin@Sun.COM #endif 2678462SApril.Chin@Sun.COM #ifdef SO_PROTOTYPE 2688462SApril.Chin@Sun.COM len = sizeof(prot); 2698462SApril.Chin@Sun.COM if (getsockopt(i, SOL_SOCKET, SO_PROTOTYPE, (void*)&prot, (void*)&len)) 2708462SApril.Chin@Sun.COM prot = -1; 2718462SApril.Chin@Sun.COM #endif 2728462SApril.Chin@Sun.COM if (!st.st_mode) 2738462SApril.Chin@Sun.COM st.st_mode = S_IFSOCK|S_IRUSR|S_IWUSR; 2748462SApril.Chin@Sun.COM s = 0; 2758462SApril.Chin@Sun.COM switch (type) 2768462SApril.Chin@Sun.COM { 2778462SApril.Chin@Sun.COM case SOCK_DGRAM: 2788462SApril.Chin@Sun.COM switch (addr.sin_family) 2794887Schin { 2808462SApril.Chin@Sun.COM case AF_INET: 2818462SApril.Chin@Sun.COM #ifdef AF_INET6 2828462SApril.Chin@Sun.COM case AF_INET6: 2838462SApril.Chin@Sun.COM #endif 2848462SApril.Chin@Sun.COM s = "udp"; 2854887Schin break; 2864887Schin } 2878462SApril.Chin@Sun.COM break; 2888462SApril.Chin@Sun.COM case SOCK_STREAM: 2898462SApril.Chin@Sun.COM switch (addr.sin_family) 2908462SApril.Chin@Sun.COM { 2918462SApril.Chin@Sun.COM case AF_INET: 2928462SApril.Chin@Sun.COM #ifdef AF_INET6 2938462SApril.Chin@Sun.COM case AF_INET6: 2944887Schin #endif 2958462SApril.Chin@Sun.COM #ifdef IPPROTO_SCTP 2968462SApril.Chin@Sun.COM if (prot == IPPROTO_SCTP) 2978462SApril.Chin@Sun.COM s = "sctp"; 2988462SApril.Chin@Sun.COM else 2994887Schin #endif 3004887Schin s = "tcp"; 3014887Schin break; 3024887Schin } 3038462SApril.Chin@Sun.COM break; 3048462SApril.Chin@Sun.COM #ifdef SOCK_RAW 3058462SApril.Chin@Sun.COM case SOCK_RAW: 3068462SApril.Chin@Sun.COM s = "raw"; 3078462SApril.Chin@Sun.COM break; 3088462SApril.Chin@Sun.COM #endif 3098462SApril.Chin@Sun.COM #ifdef SOCK_RDM 3108462SApril.Chin@Sun.COM case SOCK_RDM: 3118462SApril.Chin@Sun.COM s = "rdm"; 3128462SApril.Chin@Sun.COM break; 3138462SApril.Chin@Sun.COM #endif 3148462SApril.Chin@Sun.COM #ifdef SOCK_SEQPACKET 3158462SApril.Chin@Sun.COM case SOCK_SEQPACKET: 3168462SApril.Chin@Sun.COM s = "seqpacket"; 3178462SApril.Chin@Sun.COM break; 3184887Schin #endif 3198462SApril.Chin@Sun.COM } 3208462SApril.Chin@Sun.COM if (!s) 3218462SApril.Chin@Sun.COM { 3228462SApril.Chin@Sun.COM for (type = 0; family[type].name && family[type].value != addr.sin_family; type++); 3238462SApril.Chin@Sun.COM if (!(s = (char*)family[type].name)) 3248462SApril.Chin@Sun.COM sfsprintf(s = num, sizeof(num), "family.%d", addr.sin_family); 3258462SApril.Chin@Sun.COM } 3268462SApril.Chin@Sun.COM port = 0; 3278462SApril.Chin@Sun.COM #ifdef INET6_ADDRSTRLEN 3288462SApril.Chin@Sun.COM if (a = (char*)inet_ntop(addr.sin_family, &addr.sin_addr, nam, sizeof(nam))) 3298462SApril.Chin@Sun.COM port = ntohs(addr.sin_port); 3304887Schin else 3318462SApril.Chin@Sun.COM #endif 3328462SApril.Chin@Sun.COM if (addr.sin_family == AF_INET) 3338462SApril.Chin@Sun.COM { 3348462SApril.Chin@Sun.COM a = inet_ntoa(addr.sin_addr); 3358462SApril.Chin@Sun.COM port = ntohs(addr.sin_port); 3368462SApril.Chin@Sun.COM } 3378462SApril.Chin@Sun.COM else 3388462SApril.Chin@Sun.COM { 3398462SApril.Chin@Sun.COM a = fam; 3408462SApril.Chin@Sun.COM e = (b = (unsigned char*)&addr) + addrlen; 3418462SApril.Chin@Sun.COM while (b < e && a < &fam[sizeof(fam)-1]) 3428462SApril.Chin@Sun.COM a += sfsprintf(a, &fam[sizeof(fam)] - a - 1, ".%d", *b++); 3438462SApril.Chin@Sun.COM a = a == fam ? "0" : fam + 1; 3448462SApril.Chin@Sun.COM } 3458462SApril.Chin@Sun.COM if (port) 34610898Sroland.mainz@nrubsig.org sfprintf(sp, "%02d %s%s %s /dev/%s/%s/%d\n", i, m, x, fmtmode(st.st_mode, 0), s, a, port); 3478462SApril.Chin@Sun.COM else 34810898Sroland.mainz@nrubsig.org sfprintf(sp, "%02d %s%s %s /dev/%s/%s\n", i, m, x, fmtmode(st.st_mode, 0), s, a); 3498462SApril.Chin@Sun.COM continue; 3504887Schin } 3518462SApril.Chin@Sun.COM #endif 35210898Sroland.mainz@nrubsig.org sfprintf(sp, "%02d %s%s %s /dev/inode/%u/%u\n", i, m, x, fmtmode(st.st_mode, 0), st.st_dev, st.st_ino); 35310898Sroland.mainz@nrubsig.org } 35410898Sroland.mainz@nrubsig.org if (sp != sfstdout) 35510898Sroland.mainz@nrubsig.org { 35610898Sroland.mainz@nrubsig.org sfsetfd(sp, -1); 35710898Sroland.mainz@nrubsig.org sfclose(sp); 3588462SApril.Chin@Sun.COM } 3594887Schin return 0; 3604887Schin } 361