[net.unix-wizards] Major do-do in ungetc

terryl@tekcrl.UUCP (08/11/85)

     I'm working on a software project that uses shared memory to pass
messages around to co-operating processes. The messages are composed with
sprintf(), and are de-composed with sscanf. Once the messages are composed
and sent to the co-operating processes, the messages are made READ-ONLY.
Now this has shown up when trying to de-compose the message with sscanf.
sscanf creates a funny FILE pointer with the base address as the address
string as the base of the buffer, and the length of the string as the length.
sscanf also set a flag that this funny FILE pointer has an _IOSTRG attribute.
Well, sscanf then calls _doscan to do the actual work, and _doscan, when
parsing the string according to the format field (the % whatevers) keeps
doing getc's until it finds the end of current field according to the current
the format field, and when it finds the end, it has scanned one character pass
the end of the current field and so does an ungetc because it has read one
too many characters of the input stream(the string). ungetc actually puts
the character back into the input stream according to the current FILE pointer,
and this is where the problem is. Below is the fragment of ungetc that causes
the problem:

	if ((iop->_flag&_IOREAD) == 0 || iop->_ptr <= iop->_base)
		if (iop->_ptr == iop->_base && iop->_cnt == 0)
			*iop->_ptr++;
		else
			return (EOF);
	iop->_cnt++;
	*--iop->_ptr = c;	/* This is the problem */
	return (c);
}


     Now my question is this: since only sscanf is the one who uses the _IOSTRG
construct, is it safe to make the assignment marked /* This is the problem */
into just a decrement of the pointer into a string????

mike@BRL.ARPA (Mike Muuss) (08/18/85)

The problem you will find is that ungetc() can (and IS) used to
"push back" characters other than the one that was just read.

Rather than changing ungetc() and watching thing break later, you might
devise new innards to sscanf(), or a special ROsscanf(), or something.
	-Mike Muuss