home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckv192.zip / ckvioc.c < prev    next >
C/C++ Source or Header  |  1996-12-28  |  3KB  |  121 lines

  1. /*
  2.   NOTE: DEC C on OpenVMS AXP does not like an empty header file,
  3.   so we include the following header file unconditionally.
  4. */
  5. #include "ckcdeb.h"            /* Kermit universals */
  6.  
  7. #ifdef DEC_TCPIP
  8. #ifdef VMS
  9. /*
  10.   ioctl() similation for DEC TCP/IP, based on DEC example.
  11.   Used only for DEC TCP/IP (nee UCX).
  12. */
  13. #include "ckvioc.h"            /* IOCTL-specific definitions */
  14.  
  15. #define ISOK(s) (s & 01)        /* For checking $QIOW return value */
  16. /*
  17.   Select proper library function for getting socket device channel.
  18. */
  19. #if defined (__DECC)
  20. # define GET_SDC decc$get_sdc
  21. #elif (defined (VAXC) || defined (__VAXC) || defined(__GNUC__))
  22. # define GET_SDC vaxc$get_sdc
  23. #else
  24. # error unknown compiler, not DECC and not VAXC
  25. #endif /* __DECC */
  26.  
  27. #ifdef __DECC
  28. #include <starlet.h>
  29. #include <lib$routines.h>
  30. #include <socket.h>
  31. #endif /* __DECC */
  32.  
  33. int
  34. ioctl(d, request, argp)
  35.     int d, request;
  36. #ifdef __DECC
  37.     void
  38. #else
  39.     char
  40. #endif /* __DECC */
  41.     *argp;
  42. {
  43.  
  44.     int eflagnum;            /* Event Flag Number */
  45.     int sdc;                /* Socket Device Channel */
  46.     int status;                /* QIOW return code */
  47.     unsigned short fn;            /* QIOW function code  */
  48.     unsigned short iosb[4];        /* IO Status Block */
  49.  
  50.     struct comm {
  51.     int command;
  52.     char *addr;
  53.     } ioctl_comm;            /* QIOW ioctl commands. */
  54.  
  55.     struct it2 {
  56.     unsigned short len;
  57.     unsigned short opt;
  58.     struct comm *addr;
  59.     } ioctl_desc;            /* QIOW IOCTL commands descriptor */
  60.  
  61. #ifdef CK_GETEFN
  62. /*
  63.   It should not be necessary to ask the system for an EFN because:
  64.  
  65.     (a) the $QIOW will do a $SYNC
  66.     (b) there is an explicit IOSB (needed for correct multiprocessor operation)
  67.     (c) we are not threaded
  68.     (d) both the $QIOW return status and the IOSB status are checked
  69. */
  70.     status = lib$get_ef(&eflagnum);    /* Get an event flag number. */
  71.     if (!ISOK(status))            /* Did we? */
  72.       eflagnum = 0;            /* No event flag available, use 0. */
  73. #else
  74.     eflagnum = 0;            /* Use event flag number 0 */
  75. #endif /* CK_GETEFN */
  76.  
  77.     sdc = GET_SDC(d);            /* Get socket device channel number. */
  78.     if (sdc == 0) {
  79.     errno = EBADF;            /* Not an open socket descriptor. */
  80.     return -1;
  81.     }
  82.     ioctl_desc.opt = UCX$C_IOCTL;    /*  Fill in ioctl descriptor. */
  83.     ioctl_desc.len = sizeof(struct comm);
  84.     ioctl_desc.addr = &ioctl_comm;
  85.  
  86. /* Decide QIOW function code and In / Out parameter. */
  87.  
  88.     ioctl_comm.command = request;
  89.     ioctl_comm.addr = argp;
  90.     if (request & IOC_OUT) {
  91.     fn = IO$_SENSEMODE;
  92.     status = sys$qiow(eflagnum,
  93.               sdc, fn, iosb, 0, 0, 0, 0, 0, 0, 0, &ioctl_desc);
  94.     } else {
  95.     fn = IO$_SETMODE;
  96.     status = sys$qiow(eflagnum,
  97.               sdc, fn, iosb, 0, 0, 0, 0, 0, 0, &ioctl_desc, 0);
  98.     }
  99.     if (!ISOK(status)) {
  100.     debug(F101,"ioctl failed: status","",status);
  101.     errno = status;
  102.     return -1;
  103.     }
  104.     if (!ISOK(iosb[0])) {
  105. #ifdef DEBUG
  106.     char tmpbuf[80];
  107.     sprintf(tmpbuf,"ioctl failed: status = %x, %x, %x%x\n",
  108.         iosb[0], iosb[1], iosb[3], iosb[2]);
  109.     debug(F100,(char *)tmpbuf,"",0);
  110. #endif /* DEBUG */
  111.     errno = (long int) iosb[0];
  112.     return -1;
  113.     }
  114. #ifdef CK_GETEFN
  115.     status = lib$free_ef(&eflagnum);
  116. #endif /* CK_GETEFN */
  117.     return 0;
  118. }
  119. #endif /* VMS */
  120. #endif /* DEC_TCPIP */
  121.