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

📄 clnt_tty.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
/* clnt_tty.c - implements a serial line based, client side RPC *//* Copyright 1984-1994 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * Copyright (c) 1987 Wind River Systems, Inc. * Copyright (C) 1984, Sun Microsystems, Inc. * * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part.  Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California  94043 *//*modification history--------------------01k,25jan99,elg  Add Flow Control on Serial Backend (SPR 22159)01j,01jul98,c_s  WindView 2 -> Tornado 2 Merge01i,12may98,nps  cumulative patch merge01h,26aug97,pcn  Fixed SPR #8979.01k,03mar98,c_c  Removed strings.h for WIN32.01j,02mar98,pcn  Removed warnings.01i,21jan98,c_c  DLLized Target Server implementation.                 Got rid of EXT_FUNC refs.01h,26aug97,pcn  Fixed SPR #8979.01g,21nov96,wmd  fixed spr #7427 - wdbserial for AIX host.01f,19apr96,jco  in routine clnttty_call, used __seterr_reply on Solaris 2.x 		 hosts instead of _seterr_reply (spr 4780 and further 4751).01e,16jan96,elp  adapted calls of dll external functions (changed wpwrLogErr in		 wpwrLogErr ...)01d,27jun95,tpr  changed 38800 to 38400 in baudTable[].01c,09jun95,p_m  changed __WIN32__ to WIN32.01b,01jun95,tpr  cleaned up.01a,21apr95,ms	 hacked up version of clnt_udp.c for serial devices.*/#ifndef lint/* static char sccsid[] = "@(#)clnt_tty.c 1.1 86/02/03 Copyr 1984 Sun Micro"; */#endif/* * clnt_tty.c, Implements a UPD/IP based, client side RPC. * */#ifdef WIN32#define WIN32_LEAN_AND_MEAN 1#include <windows.h>#include <winbase.h>#include <winnt.h>#include <time.h>#include <process.h>#include "ttydev.h"#include "win32Serial.h"#else#ifdef RS6000_AIX4#include <sys/termio.h>#endif#ifdef	PARISC_HPUX10#include <sys/termiox.h>#include <sys/modem.h>#endif	/* PARISC_HPUX10 */#include <sys/tiuser.h>#include <strings.h>#endif	/* WIN32 */#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <termios.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <rpc/rpc.h>#include <rpc/types.h>#include <rpc/xdr.h>#include <rpc/auth.h>#include <rpc/clnt.h>#include <rpc/rpc_msg.h>#include <rpc/pmap_clnt.h>#include "wdbP.h"#include "wpwrutil.h"/* externals */IMPORT bool_t xdr_opaque_auth (XDR *, struct opaque_auth *);IMPORT bool_t xdr_callhdr (XDR *, struct rpc_msg *);IMPORT bool_t xdr_replymsg (XDR *, struct rpc_msg *);#ifndef	SUN4_SOLARIS2IMPORT void _seterr_reply (struct rpc_msg *, struct rpc_err *);#endif	/* SUN4_SOLARIS2 *//* * TTY bases client side rpc operations */static enum clnt_stat   clnttty_call    (    CLIENT *	cl,		/* client handle */    u_long	proc,		/* procedure number */    xdrproc_t	xargs,		/* xdr routine for args */    caddr_t	argsp,		/* pointer to args */    xdrproc_t	xresults,	/* xdr routine for results */    caddr_t	resultsp,	/* pointer to results */    struct timeval utimeout	/* seconds to wait before giving up - 4.0 */    );static void clnttty_abort     (    CLIENT *h    );static void clnttty_geterr    (    CLIENT *cl,    struct rpc_err *errp    );static bool_t clnttty_control     (    CLIENT *cl,    int request,    char *info    );static void clnttty_destroy    (    CLIENT *cl    );static bool_t   clnttty_freeres     (    CLIENT *cl,    xdrproc_t xdr_res,    caddr_t res_ptr    );#ifdef WIN32HANDLE serialFd = 0;static struct opaque_auth _null_auth;/* static struct rpc_createerr rpc_createerr; */#define mem_alloc(bsize) malloc(bsize)#define mem_free(ptr, bsize) free(ptr)#endif	/* WIN32 *//* * Other forward static function declarations */static int      clnttty_send    (    int     fd,    char *  inBuf,    int     nBytes    );static int      clnttty_rcv      (    int     fd,    char *  buf,    int     nBytes    );static int      clnttty_open     (    char *      	devName,    int         	baudRate,    BOOL		hardFlowControl,    struct timeval  	wait    );/* locals */static struct clnt_ops tty_ops =    {    clnttty_call,    clnttty_abort,    clnttty_geterr,    clnttty_freeres,    clnttty_destroy,    clnttty_control    };/* * Private data kept per client handle */struct cu_data     {    int        cu_fd;    int        seqNum;    struct timeval     cu_wait;    struct timeval     cu_total;    struct rpc_err     cu_error;    XDR        cu_outxdrs;    u_int          cu_xdrpos;    u_int          cu_sendsz;    char           *cu_outbuf;    u_int          cu_recvsz;    char           cu_inbuf[1];    };/* * default size fo send/rcv buffers */#define TTYMSGSIZE	1500/* * Create a TTY based client handle. * * wait is the amount of time used between retransmitting a call if * no response has been heard;  retransmition occurs until the actual * rpc call times out. * * sendsz and recvsz are the maximum allowable packet sizes that can be * sent and received. */CLIENT * clnttty_bufcreate    (    u_long 		program,    u_long 		version,    struct timeval 	wait,    char *		devName,    int 		baudRate,    BOOL		hardFlowControl,    u_int 		sendsz,    u_int 		recvsz    )    {    CLIENT *cl;    register struct cu_data *	cu = NULL;    struct timeval now;    struct rpc_msg call_msg;    cl = (CLIENT *)mem_alloc(sizeof(CLIENT));    if(cl == NULL)	{	wpwrLogErr ("clnttty_create: out of memory\n");	rpc_createerr.cf_stat = RPC_SYSTEMERROR;	rpc_createerr.cf_error.re_errno = errno;	goto fooy;	}    sendsz = ((sendsz + 3) / 4) * 4;    recvsz = ((recvsz + 3) / 4) * 4;    cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);    if(cu == NULL)	{	wpwrLogErr ("clnttty_create: out of memory\n");	rpc_createerr.cf_stat = RPC_SYSTEMERROR;	rpc_createerr.cf_error.re_errno = errno;	goto fooy;	}    cu->cu_outbuf = &cu->cu_inbuf[recvsz];#ifndef WIN32    (void)gettimeofday(&now, (struct timezone *)0);#else    {	time_t time_val;	(void)time(&time_val);	now.tv_sec = time_val;	now.tv_usec = 0;    }#endif    cl->cl_ops = &tty_ops;    cl->cl_private = (caddr_t)cu;    cu->seqNum = (getpid() << 16);    cu->cu_wait = wait;    cu->cu_total.tv_sec = -1;    cu->cu_total.tv_usec = -1;    cu->cu_sendsz = sendsz;    cu->cu_recvsz = recvsz;    call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;    call_msg.rm_direction = CALL;    call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;    call_msg.rm_call.cb_prog = program;    call_msg.rm_call.cb_vers = version;    xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,		  sendsz, XDR_ENCODE);    if(! xdr_callhdr(&(cu->cu_outxdrs), &call_msg))	{	goto fooy;	}    cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));    /* open the serial device */    cu->cu_fd = clnttty_open (devName, baudRate, hardFlowControl, wait);    if(cu->cu_fd < 0)	{	wpwrLogErr ("clnttty_bufcreate can't open %s\n", devName);	rpc_createerr.cf_stat = RPC_SYSTEMERROR;	rpc_createerr.cf_error.re_errno = errno;	goto fooy;	}    cl->cl_auth = authnone_create();    return (cl);    fooy:    if(cu)	mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);    if(cl)	mem_free((caddr_t)cl, sizeof(CLIENT));    return ((CLIENT *)NULL);    }CLIENT * clnttty_create    (    char *		devName,    int 		baudRate,    BOOL 		hardFlowControl,    u_long 		program,    u_long 		version,    struct timeval 	wait    )    {    return (clnttty_bufcreate (program, version, wait, devName, baudRate,			       hardFlowControl, TTYMSGSIZE, TTYMSGSIZE));    }static enum clnt_stat clnttty_call	(	register CLIENT *cl,	/* client handle */	u_long      proc,	/* procedure number */	xdrproc_t   xargs,	/* xdr routine for args */	caddr_t     argsp,	/* pointer to args */	xdrproc_t   xresults,	/* xdr routine for results */	caddr_t     resultsp,	/* pointer to results */	struct timeval  utimeout/* seconds to wait before giving up - 4.0 */	)    {    register struct cu_data *cu = (struct cu_data *)cl->cl_private;    register XDR *xdrs;    register int outlen;    register int inlen;#ifndef WIN32    fd_set readFds;    fd_set mask;#endif    struct rpc_msg reply_msg;    XDR reply_xdrs;    struct timeval time_waited;    bool_t ok;    int nrefreshes = 2;    struct timeval timeout;    if(cu->cu_total.tv_usec == -1)	{	timeout = utimeout;	}    else	{	timeout = cu->cu_total;	}    time_waited.tv_sec = 0;    time_waited.tv_usec = 0;    call_again:    xdrs = &(cu->cu_outxdrs);    xdrs->x_op = XDR_ENCODE;    XDR_SETPOS(xdrs, cu->cu_xdrpos);    /*     * the transaction is the first thing in the out buffer     */    (*(u_short *)(cu->cu_outbuf))++;    if((! XDR_PUTLONG(xdrs, (long *)&proc)) ||       (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||       (! (*xargs)(xdrs, argsp)))	{	return (cu->cu_error.re_status = RPC_CANTENCODEARGS);	}    outlen = (int)XDR_GETPOS(xdrs);    send_again:    if(clnttty_send (cu->cu_fd, cu->cu_outbuf, outlen) == 0)	{	cu->cu_error.re_errno = errno;	return (cu->cu_error.re_status = RPC_CANTSEND);	}    /*     * Hack to provide rpc-based message passing     */    if(timeout.tv_sec == 0 && timeout.tv_usec == 0)	{	return (cu->cu_error.re_status = RPC_TIMEDOUT);	}    /*     * 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(win32SerialSelect ((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);    /* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */    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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -