Watt-32 tcp/ip  2.2 dev-rel.10
fsext.c
Go to the documentation of this file.
1 
5 /* BSD sockets functionality for Watt-32 TCP/IP
6  *
7  * Copyright (c) 1997-2002 Gisle Vanem <gvanem@yahoo.no>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  * must display the following acknowledgement:
19  * This product includes software developed by Gisle Vanem
20  * Bergen, Norway.
21  *
22  * THIS SOFTWARE IS PROVIDED BY ME (Gisle Vanem) AND CONTRIBUTORS ``AS IS''
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL I OR CONTRIBUTORS BE LIABLE FOR ANY
26  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Version
34  *
35  * 0.5 : Jan 21, 1998 : G. Vanem - created
36  * 0.6 : Apr 28, 2003 : G. Vanem - updates for djgpp 2.04
37  */
38 
39 #include "socket.h"
40 
41 #if defined(__DJGPP__) && defined(USE_BSD_API) && defined(USE_FSEXT)
42 
43 #include <sys/fsext.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
46 #include <unistd.h>
47 
48 #ifndef S_IFSOCK
49 #define S_IFSOCK 0x10000
50 #endif
51 
52 #if (DJGPP_MINOR < 4)
53 #define blksize_t off_t
54 #endif
55 
56 struct wstat {
57  time_t st_atime;
58  time_t st_ctime;
59  dev_t st_dev;
60  gid_t st_gid;
61  ino_t st_ino;
62  mode_t st_mode;
63  time_t st_mtime;
64  nlink_t st_nlink;
65  off_t st_size;
66  blksize_t st_blksize;
67  uid_t st_uid;
68  dev_t st_rdev;
69  };
70 
71 
72 #if defined(USE_DEBUG)
73 /*
74  * Handle printing of function names
75  */
76 static const struct search_list fs_func[] = {
77  { __FSEXT_nop, "nop" },
78  { __FSEXT_open, "open" },
79  { __FSEXT_creat, "creat" },
80  { __FSEXT_read, "read" },
81  { __FSEXT_write, "write" },
82  { __FSEXT_ready, "ready" },
83  { __FSEXT_close, "close" },
84  { __FSEXT_fcntl, "fcntl" },
85  { __FSEXT_ioctl, "ioctl" },
86  { __FSEXT_lseek, "lseek" },
87  { __FSEXT_link, "link" },
88  { __FSEXT_unlink,"unlink" },
89 #if (DJGPP_MINOR >= 2)
90  { __FSEXT_dup, "dup" },
91  { __FSEXT_dup2, "dup2" },
92  { __FSEXT_fstat, "fstat" },
93  { __FSEXT_stat, "stat" },
94 #endif
95 #if (DJGPP_MINOR >= 4)
96  { __FSEXT_llseek, "llseek" },
97  { __FSEXT_readlink,"readlink" },
98  { __FSEXT_symlink, "symlink" },
99  { __FSEXT_fchown, "fchown" },
100  { __FSEXT_chmod, "chmod", },
101  { __FSEXT_chown, "chown", },
102  { __FSEXT_fchmod, "fchmod" }
103 #endif
104  };
105 #endif /* USE_DEBUG */
106 
107 /*
108  * Filesystem extensions for BSD-sockets and djgpp 2.x
109  */
110 int _fsext_demux (__FSEXT_Fnumber func, int *rv, va_list _args)
111 {
112  int fd = va_arg (_args, int);
113  int cmd = va_arg (_args, int);
114  int arg = va_arg (_args, int);
115  Socket *sock = __FSEXT_get_data (fd); /* same as _socklist_find(fd) */
116 
117  SOCK_DEBUGF (("\n_fsext_demux: fd %d%c, func %d = \"%s\", cmd %08lX, arg %08lX",
118  fd, sock ? 's' : 'f', func,
119  list_lookup(func, fs_func, DIM(fs_func)),
120  (DWORD)cmd, (DWORD)arg));
121 
122  /* fd is not a valid socket, pass on to lower layer
123  */
124  if (!sock)
125  return (0);
126 
127  switch (func)
128  {
129  case __FSEXT_read: /* read (fd,&buf,len) */
130  *rv = read_s (fd, (char*)cmd, arg);
131  return (1);
132 
133  case __FSEXT_write: /* write (fd,&buf,len) */
134  *rv = write_s (fd, (char*)cmd, arg);
135  return (1);
136 
137  case __FSEXT_close: /* close (fd) */
138  if (sock->fd_duped == 0)
139  *rv = close_s (fd);
140  else
141  {
142  sock->fd_duped--;
143  *rv = 0;
144  }
145  return (1);
146 
147  case __FSEXT_ioctl: /* ioctl (fd,cmd,...) */
148  *rv = ioctlsocket (fd, cmd, (char*)arg);
149  return (1);
150 
151  case __FSEXT_fcntl: /* 'fcntl (fd,cmd)' or 'fcntl (fd,cmd,arg)' */
152  *rv = fcntlsocket (fd, cmd, (long)arg);
153  return (1);
154 
155  case __FSEXT_ready: /* ready (fd) called from select() */
156  {
157  struct timeval tv;
158  fd_set fd_read, fd_write, fd_err;
159 
160  FD_ZERO (&fd_read);
161  FD_ZERO (&fd_write);
162  FD_ZERO (&fd_err);
163  FD_SET (fd, &fd_read);
164  FD_SET (fd, &fd_write);
165  FD_SET (fd, &fd_err);
166  tv.tv_sec = 0;
167  tv.tv_usec = 0L;
168  *rv = 0;
169 
170  if (select_s (fd+1, &fd_read, &fd_write, &fd_err, &tv) >= 0)
171  {
172  if (FD_ISSET(fd,&fd_read))
173  *rv |= __FSEXT_ready_read;
174  if (FD_ISSET(fd,&fd_write))
175  *rv |= __FSEXT_ready_write;
176  if (FD_ISSET(fd,&fd_err))
177  *rv |= __FSEXT_ready_error;
178  }
179  else
180  *rv = -1;
181  }
182  return (1);
183 
184  case __FSEXT_creat:
185  return (0);
186 
187 #if (DJGPP_MINOR >= 2) /* functions added in v2.02 */
188  case __FSEXT_dup: /* dup (fd) */
189  *rv = fd;
190  if (sock->fd_duped < UINT_MAX)
191  sock->fd_duped++;
192  return (1);
193 
194  case __FSEXT_dup2: /* dup2 (oldfd,newfd) */
195  close (cmd); /* close (newd) */
196  *rv = socket (sock->so_family, sock->so_type, sock->so_proto);
197  return (1);
198 
199  case __FSEXT_fstat:
200 #if defined(USE_STATISTICS)
201  {
202  struct wstat *stat = (struct wstat*) cmd;
203  int size;
204 
205  *rv = 0;
206  stat->st_mode = S_IFSOCK;
207 
208  /* Hmm. If user really want this, lets return it */
209  switch (sock->so_proto)
210  {
211  case IPPROTO_TCP:
212  size = min (sizeof(tcpstats), sizeof(struct stat));
213  memcpy (rv, &tcpstats, size);
214  break;
215  case IPPROTO_UDP:
216  size = min (sizeof(udpstats), sizeof(struct stat));
217  memcpy (rv, &udpstats, size);
218  break;
219  case IPPROTO_ICMP:
220  size = min (sizeof(icmpstats), sizeof(struct stat));
221  memcpy (rv, &icmpstats, size);
222  break;
223  case IPPROTO_IGMP:
224  size = min (sizeof(igmpstats), sizeof(struct stat));
225  memcpy (rv, &igmpstats, size);
226  break;
227  case IPPROTO_IP:
228  size = min (sizeof(ip4stats), sizeof(struct stat));
229  memcpy (rv, &ip4stats, size);
230  break;
231 #if defined(IPPROTO_IP6)
232  case IPPROTO_IP6:
233  size = min (sizeof(ip6stats), sizeof(struct stat));
234  memcpy (rv, &ip6stats, size);
235  break;
236 #endif
237  default:
238  *rv = -1;
239  }
240  }
241  return (1);
242 #else
243  return (0);
244 #endif /* USE_STATISTICS */
245 
246 #endif /* DJGPP_MINOR >= 2 */
247 
248  default:
249  SOCK_DEBUGF ((" unhandled FSext function"));
250  break;
251  }
252  return (0); /* unhandled, pass on to lower layer */
253 }
254 
255 #endif /* __DJGPP__ && USE_BSD_API && USE_FSEXT */
256 
Definition: wtypes.h:197
int W32_CALL select_s(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
The select_s() function.
Definition: select.c:112
Definition: socket.h:137
const char * list_lookup(DWORD type, const struct search_list *list, int num)
Search 'list' for 'type' and return it's name.
Definition: misc.c:929
Definition: fsext.c:56
Definition: wtime.h:38
int W32_CALL socket(int family, int type, int protocol)
socket().
Definition: socket.c:1794
int MS_CDECL fcntlsocket(int s, int cmd,...)
Definition: fcntl.c:69