memmove( v_bufptr, d, len);
memmove( v_bufptr, data, len);
v_write(int f, char *d, int len){	int riten;	int c = len;	if (v_bufstr == NULL  &&  len > 0) {	        v_buffer = XtMalloc(len);		v_bufstr = v_buffer;		v_bufptr = v_buffer;		v_bufend = v_buffer + len;	}#ifdef DEBUG	if (debug) {	    fprintf(stderr, "v_write called with %d bytes (%d left over)",		    len, v_bufptr - v_bufstr);	    if (len > 1  &&  len < 10) fprintf(stderr, " \"%.*s\"", len, d);	    fprintf(stderr, "\n");	}#endif#ifndef AMOEBA	if (!FD_ISSET (f, &pty_mask))		return(write(f, d, len));#else	if (term->screen.respond != f)		return(write(f, d, len));#endif	/*	 * Append to the block we already have.	 * Always doing this simplifies the code, and	 * isn't too bad, either.  If this is a short	 * block, it isn't too expensive, and if this is	 * a long block, we won't be able to write it all	 * anyway.	 */	if (len > 0) {	    if (v_bufend < v_bufptr + len) { /* we've run out of room */		if (v_bufstr != v_buffer) {		    /* there is unused space, move everything down */		    /* possibly overlapping memmove here */#ifdef DEBUG		    if (debug)			fprintf(stderr, "moving data down %d\n",				v_bufstr - v_buffer);#endif		    memmove( v_buffer, v_bufstr, v_bufptr - v_bufstr);		    v_bufptr -= v_bufstr - v_buffer;		    v_bufstr = v_buffer;		}		if (v_bufend < v_bufptr + len) {		    /* still won't fit: get more space */		    /* Don't use XtRealloc because an error is not fatal. */		    int size = v_bufptr - v_buffer; /* save across realloc */		    v_buffer = (char *)realloc(v_buffer, size + len);		    if (v_buffer) {#ifdef DEBUG			if (debug)			    fprintf(stderr, "expanded buffer to %d\n",				    size + len);#endif			v_bufstr = v_buffer;			v_bufptr = v_buffer + size;			v_bufend = v_bufptr + len;		    } else {			/* no memory: ignore entire write request */			fprintf(stderr, "%s: cannot allocate buffer space\n",				xterm_name);			v_buffer = v_bufstr; /* restore clobbered pointer */			c = 0;		    }		}	    }	    if (v_bufend >= v_bufptr + len) {		/* new stuff will fit */		memmove( v_bufptr, d, len);		v_bufptr += len;	    }	}	/*	 * Write out as much of the buffer as we can.	 * Be careful not to overflow the pty's input silo.	 * We are conservative here and only write	 * a small amount at a time.	 *	 * If we can't push all the data into the pty yet, we expect write	 * to return a non-negative number less than the length requested	 * (if some data written) or -1 and set errno to EAGAIN,	 * EWOULDBLOCK, or EINTR (if no data written).	 *	 * (Not all systems do this, sigh, so the code is actually	 * a little more forgiving.)	 */#define MAX_PTY_WRITE 128	/* 1/2 POSIX minimum MAX_INPUT */	if (v_bufptr > v_bufstr) {#ifndef AMOEBA	    riten = write(f, v_bufstr, v_bufptr - v_bufstr <= MAX_PTY_WRITE ?			  	       v_bufptr - v_bufstr : MAX_PTY_WRITE);	    if (riten < 0)#else	    riten = v_bufptr - v_bufstr <= MAX_PTY_WRITE ?		    v_bufptr - v_bufstr : MAX_PTY_WRITE;	    if (cb_puts(term->screen.tty_inq, v_bufstr, riten) != 0)#endif /* AMOEBA */	    {#ifdef DEBUG		if (debug) perror("write");#endif		riten = 0;	    }#ifdef DEBUG	    if (debug)		fprintf(stderr, "write called with %d, wrote %d\n",			v_bufptr - v_bufstr <= MAX_PTY_WRITE ?			v_bufptr - v_bufstr : MAX_PTY_WRITE,			riten);#endif	    v_bufstr += riten;	    if (v_bufstr >= v_bufptr) /* we wrote it all */		v_bufstr = v_bufptr = v_buffer;	}	/*	 * If we have lots of unused memory allocated, return it	 */	if (v_bufend - v_bufptr > 1024) { /* arbitrary hysteresis */	    /* save pointers across realloc */	    int start = v_bufstr - v_buffer;	    int size = v_bufptr - v_buffer;	    int allocsize = size ? size : 1;	    v_buffer = (char *)realloc(v_buffer, allocsize);	    if (v_buffer) {		v_bufstr = v_buffer + start;		v_bufptr = v_buffer + size;		v_bufend = v_buffer + allocsize;#ifdef DEBUG		if (debug)		    fprintf(stderr, "shrunk buffer to %d\n", allocsize);#endif	    } else {		/* should we print a warning if couldn't return memory? */		v_buffer = v_bufstr - start; /* restore clobbered pointer */	    }	}	return(c);}