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

📄 clntpipe.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
     * 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 + -