1/* netconn.c -- is a particular file descriptor a network connection?. */
2
3/* Copyright (C) 2002-2005 Free Software Foundation, Inc.
4
5   This file is part of GNU Bash, the Bourne Again SHell.
6
7   Bash is free software: you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation, either version 3 of the License, or
10   (at your option) any later version.
11
12   Bash is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include <config.h>
22
23#include <bashtypes.h>
24#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
25#  include <sys/file.h>
26#endif
27#include <posixstat.h>
28#include <filecntl.h>
29
30#include <errno.h>
31
32#if defined (HAVE_UNISTD_H)
33#  include <unistd.h>
34#endif
35
36/* The second and subsequent conditions must match those used to decide
37   whether or not to call getpeername() in isnetconn(). */
38#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && !defined (SVR4_2)
39#  include <sys/socket.h>
40#endif
41
42/* Is FD a socket or network connection? */
43int
44isnetconn (fd)
45     int fd;
46{
47#if defined (HAVE_GETPEERNAME) && !defined (SVR4_2) && !defined (__BEOS__) && !defined(__HAIKU__)
48  int rv;
49  socklen_t l;
50  struct sockaddr sa;
51
52  l = sizeof(sa);
53  rv = getpeername(fd, &sa, &l);
54  /* Posix.2 says getpeername can return these errors. */
55  return ((rv < 0 && (errno == ENOTSOCK || errno == ENOTCONN || errno == EINVAL)) ? 0 : 1);
56#else /* !HAVE_GETPEERNAME || SVR4_2 || __BEOS__ || __HAIKU__ */
57#  if defined (SVR4) || defined (SVR4_2)
58  /* Sockets on SVR4 and SVR4.2 are character special (streams) devices. */
59  struct stat sb;
60
61  if (isatty (fd))
62    return (0);
63  if (fstat (fd, &sb) < 0)
64    return (0);
65#    if defined (S_ISFIFO)
66  if (S_ISFIFO (sb.st_mode))
67    return (0);
68#    endif /* S_ISFIFO */
69  return (S_ISCHR (sb.st_mode));
70#  else /* !SVR4 && !SVR4_2 */
71#    if defined (S_ISSOCK) && !defined (__BEOS__) && !defined(__HAIKU__)
72  struct stat sb;
73
74  if (fstat (fd, &sb) < 0)
75    return (0);
76  return (S_ISSOCK (sb.st_mode));
77#    else /* !S_ISSOCK || __BEOS__ || __HAIKU__ */
78  return (0);
79#    endif /* !S_ISSOCK || __BEOS__ || __HAIKU__ */
80#  endif /* !SVR4 && !SVR4_2 */
81#endif /* !HAVE_GETPEERNAME || SVR4_2 || __BEOS__ || __HAIKU__ */
82}
83