⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsext.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/*
 *
 *   BSD sockets functionality for Waterloo TCP/IP
 *
 *   Version
 *
 *   0.5 : Jan 21, 1998 : G. Vanem - created
 */

#include "socket.h"

#if defined(__DJGPP__) && defined(USE_BSD_FUNC) && defined(USE_FSEXT)

#include <sys/fsext.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#if defined(USE_DEBUG)
/*
 * Handle printing of function names
 */
struct func_list {
       int         func_val;
       const char *func_name;
     };

static __inline const char *lookup (int option, struct func_list *opt, int num)
{
  while (num)
  {
    if (opt->func_val == option)
       return (opt->func_name);
    num--;
    opt++;
  }
  return ("??");
}

static struct func_list fs_func[] = {
                      { __FSEXT_nop,   "nop"    },
                      { __FSEXT_open,  "open"   },
                      { __FSEXT_creat, "creat"  },
                      { __FSEXT_read,  "read"   },
                      { __FSEXT_write, "write"  },
                      { __FSEXT_ready, "ready"  },
                      { __FSEXT_close, "close"  },
                      { __FSEXT_fcntl, "fcntl"  },
                      { __FSEXT_ioctl, "ioctl"  },
                      { __FSEXT_lseek, "lseek"  },
                      { __FSEXT_link,  "link"   },
                      { __FSEXT_unlink,"unlink" },
#if (DJGPP_MINOR >= 2)
                      { __FSEXT_dup,   "dup"    },
                      { __FSEXT_dup2,  "dup2"   },
                      { __FSEXT_fstat, "fstat"  },
                      { __FSEXT_stat,  "stat"   },
#endif
                    };
#endif /* USE_DEBUG */

/*
 * Filesystem extensions for BSD-sockets and djgpp 2.x
 */
int _fsext_demux (__FSEXT_Fnumber func, int *rv, va_list _args)
{
  int     fd   = va_arg (_args, int);
  int     cmd  = va_arg (_args, int);
  int     arg  = va_arg (_args, int);
  Socket *sock = __FSEXT_get_data (fd); /* same as _socklist_find(fd) */

  SOCK_DEBUGF ((NULL,
     "\n_fsext_demux: fd %d%c, func %d = \"%s\", cmd %08lX, arg %08lX",
     fd, sock ? 's' : 'f', func, lookup (func, fs_func, DIM(fs_func)),
     (DWORD)cmd, (DWORD)arg));


  /* fd is not a valid socket, pass on to lower layer
   */
  if (!sock)
     return (0);

  switch (func)
  {
    case __FSEXT_read:                        /* read (fd,&buf,len) */
         *rv = read_s (fd, (char*)cmd, arg);
         return (1);

    case __FSEXT_write:                       /* write (fd,&buf,len) */
         *rv = write_s (fd, (char*)cmd, arg);
         return (1);

    case __FSEXT_close:                       /* close (fd) */
         if (sock->fd_duped == 0)
            *rv = close_s (fd);
         else
         {
           sock->fd_duped--;
           *rv = 0;
         }
         return (1);

    case __FSEXT_ioctl:   /* ioctl (fd,cmd,...) */
         *rv = ioctlsocket (fd, cmd, (char*)arg); 
         return (1);

    case __FSEXT_fcntl:   /* 'fcntl (fd,cmd)' or 'fcntl (fd,cmd,arg)' */
         *rv = fcntlsocket (fd, cmd, (long)arg);
         return (1);

    case __FSEXT_ready:   /* ready (fd) */
#if 0    /* avoid the overhead of select_s() */
         tcp_tick (NULL);
         *rv = 0;
         if (_sock_read_select(sock) > 0)
            *rv |= __FSEXT_ready_read;

         if (_sock_write_select(sock) > 0)
            *rv |= __FSEXT_ready_write;

         if (_sock_exc_select(sock) > 0)
            *rv |= __FSEXT_ready_error;

#else    /* include trace from select_s() */
         {
           struct  timeval timeout;
           fd_set  fd_read, fd_write, fd_err;

           FD_ZERO (&fd_read);
           FD_ZERO (&fd_write);
           FD_ZERO (&fd_err);
           FD_SET (fd, &fd_read);
           FD_SET (fd, &fd_write);
           FD_SET (fd, &fd_err);
           timeout.tv_sec  = 0;
           timeout.tv_usec = 0L;
           *rv = 0;

           if (select_s (fd+1, &fd_read, &fd_write, &fd_err, &timeout) >= 0)
           {
             if (FD_ISSET(fd,&fd_read))  *rv |= __FSEXT_ready_read;
             if (FD_ISSET(fd,&fd_write)) *rv |= __FSEXT_ready_write;
             if (FD_ISSET(fd,&fd_err))   *rv |= __FSEXT_ready_error;
           }
           else
             *rv = -1;
         }
#endif
         return (1);

    case __FSEXT_creat:
         return (0);

#if (DJGPP_MINOR >= 2)    /* functions added in v2.02 */
    case __FSEXT_dup:     /* dup (fd) */
         *rv = fd;
         sock->fd_duped++;
         return (1);

    case __FSEXT_dup2:    /* dup2 (oldfd,newfd) */
         {
           int type  = sock->so_type;  /* don't use 'sock' after close() */
           int proto = sock->so_proto;

           close (cmd);   /* close (newd) */
           *rv = socket (AF_INET, type, proto);
         }
         return (1);

    case __FSEXT_fstat:   /* Hmm. If user really want this, lets return it */
    case __FSEXT_stat:
#if defined(USE_STATISTICS)
         *rv = 0;
         switch (sock->so_proto)
         {
           int size;

           case IPPROTO_TCP:
                size = min (sizeof(tcpstats), sizeof(struct stat));
                memcpy (rv, &tcpstats, size);
                break;
           case IPPROTO_UDP:
                size = min (sizeof(udpstats), sizeof(struct stat));
                memcpy (rv, &udpstats, size);
                break;
           case IPPROTO_ICMP:
                size = min (sizeof(icmpstats), sizeof(struct stat));
                memcpy (rv, &icmpstats, size);
                break;
           case IPPROTO_IGMP:
                size = min (sizeof(igmpstats), sizeof(struct stat));
                memcpy (rv, &igmpstats, size);
                break;
           case IPPROTO_IP:
                size = min (sizeof(ipstats), sizeof(struct stat));
                memcpy (rv, &ipstats, size);
                break;
           default:
                *rv = -1;
         }
         return (1);
#else
         return (0);
#endif  /* USE_STATISTICS */

#endif  /* DJGPP_MINOR >= 2 */

    default:
         break;
  }
  return (0);    /* unhandled, pass on to lower layer */
}

#endif /* __DJGPP__ && USE_BSD_FUNC && USE_FSEXT */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -