📄 clntpipe.c
字号:
* sub-optimal code appears inside the loop because we have * some clock time to spare while the packets are in flight. * (We assume that this is actually only executed once.) */ reply_msg.acpted_rply.ar_verf = _null_auth; reply_msg.acpted_rply.ar_results.where = resultsp; reply_msg.acpted_rply.ar_results.proc = xresults;#ifndef WIN32 FD_ZERO (&mask); FD_SET (cu->cu_fd, &mask);#endif for(;;) {#ifndef WIN32 readFds = mask; switch (select (FD_SETSIZE, &readFds, (fd_set *)NULL, (fd_set *)NULL, &(cu->cu_wait)))#else switch (mailslotSelect ((int)cu->cu_wait.tv_sec))#endif { case 0: time_waited.tv_sec += cu->cu_wait.tv_sec; time_waited.tv_usec += cu->cu_wait.tv_usec; while(time_waited.tv_usec >= 1000000) { time_waited.tv_sec++; time_waited.tv_usec -= 1000000; } if((time_waited.tv_sec < timeout.tv_sec) || ((time_waited.tv_sec == timeout.tv_sec) && (time_waited.tv_usec < timeout.tv_usec))) goto send_again; return (cu->cu_error.re_status = RPC_TIMEDOUT); /* * buggy in other cases because time_waited is not being * updated */ case -1: if(errno == EINTR) continue; cu->cu_error.re_errno = errno; return (cu->cu_error.re_status = RPC_CANTRECV); } do { inlen = clnttty_rcv (cu->cu_fd, cu->cu_inbuf, cu->cu_recvsz); } while(inlen < 0 && (errno == EINTR)); if(inlen < 0) {#ifdef WIN32 if(errno == WSAEWOULDBLOCK)#else if(errno == EWOULDBLOCK)#endif continue; cu->cu_error.re_errno = errno; return (cu->cu_error.re_status = RPC_CANTRECV); } if(inlen < (int) sizeof(u_long)) continue; /* see if reply transaction id matches sent id */ if(*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf))) continue; /* we now assume we have the proper reply */ break; } /* * now decode and validate the response */ xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE); ok = xdr_replymsg(&reply_xdrs, &reply_msg); if (ok) {#ifndef SUN4_SOLARIS2 _seterr_reply(&reply_msg, &(cu->cu_error));#else __seterr_reply(&reply_msg, &(cu->cu_error));#endif /* !SUN4_SOLARIS2 */ if(cu->cu_error.re_status == RPC_SUCCESS) { if(! AUTH_VALIDATE(cl->cl_auth, &reply_msg.acpted_rply.ar_verf)) { cu->cu_error.re_status = RPC_AUTHERROR; cu->cu_error.re_why = AUTH_INVALIDRESP; } if(reply_msg.acpted_rply.ar_verf.oa_base != NULL) { xdrs->x_op = XDR_FREE; (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); } } /* end successful completion */ else { /* maybe our credentials need to be refreshed ... */ if(nrefreshes > 0 && /* 4.0 */ AUTH_REFRESH(cl->cl_auth)) goto call_again; } /* end of unsuccessful completion */ } /* end of valid reply message */ else { cu->cu_error.re_status = RPC_CANTDECODERES; } return (cu->cu_error.re_status); }static void clnttty_geterr ( CLIENT *cl, struct rpc_err *errp ) { register struct cu_data *cu = (struct cu_data *)cl->cl_private; *errp = cu->cu_error; }static bool_t clnttty_freeres ( CLIENT *cl, xdrproc_t xdr_res, caddr_t res_ptr ) { register struct cu_data *cu = (struct cu_data *)cl->cl_private; register XDR *xdrs = &(cu->cu_outxdrs); xdrs->x_op = XDR_FREE; return ((*xdr_res)(xdrs, res_ptr)); }static void clnttty_abort ( CLIENT *h ) { }static bool_t clnttty_control ( CLIENT *cl, int request, char *info ) { register struct cu_data *cu = (struct cu_data *) cl->cl_private; switch(request) { case CLSET_TIMEOUT: cu->cu_total = *(struct timeval *) info; break; case CLGET_TIMEOUT: *(struct timeval *) info = cu->cu_total; break; case CLSET_RETRY_TIMEOUT: cu->cu_wait = *(struct timeval *)info; break; case CLGET_RETRY_TIMEOUT: *(struct timeval *) info = cu->cu_wait; break; default: return (FALSE); } return (TRUE); }static void clnttty_destroy ( CLIENT *cl ) { register struct cu_data *cu = (struct cu_data *)cl->cl_private; XDR_DESTROY(&(cu->cu_outxdrs)); mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz)); mem_free((caddr_t)cl, sizeof(CLIENT));#ifdef WIN32 mailslotClose ((HANDLE)t2h_fd); mailslotClose ((HANDLE)h2t_fd);#endif }/******************************************************************************** clnttty_send - write data after prepending the two bytes packet length.*/ static int clnttty_send ( int fd, char * inBuf, int nBytes ) { int bytesSent; int totalBytes; int buf[UDP_IP_HDR_SIZE/sizeof (int)]; char * pUdpIpHdr; int len; char * outBuf;#ifndef WIN32 len = sizeof(short);#else len = 0;#endif totalBytes = nBytes + UDP_IP_HDR_SIZE + len; /* set up a dummy UDP/IP header */ pUdpIpHdr = (char *) buf; bzero (pUdpIpHdr, UDP_IP_HDR_SIZE); pUdpIpHdr [IP_VERS_LEN] = 0x45; /* XXX - little endian 0x54? */ pUdpIpHdr [IP_PROT] = IPPROTO_UDP; * (short *) &pUdpIpHdr [UDP_DEST_PORT] = htons(WDBPORT); outBuf = (char *) malloc (nBytes + UDP_IP_HDR_SIZE + sizeof(short)); if(outBuf == NULL) return (0); /* prepending the packet length here */#ifndef WIN32 * (short *) &outBuf[0] = nBytes + UDP_IP_HDR_SIZE;#endif memcpy (outBuf + len, pUdpIpHdr, UDP_IP_HDR_SIZE); memcpy (outBuf + len + UDP_IP_HDR_SIZE, inBuf, nBytes); /* write out the data */#ifndef WIN32 bytesSent = write (h2t_fd, outBuf, totalBytes);#else /* WIN32 */ bytesSent = mailslotWrite ((HANDLE) h2t_fd, outBuf, totalBytes);#endif /* WIN32 */ if (bytesSent < 0) goto sendError; free (outBuf); return (nBytes);sendError:#ifdef WIN32 if (bytesSent == -3) { /* map ERROR_SIMULATOR_KILLED */ tgtSvrKill (); errno = EPIPE; } else if (bytesSent == -2) errno = EPIPE; /* map ERROR_DISCONNECTED to the broken pipe */#endif free (outBuf); return 0; }/******************************************************************************** clnttty_rcv - get input over a pipe** This routine first gets the first two bytes (packet length), then uses the * packet length to get the rest of the packet.* It assumes there is a UDP/IP header at the beggining, which it throws* away.*/ static int clnttty_rcv ( int fd, char * buf, int nBytes ) { int bytesRead; short totalBytes = 0; char szTotalByte[sizeof(short)] = {0};#ifdef WIN32 unsigned char tmpBuf[MAX_MSG_SIZE];#endif#ifndef WIN32 if (read (t2h_fd, szTotalByte, sizeof(short)) < (int) sizeof(short)) { wpwrLogErr ("clnttty_rcv: can't read packet length"); return (0); } totalBytes = * (short *) szTotalByte; /* throw away UDP_IP_HDR */ if (read (t2h_fd, buf, UDP_IP_HDR_SIZE) < UDP_IP_HDR_SIZE) { wpwrLogErr ("clnttty_rcv: can't read UDP_IP_HDR"); return (0); } bytesRead = read (t2h_fd, buf, totalBytes - UDP_IP_HDR_SIZE); if (bytesRead < totalBytes - UDP_IP_HDR_SIZE) { wpwrLogErr ("clnttty_rcv: can't read packet data."); return (0); }#else bytesRead = mailslotRead ((HANDLE)t2h_fd, tmpBuf, MAX_MSG_SIZE); if (bytesRead <= UDP_IP_HDR_SIZE) return (0); memcpy (buf, tmpBuf + UDP_IP_HDR_SIZE, bytesRead - UDP_IP_HDR_SIZE); bytesRead = bytesRead - UDP_IP_HDR_SIZE;#endif /* ! WIN32 */ return (bytesRead); }#ifndef WIN32/******************************************************************************** clnttty_flush - flush a pipe device.** This routine uses POSIX defined routines in order to flush the reception* pipe.** RETURNS: N/A*/ LOCAL void clnttty_flush ( int pipeFd /* pipe file descriptor */ ) { char tmpBuf [MAX_MSG_SIZE]; int nBytes = 0; while ((ioctl (pipeFd, FIONREAD, &nBytes) >= 0) && nBytes) { read (pipeFd, tmpBuf, MAX_MSG_SIZE); } }#endif /* !WIN32 *//******************************************************************************** clnttty_open - open and initialize a pipe device.** This routine uses POSIX defined routines in order to:* open the the two pipes for read and write.** RETURNS: a file handle, or -1 on error.*/ LOCAL int clnttty_open ( char * devName, int baudRate, struct timeval wait ) { char h2tPipe[64] = {0}; char t2hPipe[64] = {0};#ifndef WIN32 { struct stat buf; sprintf (h2tPipe, "/tmp/vxsim_h2t_%d", (int) getuid()); sprintf (t2hPipe, "/tmp/vxsim_t2h_%d", (int) getuid()); /* create named pipes if necessary */ if (stat (h2tPipe, &buf) < 0) { unlink (h2tPipe); mkfifo (h2tPipe, 0600); } if (stat (t2hPipe, &buf) < 0) { unlink (t2hPipe); mkfifo (t2hPipe, 0600); } /* Attempt to open named pipes. */ h2t_fd = open (h2tPipe, O_RDWR, 0); t2h_fd = open (t2hPipe, O_RDWR, 0); if (t2h_fd != -1) { /* test if the pipe is already used by another target server */ if (lockf (t2h_fd, F_TLOCK, 0) != 0) { wpwrLogErr ("Pipe is already used by another target server\n"); return (ERROR); } /* flush reception pipe */ clnttty_flush (t2h_fd); } }#else /* * Attempt to open mailslots. */ if (((t2h_fd = (int)mailslotCreate (TGTSVR_MAIL_SLOT)) != -1) && ((h2t_fd = (int)mailslotConnect (VXSIM_MAIL_SLOT, wait.tv_sec)) == -1)) mailslotClose ((HANDLE)t2h_fd); else { wpwrSigHookAdd (mailslotClose, (HANDLE)t2h_fd); wpwrSigHookAdd (mailslotClose, (HANDLE)h2t_fd); } #endif /* WIN32 */ if((h2t_fd < 0) || (t2h_fd < 0)) return (-1); return (t2h_fd); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -