From:	CRDGW2::CRDGW2::MRGATE::"SMTP::AI.MIT.EDU::GNULISTS" 28-FEB-1991 08:19:40.01
To:	ARISIA::EVERHART
CC:	
Subj:	Re: RPC problems with gcc

From:	gnulists@ai.mit.edu@SMTP@CRDGW2
To:	Everhart@Arisia@MRGATE

Received:  by crdgw1.ge.com (5.57/GE 1.87)
	 id AA00622; Thu, 28 Feb 91 08:12:14 EST
Received: by life.ai.mit.edu (4.1/AI-4.10) id AA19909; Thu, 28 Feb 91 02:37:31 EST
Return-Path: <gnulists@ai.mit.edu>
Received: from wheat-chex (wheat-chex.ai.mit.edu) by life.ai.mit.edu (4.1/AI-4.10) id AA19873; Thu, 28 Feb 91 02:35:41 EST
Received: by wheat-chex (4.1/AI-4.10) id AA00697; Thu, 28 Feb 91 02:35:45 EST
Resent-Date: 27 Feb 91 01:41:58 GMT
Resent-From: gnulists@ai.mit.edu
Resent-Message-Id: <9102280735.AA00697@wheat-chex>
Received: from tut.cis.ohio-state.edu by life.ai.mit.edu (4.1/AI-4.10) id AA11469; Tue, 26 Feb 91 22:36:44 EST
Received: by tut.cis.ohio-state.edu (5.61-kk/5.910130)
	id AA11847; Tue, 26 Feb 91 22:36:12 -0500
Received: from USENET by tut.cis.ohio-state.edu with netnews
	for help-gcc@prep.ai.mit.edu (help-gcc@prep.ai.mit.edu)
	(contact usenet@tut.cis.ohio-state.edu if you have questions)
Date: 27 Feb 91 01:41:58 GMT
From: morrow!drapeau@morrow.stanford.edu  (George Drapeau)
Sender: gnulists@ai.mit.edu
Organization: Interactive Classroom Experiment, Stanford University
Subject: Re: RPC problems with gcc
Message-Id: <DRAPEAU.91Feb26174158@sioux.Stanford.EDU>
References: <patrick.667229393@beppe15>
To: help-gcc@prep.ai.mit.edu

In article <patrick.667229393@beppe15> patrick@beppe15.ericsson.se (Patrick Sendek) writes:


   I am having problems running gcc (version 1.39) compiled RPCGENed code under 
   SUN OS 4.1.1.

   I have coded in the Remote Console Print example that is listed in Sun's 
   Network Programming Manual - Chapter 3 (pgs 43-47).  If I compile these
   modules with Sun's cc compiler, they work perfectly, but if I compile these
   modules as listed below I have problems.

     example%  rpcgen msg.x
     example%  gcc rprintmsg.c msg_clnt.c -o rprintmsg
     example%  gcc msg_proc.c msg_svc.c -o msg_server

   I run the "rprintmsg" client, after running the server in the background, and
   I consistantly get a Bus Error (core dump) in clnttcp_create().  The stack
   seems to be getting corrupted, but I haven't been able to determine why. This 
   is only one of many example problems I am having running RPC code with the gcc 
   compile.  

   Is anyone else having similar results?  Does anyone know of a possible solution 
   for this problem?

I've run into the same problem (although with gcc 1.37).  I know which
piece of code in the RPC source causes the problem; I wish I knew
enough about the difference between gcc and Sun cc to know why this
problem comes about.  Maybe somebody here can illuminate us all.

The problem appears to be in the function "clnttcp_call"; the problem
is the last parameter,  a "struct timeval".  I modified the function
so that it takes a "struct timeval*"; this cleared things up.

So, the Sun cc-compiled code didn't behave well with the gcc-compiled
code when it came to passing structures as arguments to functions.
Why is this?

If I want to use gcc when linking with Sun-cc code, do I have to find
and change the Sun-cc code everytime something like this happens?
This is unacceptable; I was lucky that the RPC source is out there for
anybody to use (I got it from uunet.uu.net via anonymous ftp somewhere
in the comp.sources.unix area, one of the later volumes), but this
will not be the case for all software.

Here's the fix I used.  I hope it helps.

	George

-------------------------- cut here --------------------------
#include <stdio.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <rpc/pmap_clnt.h>

#define MCALL_MSG_SIZE 24

struct ct_data {
	int		ct_sock;
	bool_t		ct_closeit;
	struct timeval	ct_wait;
	bool_t          ct_waitset;       /* wait set by clnt_control? */
	struct sockaddr_in ct_addr; 
	struct rpc_err	ct_error;
	char		ct_mcall[MCALL_MSG_SIZE];	/* marshalled callmsg */
	u_int		ct_mpos;			/* pos after marshal */
	XDR		ct_xdrs;
};
  
  
static enum clnt_stat clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
     register CLIENT *h;
     u_long proc;
     xdrproc_t xdr_args;
     caddr_t args_ptr;
     xdrproc_t xdr_results;
     caddr_t results_ptr;
     struct timeval *timeout;					    /* Changed timeout to be a pointer to the timeval ... */
{								    /* structure instead of the whole struct. */
								    /* George D. Drapeau, 10/15/90 */
  register struct ct_data *ct = (struct ct_data *) h->cl_private;
  register XDR *xdrs = &(ct->ct_xdrs);
  struct rpc_msg reply_msg;
  u_long x_id;
  u_long *msg_x_id = (u_long *)(ct->ct_mcall);			    /* yuk */
  register bool_t shipnow;
  int refreshes = 2;
  
  if (!ct->ct_waitset)
    {
    ct->ct_wait.tv_sec = timeout->tv_sec;
    ct->ct_wait.tv_usec = timeout->tv_usec;
    }
  shipnow = (xdr_results == (xdrproc_t)0
	     && timeout->tv_sec == 0
	     && timeout->tv_usec == 0) ? FALSE : TRUE;
  
  call_again:
  xdrs->x_op = XDR_ENCODE;
  ct->ct_error.re_status = RPC_SUCCESS;
  x_id = ntohl(--(*msg_x_id));
  if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
      (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
      (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
      (! (*xdr_args)(xdrs, args_ptr)))
    {
    if (ct->ct_error.re_status == RPC_SUCCESS)
      ct->ct_error.re_status = RPC_CANTENCODEARGS;
    (void)xdrrec_endofrecord(xdrs, TRUE);
    return (ct->ct_error.re_status);
    }
  if (! xdrrec_endofrecord(xdrs, shipnow))
    return (ct->ct_error.re_status = RPC_CANTSEND);
  if (! shipnow)
    return (RPC_SUCCESS);

  if (timeout->tv_sec == 0 && timeout->tv_usec == 0)		    /* Hack to provide rpc-based message passing */
    {
    return(ct->ct_error.re_status = RPC_TIMEDOUT);
    }
  xdrs->x_op = XDR_DECODE;					    /* Keep receiving until we get a valid transaction id */
  while (TRUE)
    {
    reply_msg.acpted_rply.ar_verf = _null_auth;
    reply_msg.acpted_rply.ar_results.where = NULL;
    reply_msg.acpted_rply.ar_results.proc = xdr_void;
    if (! xdrrec_skiprecord(xdrs))
      return (ct->ct_error.re_status);
								    /* now decode and validate the response header */
    if (! xdr_replymsg(xdrs, &reply_msg))
      {
      if (ct->ct_error.re_status == RPC_SUCCESS)
	continue;
      return (ct->ct_error.re_status);
      }
    if (reply_msg.rm_xid == x_id)
      break;
    }
  _seterr_reply(&reply_msg, &(ct->ct_error));			    /* process header */
  if (ct->ct_error.re_status == RPC_SUCCESS)
    {
    if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf))
      {
      ct->ct_error.re_status = RPC_AUTHERROR;
      ct->ct_error.re_why = AUTH_INVALIDRESP;
      }
    else
      if (! (*xdr_results)(xdrs, results_ptr))
	{
	if (ct->ct_error.re_status == RPC_SUCCESS)
	  ct->ct_error.re_status = RPC_CANTDECODERES;
	}
    if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)		    /* free verifier ... */
      {
      xdrs->x_op = XDR_FREE;
      (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
      }
    }								    /* end successful completion */
  else
    {
    if (refreshes-- && AUTH_REFRESH(h->cl_auth))		    /* maybe our credentials need to be refreshed ... */
      goto call_again;
    }								    /* end of unsuccessful completion */
  return (ct->ct_error.re_status);
  }								    /* end function clnttcp_call */
-------------------------- cut here --------------------------
--
______________________________________________________________________________
George D. Drapeau			Internet: drapeau@jessica.stanford.edu
Academic Information Resources
Stanford University

