1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman * *
3*b30d1939SAndy Fiddaman * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1992-2012 AT&T Intellectual Property *
5*b30d1939SAndy Fiddaman * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property *
8*b30d1939SAndy Fiddaman * *
9*b30d1939SAndy Fiddaman * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12*b30d1939SAndy Fiddaman * *
13*b30d1939SAndy Fiddaman * Information and Software Systems Research *
14*b30d1939SAndy Fiddaman * AT&T Research *
15*b30d1939SAndy Fiddaman * Florham Park NJ *
16*b30d1939SAndy Fiddaman * *
17*b30d1939SAndy Fiddaman * Glenn Fowler <gsf@research.att.com> *
18*b30d1939SAndy Fiddaman * David Korn <dgk@research.att.com> *
19*b30d1939SAndy Fiddaman * *
20*b30d1939SAndy Fiddaman ***********************************************************************/
21*b30d1939SAndy Fiddaman #pragma prototyped
22*b30d1939SAndy Fiddaman
23*b30d1939SAndy Fiddaman static const char usage[] =
24*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: fds (AT&T Research) 2009-09-09 $\n]"
25*b30d1939SAndy Fiddaman USAGE_LICENSE
26*b30d1939SAndy Fiddaman "[+NAME?fds - list open file descriptor status]"
27*b30d1939SAndy Fiddaman "[+DESCRIPTION?\bfds\b lists the status for each open file descriptor. "
28*b30d1939SAndy Fiddaman "When invoked as a shell builtin it accesses the file descriptors of the "
29*b30d1939SAndy Fiddaman "calling shell, otherwise it lists the file descriptors passed across "
30*b30d1939SAndy Fiddaman "\bexec\b(2).]"
31*b30d1939SAndy Fiddaman "[l:long?List file descriptor details.]"
32*b30d1939SAndy Fiddaman "[u:unit?Write output to \afd\a.]#[fd]"
33*b30d1939SAndy Fiddaman "[+SEE ALSO?\blogname\b(1), \bwho\b(1), \bgetgroups\b(2), \bgetsockname\b(2), \bgetsockopts\b(2)]"
34*b30d1939SAndy Fiddaman ;
35*b30d1939SAndy Fiddaman
36*b30d1939SAndy Fiddaman #include <cmd.h>
37*b30d1939SAndy Fiddaman #include <ls.h>
38*b30d1939SAndy Fiddaman
39*b30d1939SAndy Fiddaman #include "FEATURE/sockets"
40*b30d1939SAndy Fiddaman
41*b30d1939SAndy Fiddaman #if defined(S_IFSOCK) && _sys_socket && _hdr_arpa_inet && _hdr_netinet_in && _lib_getsockname && _lib_getsockopt && _lib_inet_ntoa
42*b30d1939SAndy Fiddaman #include <sys/socket.h>
43*b30d1939SAndy Fiddaman #include <netinet/in.h>
44*b30d1939SAndy Fiddaman #include <arpa/inet.h>
45*b30d1939SAndy Fiddaman #else
46*b30d1939SAndy Fiddaman #undef S_IFSOCK
47*b30d1939SAndy Fiddaman #endif
48*b30d1939SAndy Fiddaman
49*b30d1939SAndy Fiddaman #ifndef minor
50*b30d1939SAndy Fiddaman #define minor(x) (int)((x)&0xff)
51*b30d1939SAndy Fiddaman #endif
52*b30d1939SAndy Fiddaman #ifndef major
53*b30d1939SAndy Fiddaman #define major(x) (int)(((unsigned int)(x)>>8)&0xff)
54*b30d1939SAndy Fiddaman #endif
55*b30d1939SAndy Fiddaman
56*b30d1939SAndy Fiddaman #undef getconf
57*b30d1939SAndy Fiddaman #define getconf(x) strtol(astconf(x,NiL,NiL),NiL,0)
58*b30d1939SAndy Fiddaman
59*b30d1939SAndy Fiddaman #ifdef S_IFSOCK
60*b30d1939SAndy Fiddaman
61*b30d1939SAndy Fiddaman typedef struct NV_s
62*b30d1939SAndy Fiddaman {
63*b30d1939SAndy Fiddaman const char* name;
64*b30d1939SAndy Fiddaman int value;
65*b30d1939SAndy Fiddaman } NV_t;
66*b30d1939SAndy Fiddaman
67*b30d1939SAndy Fiddaman static const NV_t family[] =
68*b30d1939SAndy Fiddaman {
69*b30d1939SAndy Fiddaman #ifdef AF_LOCAL
70*b30d1939SAndy Fiddaman "pipe", AF_LOCAL,
71*b30d1939SAndy Fiddaman #endif
72*b30d1939SAndy Fiddaman #ifdef AF_UNIX
73*b30d1939SAndy Fiddaman "pipe", AF_UNIX,
74*b30d1939SAndy Fiddaman #endif
75*b30d1939SAndy Fiddaman #ifdef AF_FILE
76*b30d1939SAndy Fiddaman "FILE", AF_FILE,
77*b30d1939SAndy Fiddaman #endif
78*b30d1939SAndy Fiddaman #ifdef AF_INET
79*b30d1939SAndy Fiddaman "INET", AF_INET,
80*b30d1939SAndy Fiddaman #endif
81*b30d1939SAndy Fiddaman #ifdef AF_AX25
82*b30d1939SAndy Fiddaman "AX25", AF_AX25,
83*b30d1939SAndy Fiddaman #endif
84*b30d1939SAndy Fiddaman #ifdef AF_IPX
85*b30d1939SAndy Fiddaman "IPX", AF_IPX,
86*b30d1939SAndy Fiddaman #endif
87*b30d1939SAndy Fiddaman #ifdef AF_APPLETALK
88*b30d1939SAndy Fiddaman "APPLETALK", AF_APPLETALK,
89*b30d1939SAndy Fiddaman #endif
90*b30d1939SAndy Fiddaman #ifdef AF_NETROM
91*b30d1939SAndy Fiddaman "NETROM", AF_NETROM,
92*b30d1939SAndy Fiddaman #endif
93*b30d1939SAndy Fiddaman #ifdef AF_BRIDGE
94*b30d1939SAndy Fiddaman "BRIDGE", AF_BRIDGE,
95*b30d1939SAndy Fiddaman #endif
96*b30d1939SAndy Fiddaman #ifdef AF_ATMPVC
97*b30d1939SAndy Fiddaman "ATMPVC", AF_ATMPVC,
98*b30d1939SAndy Fiddaman #endif
99*b30d1939SAndy Fiddaman #ifdef AF_X25
100*b30d1939SAndy Fiddaman "X25", AF_X25,
101*b30d1939SAndy Fiddaman #endif
102*b30d1939SAndy Fiddaman #ifdef AF_INET6
103*b30d1939SAndy Fiddaman "INET6", AF_INET6,
104*b30d1939SAndy Fiddaman #endif
105*b30d1939SAndy Fiddaman #ifdef AF_ROSE
106*b30d1939SAndy Fiddaman "ROSE", AF_ROSE,
107*b30d1939SAndy Fiddaman #endif
108*b30d1939SAndy Fiddaman #ifdef AF_DECnet
109*b30d1939SAndy Fiddaman "DECnet", AF_DECnet,
110*b30d1939SAndy Fiddaman #endif
111*b30d1939SAndy Fiddaman #ifdef AF_NETBEUI
112*b30d1939SAndy Fiddaman "NETBEUI", AF_NETBEUI,
113*b30d1939SAndy Fiddaman #endif
114*b30d1939SAndy Fiddaman #ifdef AF_SECURITY
115*b30d1939SAndy Fiddaman "SECURITY", AF_SECURITY,
116*b30d1939SAndy Fiddaman #endif
117*b30d1939SAndy Fiddaman #ifdef AF_KEY
118*b30d1939SAndy Fiddaman "KEY", AF_KEY,
119*b30d1939SAndy Fiddaman #endif
120*b30d1939SAndy Fiddaman #ifdef AF_NETLINK
121*b30d1939SAndy Fiddaman "NETLINK", AF_NETLINK,
122*b30d1939SAndy Fiddaman #endif
123*b30d1939SAndy Fiddaman #ifdef AF_ROUTE
124*b30d1939SAndy Fiddaman "ROUTE", AF_ROUTE,
125*b30d1939SAndy Fiddaman #endif
126*b30d1939SAndy Fiddaman #ifdef AF_PACKET
127*b30d1939SAndy Fiddaman "PACKET", AF_PACKET,
128*b30d1939SAndy Fiddaman #endif
129*b30d1939SAndy Fiddaman #ifdef AF_ASH
130*b30d1939SAndy Fiddaman "ASH", AF_ASH,
131*b30d1939SAndy Fiddaman #endif
132*b30d1939SAndy Fiddaman #ifdef AF_ECONET
133*b30d1939SAndy Fiddaman "ECONET", AF_ECONET,
134*b30d1939SAndy Fiddaman #endif
135*b30d1939SAndy Fiddaman #ifdef AF_ATMSVC
136*b30d1939SAndy Fiddaman "ATMSVC", AF_ATMSVC,
137*b30d1939SAndy Fiddaman #endif
138*b30d1939SAndy Fiddaman #ifdef AF_SNA
139*b30d1939SAndy Fiddaman "SNA", AF_SNA,
140*b30d1939SAndy Fiddaman #endif
141*b30d1939SAndy Fiddaman #ifdef AF_IRDA
142*b30d1939SAndy Fiddaman "IRDA", AF_IRDA,
143*b30d1939SAndy Fiddaman #endif
144*b30d1939SAndy Fiddaman #ifdef AF_PPPOX
145*b30d1939SAndy Fiddaman "PPPOX", AF_PPPOX,
146*b30d1939SAndy Fiddaman #endif
147*b30d1939SAndy Fiddaman #ifdef AF_WANPIPE
148*b30d1939SAndy Fiddaman "WANPIPE", AF_WANPIPE,
149*b30d1939SAndy Fiddaman #endif
150*b30d1939SAndy Fiddaman #ifdef AF_BLUETOOTH
151*b30d1939SAndy Fiddaman "BLUETOOTH", AF_BLUETOOTH,
152*b30d1939SAndy Fiddaman #endif
153*b30d1939SAndy Fiddaman 0
154*b30d1939SAndy Fiddaman };
155*b30d1939SAndy Fiddaman
156*b30d1939SAndy Fiddaman #endif
157*b30d1939SAndy Fiddaman
158*b30d1939SAndy Fiddaman int
b_fds(int argc,char ** argv,Shbltin_t * context)159*b30d1939SAndy Fiddaman b_fds(int argc, char** argv, Shbltin_t* context)
160*b30d1939SAndy Fiddaman {
161*b30d1939SAndy Fiddaman register char* s;
162*b30d1939SAndy Fiddaman register int i;
163*b30d1939SAndy Fiddaman register char* m;
164*b30d1939SAndy Fiddaman register char* x;
165*b30d1939SAndy Fiddaman int flags;
166*b30d1939SAndy Fiddaman int details;
167*b30d1939SAndy Fiddaman int open_max;
168*b30d1939SAndy Fiddaman int unit;
169*b30d1939SAndy Fiddaman Sfio_t* sp;
170*b30d1939SAndy Fiddaman struct stat st;
171*b30d1939SAndy Fiddaman #ifdef S_IFSOCK
172*b30d1939SAndy Fiddaman struct sockaddr_in addr;
173*b30d1939SAndy Fiddaman char* a;
174*b30d1939SAndy Fiddaman unsigned char* b;
175*b30d1939SAndy Fiddaman unsigned char* e;
176*b30d1939SAndy Fiddaman socklen_t addrlen;
177*b30d1939SAndy Fiddaman socklen_t len;
178*b30d1939SAndy Fiddaman int type;
179*b30d1939SAndy Fiddaman int port;
180*b30d1939SAndy Fiddaman int prot;
181*b30d1939SAndy Fiddaman char num[64];
182*b30d1939SAndy Fiddaman char fam[64];
183*b30d1939SAndy Fiddaman #ifdef INET6_ADDRSTRLEN
184*b30d1939SAndy Fiddaman char nam[256];
185*b30d1939SAndy Fiddaman #endif
186*b30d1939SAndy Fiddaman #endif
187*b30d1939SAndy Fiddaman
188*b30d1939SAndy Fiddaman cmdinit(argc, argv, context, ERROR_CATALOG, 0);
189*b30d1939SAndy Fiddaman details = 0;
190*b30d1939SAndy Fiddaman unit = 1;
191*b30d1939SAndy Fiddaman for (;;)
192*b30d1939SAndy Fiddaman {
193*b30d1939SAndy Fiddaman switch (optget(argv, usage))
194*b30d1939SAndy Fiddaman {
195*b30d1939SAndy Fiddaman case 'l':
196*b30d1939SAndy Fiddaman details = opt_info.num;
197*b30d1939SAndy Fiddaman continue;
198*b30d1939SAndy Fiddaman case 'u':
199*b30d1939SAndy Fiddaman unit = opt_info.num;
200*b30d1939SAndy Fiddaman continue;
201*b30d1939SAndy Fiddaman case '?':
202*b30d1939SAndy Fiddaman error(ERROR_USAGE|4, "%s", opt_info.arg);
203*b30d1939SAndy Fiddaman break;
204*b30d1939SAndy Fiddaman case ':':
205*b30d1939SAndy Fiddaman error(2, "%s", opt_info.arg);
206*b30d1939SAndy Fiddaman break;
207*b30d1939SAndy Fiddaman }
208*b30d1939SAndy Fiddaman break;
209*b30d1939SAndy Fiddaman }
210*b30d1939SAndy Fiddaman argv += opt_info.index;
211*b30d1939SAndy Fiddaman if (error_info.errors || *argv)
212*b30d1939SAndy Fiddaman error(ERROR_USAGE|4, "%s", optusage(NiL));
213*b30d1939SAndy Fiddaman if ((open_max = getconf("OPEN_MAX")) <= 0)
214*b30d1939SAndy Fiddaman open_max = OPEN_MAX;
215*b30d1939SAndy Fiddaman if (unit == 1)
216*b30d1939SAndy Fiddaman sp = sfstdout;
217*b30d1939SAndy Fiddaman else if (fstat(unit, &st) || !(sp = sfnew(NiL, NiL, SF_UNBOUND, unit, SF_WRITE)))
218*b30d1939SAndy Fiddaman error(ERROR_SYSTEM|3, "%d: cannot write to file descriptor");
219*b30d1939SAndy Fiddaman for (i = 0; i <= open_max; i++)
220*b30d1939SAndy Fiddaman {
221*b30d1939SAndy Fiddaman if (fstat(i, &st))
222*b30d1939SAndy Fiddaman {
223*b30d1939SAndy Fiddaman /* not open */
224*b30d1939SAndy Fiddaman continue;
225*b30d1939SAndy Fiddaman }
226*b30d1939SAndy Fiddaman if (!details)
227*b30d1939SAndy Fiddaman {
228*b30d1939SAndy Fiddaman sfprintf(sp, "%d\n", i);
229*b30d1939SAndy Fiddaman continue;
230*b30d1939SAndy Fiddaman }
231*b30d1939SAndy Fiddaman if ((flags = fcntl(i, F_GETFL, (char*)0)) == -1)
232*b30d1939SAndy Fiddaman m = "--";
233*b30d1939SAndy Fiddaman else
234*b30d1939SAndy Fiddaman switch (flags & (O_RDONLY|O_WRONLY|O_RDWR))
235*b30d1939SAndy Fiddaman {
236*b30d1939SAndy Fiddaman case O_RDONLY:
237*b30d1939SAndy Fiddaman m = "r-";
238*b30d1939SAndy Fiddaman break;
239*b30d1939SAndy Fiddaman case O_WRONLY:
240*b30d1939SAndy Fiddaman m = "-w";
241*b30d1939SAndy Fiddaman break;
242*b30d1939SAndy Fiddaman case O_RDWR:
243*b30d1939SAndy Fiddaman m = "rw";
244*b30d1939SAndy Fiddaman break;
245*b30d1939SAndy Fiddaman default:
246*b30d1939SAndy Fiddaman m = "??";
247*b30d1939SAndy Fiddaman break;
248*b30d1939SAndy Fiddaman }
249*b30d1939SAndy Fiddaman x = (fcntl(i, F_GETFD, (char*)0) > 0) ? "x" : "-";
250*b30d1939SAndy Fiddaman if (isatty(i) && (s = ttyname(i)))
251*b30d1939SAndy Fiddaman {
252*b30d1939SAndy Fiddaman sfprintf(sp, "%02d %s%s %s %s\n", i, m, x, fmtmode(st.st_mode, 0), s);
253*b30d1939SAndy Fiddaman continue;
254*b30d1939SAndy Fiddaman }
255*b30d1939SAndy Fiddaman #ifdef S_IFSOCK
256*b30d1939SAndy Fiddaman addrlen = sizeof(addr);
257*b30d1939SAndy Fiddaman memset(&addr, 0, addrlen);
258*b30d1939SAndy Fiddaman if (!getsockname(i, (struct sockaddr*)&addr, (void*)&addrlen))
259*b30d1939SAndy Fiddaman {
260*b30d1939SAndy Fiddaman type = 0;
261*b30d1939SAndy Fiddaman prot = 0;
262*b30d1939SAndy Fiddaman #ifdef SO_TYPE
263*b30d1939SAndy Fiddaman len = sizeof(type);
264*b30d1939SAndy Fiddaman if (getsockopt(i, SOL_SOCKET, SO_TYPE, (void*)&type, (void*)&len))
265*b30d1939SAndy Fiddaman type = -1;
266*b30d1939SAndy Fiddaman #endif
267*b30d1939SAndy Fiddaman #ifdef SO_PROTOTYPE
268*b30d1939SAndy Fiddaman len = sizeof(prot);
269*b30d1939SAndy Fiddaman if (getsockopt(i, SOL_SOCKET, SO_PROTOTYPE, (void*)&prot, (void*)&len))
270*b30d1939SAndy Fiddaman prot = -1;
271*b30d1939SAndy Fiddaman #endif
272*b30d1939SAndy Fiddaman if (!st.st_mode)
273*b30d1939SAndy Fiddaman st.st_mode = S_IFSOCK|S_IRUSR|S_IWUSR;
274*b30d1939SAndy Fiddaman s = 0;
275*b30d1939SAndy Fiddaman switch (type)
276*b30d1939SAndy Fiddaman {
277*b30d1939SAndy Fiddaman case SOCK_DGRAM:
278*b30d1939SAndy Fiddaman switch (addr.sin_family)
279*b30d1939SAndy Fiddaman {
280*b30d1939SAndy Fiddaman case AF_INET:
281*b30d1939SAndy Fiddaman #ifdef AF_INET6
282*b30d1939SAndy Fiddaman case AF_INET6:
283*b30d1939SAndy Fiddaman #endif
284*b30d1939SAndy Fiddaman s = "udp";
285*b30d1939SAndy Fiddaman break;
286*b30d1939SAndy Fiddaman }
287*b30d1939SAndy Fiddaman break;
288*b30d1939SAndy Fiddaman case SOCK_STREAM:
289*b30d1939SAndy Fiddaman switch (addr.sin_family)
290*b30d1939SAndy Fiddaman {
291*b30d1939SAndy Fiddaman case AF_INET:
292*b30d1939SAndy Fiddaman #ifdef AF_INET6
293*b30d1939SAndy Fiddaman case AF_INET6:
294*b30d1939SAndy Fiddaman #endif
295*b30d1939SAndy Fiddaman #ifdef IPPROTO_SCTP
296*b30d1939SAndy Fiddaman if (prot == IPPROTO_SCTP)
297*b30d1939SAndy Fiddaman s = "sctp";
298*b30d1939SAndy Fiddaman else
299*b30d1939SAndy Fiddaman #endif
300*b30d1939SAndy Fiddaman s = "tcp";
301*b30d1939SAndy Fiddaman break;
302*b30d1939SAndy Fiddaman }
303*b30d1939SAndy Fiddaman break;
304*b30d1939SAndy Fiddaman #ifdef SOCK_RAW
305*b30d1939SAndy Fiddaman case SOCK_RAW:
306*b30d1939SAndy Fiddaman s = "raw";
307*b30d1939SAndy Fiddaman break;
308*b30d1939SAndy Fiddaman #endif
309*b30d1939SAndy Fiddaman #ifdef SOCK_RDM
310*b30d1939SAndy Fiddaman case SOCK_RDM:
311*b30d1939SAndy Fiddaman s = "rdm";
312*b30d1939SAndy Fiddaman break;
313*b30d1939SAndy Fiddaman #endif
314*b30d1939SAndy Fiddaman #ifdef SOCK_SEQPACKET
315*b30d1939SAndy Fiddaman case SOCK_SEQPACKET:
316*b30d1939SAndy Fiddaman s = "seqpacket";
317*b30d1939SAndy Fiddaman break;
318*b30d1939SAndy Fiddaman #endif
319*b30d1939SAndy Fiddaman }
320*b30d1939SAndy Fiddaman if (!s)
321*b30d1939SAndy Fiddaman {
322*b30d1939SAndy Fiddaman for (type = 0; family[type].name && family[type].value != addr.sin_family; type++);
323*b30d1939SAndy Fiddaman if (!(s = (char*)family[type].name))
324*b30d1939SAndy Fiddaman sfsprintf(s = num, sizeof(num), "family.%d", addr.sin_family);
325*b30d1939SAndy Fiddaman }
326*b30d1939SAndy Fiddaman port = 0;
327*b30d1939SAndy Fiddaman #ifdef INET6_ADDRSTRLEN
328*b30d1939SAndy Fiddaman if (a = (char*)inet_ntop(addr.sin_family, &addr.sin_addr, nam, sizeof(nam)))
329*b30d1939SAndy Fiddaman port = ntohs(addr.sin_port);
330*b30d1939SAndy Fiddaman else
331*b30d1939SAndy Fiddaman #endif
332*b30d1939SAndy Fiddaman if (addr.sin_family == AF_INET)
333*b30d1939SAndy Fiddaman {
334*b30d1939SAndy Fiddaman a = inet_ntoa(addr.sin_addr);
335*b30d1939SAndy Fiddaman port = ntohs(addr.sin_port);
336*b30d1939SAndy Fiddaman }
337*b30d1939SAndy Fiddaman else
338*b30d1939SAndy Fiddaman {
339*b30d1939SAndy Fiddaman a = fam;
340*b30d1939SAndy Fiddaman e = (b = (unsigned char*)&addr) + addrlen;
341*b30d1939SAndy Fiddaman while (b < e && a < &fam[sizeof(fam)-1])
342*b30d1939SAndy Fiddaman a += sfsprintf(a, &fam[sizeof(fam)] - a - 1, ".%d", *b++);
343*b30d1939SAndy Fiddaman a = a == fam ? "0" : fam + 1;
344*b30d1939SAndy Fiddaman }
345*b30d1939SAndy Fiddaman if (port)
346*b30d1939SAndy Fiddaman sfprintf(sp, "%02d %s%s %s /dev/%s/%s/%d\n", i, m, x, fmtmode(st.st_mode, 0), s, a, port);
347*b30d1939SAndy Fiddaman else
348*b30d1939SAndy Fiddaman sfprintf(sp, "%02d %s%s %s /dev/%s/%s\n", i, m, x, fmtmode(st.st_mode, 0), s, a);
349*b30d1939SAndy Fiddaman continue;
350*b30d1939SAndy Fiddaman }
351*b30d1939SAndy Fiddaman #endif
352*b30d1939SAndy Fiddaman 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);
353*b30d1939SAndy Fiddaman }
354*b30d1939SAndy Fiddaman if (sp != sfstdout)
355*b30d1939SAndy Fiddaman {
356*b30d1939SAndy Fiddaman sfsetfd(sp, -1);
357*b30d1939SAndy Fiddaman sfclose(sp);
358*b30d1939SAndy Fiddaman }
359*b30d1939SAndy Fiddaman return 0;
360*b30d1939SAndy Fiddaman }
361