home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / ckvioc.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  3KB  |  125 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. #ifndef UCX$C_IOCTL
  34. #define UCX$C_IOCTL 2
  35. #endif /* UCX$C_IOCTL */
  36.  
  37. int
  38. ioctl(d, request, argp)
  39.     int d, request;
  40. #ifdef __DECC
  41.     void
  42. #else
  43.     char
  44. #endif /* __DECC */
  45.     *argp;
  46. {
  47.  
  48.     int eflagnum;            /* Event Flag Number */
  49.     int sdc;                /* Socket Device Channel */
  50.     int status;                /* QIOW return code */
  51.     unsigned short fn;            /* QIOW function code  */
  52.     unsigned short iosb[4];        /* IO Status Block */
  53.  
  54.     struct comm {
  55.     int command;
  56.     char *addr;
  57.     } ioctl_comm;            /* QIOW ioctl commands. */
  58.  
  59.     struct it2 {
  60.     unsigned short len;
  61.     unsigned short opt;
  62.     struct comm *addr;
  63.     } ioctl_desc;            /* QIOW IOCTL commands descriptor */
  64.  
  65. #ifdef CK_GETEFN
  66. /*
  67.   It should not be necessary to ask the system for an EFN because:
  68.  
  69.     (a) the $QIOW will do a $SYNC
  70.     (b) there is an explicit IOSB (needed for correct multiprocessor operation)
  71.     (c) we are not threaded
  72.     (d) both the $QIOW return status and the IOSB status are checked
  73. */
  74.     status = lib$get_ef(&eflagnum);    /* Get an event flag number. */
  75.     if (!ISOK(status))            /* Did we? */
  76.       eflagnum = 0;            /* No event flag available, use 0. */
  77. #else
  78.     eflagnum = 0;            /* Use event flag number 0 */
  79. #endif /* CK_GETEFN */
  80.  
  81.     sdc = GET_SDC(d);            /* Get socket device channel number. */
  82.     if (sdc == 0) {
  83.     errno = EBADF;            /* Not an open socket descriptor. */
  84.     return -1;
  85.     }
  86.     ioctl_desc.opt = UCX$C_IOCTL;    /*  Fill in ioctl descriptor. */
  87.     ioctl_desc.len = sizeof(struct comm);
  88.     ioctl_desc.addr = &ioctl_comm;
  89.  
  90. /* Decide QIOW function code and In / Out parameter. */
  91.  
  92.     ioctl_comm.command = request;
  93.     ioctl_comm.addr = argp;
  94.     if (request & IOC_OUT) {
  95.     fn = IO$_SENSEMODE;
  96.     status = sys$qiow(eflagnum,
  97.               sdc, fn, iosb, 0, 0, 0, 0, 0, 0, 0, &ioctl_desc);
  98.     } else {
  99.     fn = IO$_SETMODE;
  100.     status = sys$qiow(eflagnum,
  101.               sdc, fn, iosb, 0, 0, 0, 0, 0, 0, &ioctl_desc, 0);
  102.     }
  103.     if (!ISOK(status)) {
  104.     debug(F101,"ioctl failed: status","",status);
  105.     errno = status;
  106.     return -1;
  107.     }
  108.     if (!ISOK(iosb[0])) {
  109. #ifdef DEBUG
  110.     char tmpbuf[80];
  111.     sprintf(tmpbuf,"ioctl failed: status = %x, %x, %x%x\n",
  112.         iosb[0], iosb[1], iosb[3], iosb[2]);
  113.     debug(F100,(char *)tmpbuf,"",0);
  114. #endif /* DEBUG */
  115.     errno = (long int) iosb[0];
  116.     return -1;
  117.     }
  118. #ifdef CK_GETEFN
  119.     status = lib$free_ef(&eflagnum);
  120. #endif /* CK_GETEFN */
  121.     return 0;
  122. }
  123. #endif /* VMS */
  124. #endif /* DEC_TCPIP */
  125.