xref: /onnv-gate/usr/src/lib/libcmd/common/fds.c (revision 12068:08a39a083754)
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
b_fds(int argc,char ** argv,void * context)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