BBN-V6/tcp/putc.c

Compare this file to the similar file:
Show the results in this format:

#
/*
 * Buffered character and word output.
 * as similar as possible to the standard Unix version,
 * but is much more careful about errors and probably
 * a bit slower.
 *
 * Imports: creat (II), write (II), errno
 * Exports: FCreat(), PutC(), PutW(), FFlush(), FPutBlock()
 * Author: Jon Dreyer, October, 1978
 * Fixed up 12/13/78 so it doesn't output an extra byte each
 *	time buffer is flushed automatically.
 */
struct iobuf {
	int fildes;	/* file desc. of output file */
	int nunused;	/* # free bytes in buff */
	char *xfree;	/* ptr to next free slot */
	char buff[512];	/* dis is it */
};

#define MODE 0664	/* mode of created file */

extern int errno;

/*
 * FCreat -- creates file (mode MODE) and readies it for
 * buffered output via PutC and PutW
 */
FCreat(FileName, Buf) char *FileName; struct iobuf *Buf;{
	register struct iobuf *B;	/* just a quick Buf */
	B = Buf;
	if ((B->fildes = creat(FileName, MODE)) < 0)
		return (-1);
	else {
		B->nunused = 512;
		B->xfree = B->buff;
		return (0);
	}
}

/*
 * PutC -- Put one char (buffered)
 * Returns the char if ok, else returns -1.
 * Note that a -1 test won't work if there's a chance you'll
 * be putting a -1.
 */
PutC(Ch, Buf) char Ch; struct iobuf *Buf; {
	*(Buf->xfree)++ = Ch;
	if (--(Buf->nunused) == 0)
		if (FFlush(Buf) < 0)
			return (-1);
	return (Ch);
}

/*
 * PutW -- Like PutC, but for words
 */
PutW(Wd, Buf) int Wd; struct iobuf *Buf; {
	struct {char LowByte, HighByte;};
	/* Quick and vutt! */
	PutC((&Wd)->LowByte, Buf);
	PutC((&Wd)->HighByte, Buf);
	return (errno ? -1 : Wd);
}


/*
 * FFlush -- flush buffer
 * Used by PutC and PutW and also by the user.
 * Returns -1 if there's a problem.
 */
FFlush(Buf) struct iobuf *Buf; {
	register struct iobuf *B;	/* for short */
	register int NBytes;
	B = Buf;
	NBytes = 512 - B->nunused;
	if (write(B->fildes, B->buff, NBytes) < NBytes)
		return (-1);
	B->nunused = 512;
	B->xfree = B->buff;
	return (0);
}

/*
 * FEven -- ensure word boundary
 */
FEven(Buf) struct iobuf *Buf; {
	if (Buf->xfree % 2)
		PutC(0, Buf);
}

/*
 * FPutBlock -- output a block of data
 */
FPutBlock(Block, NBytes, Buf) char *Block; struct iobuf *Buf; {
	while (NBytes--)
		PutC(*Block++, Buf);
	return (errno ? -1 : 0);
}