/* NOTE: DEC C on OpenVMS AXP does not like an empty header file, so we include the following header file unconditionally. */ #include "ckcdeb.h" /* Kermit universals */ #ifdef DEC_TCPIP #ifdef VMS /* ioctl() similation for DEC TCP/IP, based on DEC example. Used only for DEC TCP/IP (nee UCX). */ #include "ckvioc.h" /* IOCTL-specific definitions */ #define ISOK(s) (s & 01) /* For checking $QIOW return value */ /* Select proper library function for getting socket device channel. */ #if defined (__DECC) # define GET_SDC decc$get_sdc #elif (defined (VAXC) || defined (__VAXC)) # define GET_SDC vaxc$get_sdc #else # error unknown compiler, not DECC and not VAXC #endif /* __DECC */ int ioctl(d, request, argp) int d, request; char *argp; { int eflagnum; /* Event Flag Number */ int sdc; /* Socket Device Channel */ int status; /* QIOW return code */ unsigned short fn; /* QIOW function code */ unsigned short iosb[4]; /* IO Status Block */ char *p5, *p6; /* Arguments p5 and p6 of QIOW */ struct comm { int command; char *addr; } ioctl_comm; /* QIOW ioctl commands. */ struct it2 { unsigned short len; unsigned short opt; struct comm *addr; } ioctl_desc; /* QIOW IOCTL commands descriptor */ #ifdef CK_GETEFN /* It should not be necessary to ask the system for an EFN because: (a) the $QIOW will do a $SYNC (b) there is an explicit IOSB (needed for correct multiprocessor operation) (c) we are not threaded (d) both the $QIOW return status and the IOSB status are checked */ status = LIB$GET_EF(&eflagnum); /* Get an event flag number. */ if (!ISOK(status)) /* Did we? */ eflagnum = 0; /* No event flag available, use 0. */ #else eflagnum = 0; /* Use event flag number 0 */ #endif /* CK_GETEFN */ sdc = GET_SDC(d); /* Get socket device channel number. */ if (sdc == 0) { errno = EBADF; /* Not an open socket descriptor. */ return -1; } ioctl_desc.opt = UCX$C_IOCTL; /* Fill in ioctl descriptor. */ ioctl_desc.len = sizeof(struct comm); ioctl_desc.addr = &ioctl_comm; /* Decide QIOW function code and In / Out parameter. */ if (request & IOC_OUT) { fn = IO$_SENSEMODE; p5 = 0; (struct it2 *)p6 = &ioctl_desc; } else { fn = IO$_SETMODE; (struct it2 *)p5 = &ioctl_desc; p6 = 0; } ioctl_comm.command = request; ioctl_comm.addr = argp; status = SYS$QIOW(eflagnum, sdc, fn, iosb, 0, 0, 0, 0, 0, 0, p5, p6); if (!ISOK(status)) { debug(F101,"ioctl failed: status","",status); errno = status; return -1; } if (!ISOK(iosb[0])) { #ifdef DEBUG char tmpbuf[80]; sprintf(tmpbuf,"ioctl failed: status = %x, %x, %x%x\n", iosb[0], iosb[1], iosb[3], iosb[2]); debug(F100,(char *)tmpbuf,"",0); #endif /* DEBUG */ errno = (long int) iosb[0]; return -1; } #ifdef CK_GETEFN status = LIB$FREE_EF(&eflagnum); #endif /* CK_GETEFN */ return 0; } #endif /* VMS */ #endif /* DEC_TCPIP */