Пример #1
0
/*
 * _sds_fr_mem moves data into SDS from user memory.
 *
 * Returns 0 on normal return, or else -1 with error code in errno.
 */
_sds_fr_mem(
bitptr  sdsaddr,	/* SDS bit address where data will be received */
bitptr  ubuf,		/* user buffer containing data */
int     nbits		/* number of bits to move */
)
{
	long sds_bit_offset;
	char *ucaddr;
	long *uwaddr;
	int  ret;
	
	if (nbits & (BITPBLOCK - 1)) {
		errno = FDC_ERR_GRAN;	/* must be block multiple */
		return -1;
	}

	ucaddr	 = BPTR2CP(ubuf);
	uwaddr	 = BPTR2WP(ubuf);
	if (ucaddr != (char*)uwaddr) {
		errno = FDC_ERR_SDSWB;	/* must be word-aligned */
		return -1;
	}

	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	if (sds_bit_offset & (BITPBLOCK - 1)) {
		errno = FDC_ERR_GRAN;	/* must be block multiple */
		return -1;
	}

	ret = sswrite(uwaddr, BITS2BLOCKS(sds_bit_offset), BITS2BLOCKS(nbits));
	if (ret == -1)
		errno = FDC_ERR_SDSIO;
	return ret;
}
Пример #2
0
long
_fwch(
	unit	*cup,
	long	*uda,
	long	chars,
	int	mode)
{
	register int	bytsiz;
	register long	nchr;
	unsigned char	tbuf[TBUFSZB];	/* Line packing buffer */
	FILE		*fptr;

/*
 *	If positioned after an endfile, and the file does not
 *	support multiple endfiles, a write is invalid.
 */
	if (cup->uend && !cup->umultfil && !cup->uspcproc) {
		errno	= FEWRAFEN;
		return(IOERR);
	}

	nchr	= 0;

	switch (cup->ufs) {

	case FS_TEXT:
	case STD:
		fptr	= cup->ufp.std;

		/* switch the FILE structure into write mode */

#if	!defined(_LITTLE_ENDIAN) || (defined(_LITTLE_ENDIAN) && defined(__sv2))
		if ((FILE_FLAG(fptr) & (_IOWRT | _IORW)) == _IORW) {
			if (FILE_FLAG(fptr) & _IOREAD)
				(void) fseek(fptr, 0, SEEK_CUR);

			FILE_FLAG(fptr) |= _IOWRT;
		}
#endif

#if	defined(_SOLARIS) || (defined(_LITTLE_ENDIAN) && !defined(__sv2))
		while (nchr < chars) {
			register long	count;
			register int	ret;
			/* Pack chars into temp buffer and write them */
			count	= chars - nchr;
			if (count > TBUFSZB)
				count	= TBUFSZB;
#ifdef KEY /* Bug 5926 */
			count = _pack(&uda[nchr], (char *)tbuf, count,
			  terminator(&mode, nchr, count, chars));
#else /* KEY Bug 5926 */
			_pack(&uda[nchr], (char *)tbuf, count, -1);
#endif /* KEY Bug 5926 */
			ret	= fwrite(tbuf, 1, count, fptr);
			if ( ret != count || ferror(fptr) ) {
				if ( ret != count || errno == 0)
					errno	= FESTIOER;
				return(IOERR);
			}
			nchr	+= count;
		}
#else

		/* If the stream is unbuffered... */

		if (FILE_FLAG(fptr) & (_IONBF | _IOLBF)) {
			while (nchr < chars) {
				register long	count;
				register long	ret;

				/* Pack chars into temp buffer and write them */

				count	= chars - nchr;

				if (count > TBUFSZB)
					count	= TBUFSZB;

#ifdef KEY /* Bug 5926 */
			count= _pack(&uda[nchr], (char *)tbuf, count,
			  terminator(&mode, nchr, count, chars));
#else /* KEY Bug 5926 */
				_pack(&uda[nchr], (char *)tbuf, count, -1);

#endif /* KEY Bug 5926 */
				ret	= fwrite(tbuf, 1, count, fptr);

				if ( ret != count || ferror(fptr) ) {
					if ( ret != count || errno == 0)
						errno	= FESTIOER;
					return(IOERR);
				}

				nchr	+= count;
			}
		}
		else {	/* for a buffered stream... */

			while (FILE_CNT(fptr) < chars - nchr) {
				register long	count;
				register int	ret;

				count	= FILE_CNT(fptr); /* space left in buffer */
				if (count > 0) {
					/* pack data into the buffer */
					_pack(&uda[nchr], (char *)FILE_PTR(fptr),
						count, -1);
					FILE_PTR(fptr)	+= count;
					FILE_CNT(fptr)	= 0;
				}

				/*
				 * We set errno to 0 here in case the following
				 * buffer flush fails.  UNICOS 8.2 fputc (and
				 * previous) was not X/Open compliant and did
				 * not always set errno when a buffer flush
				 * completed partially due to a disk full
				 * conditon.  The zeroing of errno may be
				 * removed when we can assume that the fputc()
				 * from UNICOS and Solaris are X/Open compliant.
				 */

				errno	= 0;

				/*
				 * This fputc() will either trigger a buffer
				 * flush or cause the buffer to be allocated
				 * for the first time.
				 */

				ret	= fputc(uda[nchr + count], fptr);

				if (ret == EOF && ferror(fptr)) {
					if (errno == 0)
						errno	= FESTIOER;
					return(IOERR);
				}

				nchr	+= count + 1;
			}

			if (nchr < chars) {	/* Put data in buffer */
				_pack(&uda[nchr], (char *)FILE_PTR(fptr),
					chars - nchr, -1);

				FILE_CNT(fptr)	-= chars - nchr;
				FILE_PTR(fptr)	+= chars - nchr;
			}
		}
#endif

		if (mode == FULL) {
			register int	ret;

 			ret	= putc('\n', fptr);;

			if (ret == EOF && ferror(fptr)) {
				if (errno == 0)
					errno	= FESTIOER;
				return(IOERR);
			}
			chars++;
		}

		return(chars);

	case FS_FDC:

		/*
		 * If a logical endfile record had just been read,
		 * replace it with a physical endfile record before
		 * starting the current data record.
		 */
		if ((cup->uend == LOGICAL_ENDFILE) && !(cup->uspcproc)) {
			if (XRCALL(cup->ufp.fdc, weofrtn)cup->ufp.fdc,
				&cup->uffsw) < 0){
				errno	= cup->uffsw.sw_error;
				return(IOERR);
			}
		}

		cup->uend	= BEFORE_ENDFILE;

		if (cup->ucharset == 0) {
			register long	ret;

			ret	= XRCALL(cup->ufp.fdc, writecrtn) cup->ufp.fdc,
					WPTR2BP(uda),
					chars, &cup->uffsw, mode);

			if (ret < 0) {
				errno	= cup->uffsw.sw_error;
				return(IOERR);
			}

			return(chars);
		}

/*
 *		Get proper byte size (might not be 8-bits if doing conversion).
 */

#if	NUMERIC_DATA_CONVERSION_ENABLED
		bytsiz	= __fndc_charsz[cup->ucharset];
#else
		bytsiz	= 8;
#endif

		do {
			register long	breq;
			register int	fulp;
			register long	ncnt;
			register long	ret;
			int		ubc;

			ncnt	= TBUFSZB;
			breq	= 0;
			ubc	= 0;

			if ((chars - nchr) > 0) {
				register long	totbits;

				if (ncnt > (chars - nchr))
					ncnt	= chars - nchr;

				if (_fdc_packc((char *)tbuf, &uda[nchr], ncnt,
					cup->ucharset) < 0) {
					return(IOERR);
				}


				totbits	= bytsiz * ncnt;	/* bit count */
				breq	= (totbits + 7) >> 3; /* 8-bit bytes */
				ubc	= (breq << 3) - totbits;
			}

			nchr	+= ncnt;

			if ((nchr >= chars) && ( mode == FULL ))
				fulp	= FULL;
			else
				fulp	= PARTIAL;

			ret	= XRCALL(cup->ufp.fdc, writertn) cup->ufp.fdc,
					CPTR2BP(tbuf),
					breq, &cup->uffsw, fulp, &ubc);

			if (ret != breq) { 	/* if an error */
				errno	= cup->uffsw.sw_error;
				return(IOERR);
			}

		} while (nchr < chars);

		return(chars);
/*
 *	unsupported structure if not TEXT/STD, or FDC
 */
	default:
		errno	= FEINTFST;
		return(IOERR);
	}
}
Пример #3
0
/*
 * _any_mem_fr_sds moves data into user memory from a secondary data segment (SDS).
 *
 * unlike _mem_fr_sds, _any_mem_fr_sds handles moving a number of bits that
 * may not be a multiple of 512.
 *
 * Returns 0 on normal return, or else -1 with error code in errno.
 */
_any_mem_fr_sds(
bitptr  ubuf,		/* user buffer to receive data */
bitptr  sdsaddr,	/* SDS bit address of data */
int     nbits		/* number of bits to move */
)
{

	int sds_bit_offset;	
	int sds_bit_offset_blk;	
	int rbits;
	char localbuf[BYTPBLOCK];
	bitptr locptr;
	long *uwaddr;
	char *ucaddr;

	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	if (sds_bit_offset & (BITPBLOCK -1)) {
		/* The sds address is not on a block boundary. */
		/* Read data from sds to a local buffer. Copy the */
		/* appropriate part of the local buffer to user's memory. */
		sds_bit_offset_blk = (sds_bit_offset & ~(BITPBLOCK - 1));
		if(ssread((int *)localbuf, BITS2BLOCKS(sds_bit_offset_blk), 1) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
		rbits = MIN(nbits, BITPBLOCK - (sds_bit_offset -
			sds_bit_offset_blk));
		locptr = CPTR2BP(localbuf);
		SET_BPTR(locptr, INC_BPTR(locptr, sds_bit_offset - sds_bit_offset_blk));
		MOV_BITS(ubuf, locptr, rbits);
		SET_BPTR(ubuf, INC_BPTR(ubuf, rbits));
		nbits -= rbits;
		SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, rbits));
		if (nbits == 0)
			return(0);
		
		/* Verify that our sds address is now on a block boundary */
		assert (((SUBT_BPTR(sdsaddr, WPTR2BP(0))) & (BITPBLOCK -1)) == 0);
	}
	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	uwaddr	 = BPTR2WP(ubuf);
	ucaddr	 = BPTR2CP(ubuf);
	if ((nbits & (BITPBLOCK-1)) || (ucaddr != (char *)uwaddr)){
		int  left;

		/* Either we are not reading in a multiple of blocks or */
		/* the user's address is not word-aligned. */
		/* Round nbits down to a block boundary and */
		/* move those to user's memory. */

		locptr = CPTR2BP(localbuf);	
		rbits = nbits & ~(BITPBLOCK-1);
		if (rbits) {
			if (ucaddr != (char*)uwaddr) {
				/* ubuf is not word aligned. */
				/* Read the data from sds into a local */
				/* buffer and copy to the user's memory */
				left = rbits;
				sds_bit_offset_blk = BITS2BLOCKS(sds_bit_offset);
				while (left > 0) {
				   if (ssread((int *)localbuf,
				       sds_bit_offset_blk, 1) == -1) {
					errno = FDC_ERR_SDSIO;
					return(-1);
				   }
				   MOV_BITS(ubuf, locptr, BITPBLOCK);	
				   SET_BPTR(ubuf, INC_BPTR(ubuf, BITPBLOCK));
				   SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, BITPBLOCK));
				   sds_bit_offset_blk++;
				   left-= BITPBLOCK;
				}
			}
			else {
				if (ssread(uwaddr, BITS2BLOCKS(sds_bit_offset),
				   BITS2BLOCKS(rbits)) == -1) {
					errno = FDC_ERR_SDSIO;
					return(-1);
				}
				SET_BPTR(ubuf, INC_BPTR(ubuf, rbits));
				SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, rbits));
			}
			sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
		}
		/* get last block into local memory and */
		/* transfer to 	user's memory */
		if (ssread((int *)localbuf, BITS2BLOCKS(sds_bit_offset), 1) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
		assert((nbits - rbits) < BITPBLOCK);
		MOV_BITS(ubuf, locptr, nbits - rbits);	
	}
	else {
		if(ssread(uwaddr, BITS2BLOCKS(sds_bit_offset), BITS2BLOCKS(nbits)) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
	}
	return(0);
}
Пример #4
0
/*
 * _any_sds_fr_mem moves data into a secondary data segment (SDS) from
 *	user memory
 *
 * unlike _sds_fr_mem, _any_sds_fr_mem handles moving a number of bits that
 * may not be a multiple of 512.
 *
 * Returns 0 on normal return, or else -1 with error code in errno.
 */
_any_sds_fr_mem(
bitptr  sdsaddr,	/* SDS bit address of data */
bitptr  ubuf,		/* user buffer to receive data */
int     nbits		/* number of bits to move */
)
{

	int sds_bit_offset;	
	int sds_bit_offset_blk;	
	int rbits;
	char localbuf[BYTPBLOCK];
	bitptr locptr;
	long *uwaddr;
	char *ucaddr;

	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	if (sds_bit_offset & (BITPBLOCK -1)) {
		/* The sds address is not on a block boundary. */
		/* Read data from sds to a local buffer. Copy the */
		/* user's memory to the appropriate part of the local */
		/* buffer, and write it back out to sds. */
		sds_bit_offset_blk = (sds_bit_offset & ~(BITPBLOCK - 1));
		if (ssread((int *)localbuf, BITS2BLOCKS(sds_bit_offset_blk), 1) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
		rbits = MIN(nbits, BITPBLOCK - (sds_bit_offset -
			sds_bit_offset_blk));
		locptr = CPTR2BP(localbuf);
		SET_BPTR(locptr, INC_BPTR(locptr, sds_bit_offset - sds_bit_offset_blk));
		MOV_BITS(locptr, ubuf, rbits);
		SET_BPTR(ubuf, INC_BPTR(ubuf, rbits));
		nbits -= rbits;
		if(sswrite((int *)localbuf, BITS2BLOCKS(sds_bit_offset_blk), 1) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
		SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, rbits));
		if (nbits == 0)
			return(0);
		
		assert(((SUBT_BPTR(sdsaddr, WPTR2BP(0))) & (BITPBLOCK -1)) == 0);
	}
	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	uwaddr	 = BPTR2WP(ubuf);
	ucaddr	 = BPTR2CP(ubuf);
	if ((nbits & (BITPBLOCK-1)) || (ucaddr != (char *)uwaddr)){
		int left;

		locptr = CPTR2BP(localbuf);	

		/* round down nbits to a block boundary */
		rbits = nbits & ~(BITPBLOCK-1);
		if (rbits) {
			if (ucaddr != (char*)uwaddr) {
				/* ubuf is not word aligned. */
				left = rbits;
				sds_bit_offset_blk = BITS2BLOCKS(sds_bit_offset);
				while (left > 0) {
				   if( ssread((int *)localbuf,
				      sds_bit_offset_blk, 1) == -1) {
				      errno = FDC_ERR_SDSIO;
				      return(-1);
				   }
				   MOV_BITS(locptr, ubuf, BITPBLOCK);	
				   SET_BPTR(ubuf, INC_BPTR(ubuf, BITPBLOCK));

				   if( sswrite((int *)localbuf,
				      sds_bit_offset_blk, 1) == -1) {
				      errno = FDC_ERR_SDSIO;
				      return(-1);
				   }
				   SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, BITPBLOCK));
				   sds_bit_offset_blk++;
				   left-= BITPBLOCK;
				
				}
			}
			else {
				if (_sds_fr_mem(sdsaddr, ubuf, rbits) == -1) {
					return(-1);
				}
				SET_BPTR(ubuf, INC_BPTR(ubuf, rbits));
				SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, rbits));
			}
                        sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
		}
		/* Get last block into local memory. Merge in user's memory */
		/* and write it back out to sds. */
	        if( ssread((int *)localbuf, BITS2BLOCKS(sds_bit_offset), 1) == -1) {
		      errno = FDC_ERR_SDSIO;
		      return(-1);
		}
		MOV_BITS(locptr, ubuf, nbits - rbits);	
	        if( sswrite((int *)localbuf, BITS2BLOCKS(sds_bit_offset), 1) == -1) {
		        errno = FDC_ERR_SDSIO;
			return(-1);
		}
	}
	else {
		if(sswrite(uwaddr, BITS2BLOCKS(sds_bit_offset), BITS2BLOCKS(nbits)) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
	}
	return(0);
}
Пример #5
0
static void 
_rb(
	FIOSPTR		css,		/* Current Fortran I/O state	*/
	unit		*cup,		/* Unit pointer			*/
	_f_int		*recmode,	/* Mode				*/
	gfptr_t		bloc,		/* Beginning location		*/
	gfptr_t		eloc,		/* Ending location		*/
	type_packet	*tip)		/* Type information packet	*/
{
	register int	bytshft;
	register int	mode;
	register long	bytes;
	register long	elsize;
	register long	itemlen;
	register long	items;
	register long 	stat;
	register ftype_t type90;
	int		state;
	char		*uda, *udax;
#ifdef	_CRAYT3D
	register short	shared;
	register long	ntot;	
	register long	numleft;	
	long		shrd[MAXSH];
#endif

	if (cup->useq == 0)	/* If direct access file */
		_ferr(css, FEBIONDA, "BUFFER IN");

	if (cup->ufmt)		/* If formatted file */
		_ferr(css, FEBIONFM, "BUFFER IN");

	if (cup->uerr && !cup->unitchk)
		_ferr(css, cup->uffsw.sw_error);

/*
 *	This check taken out temporarily because we'd like to be able to
 *	follow an ENDFILE statement or a READ which encounters an endfile
 *	record with a BUFFER IN statement.  The sticky EOF principle should
 *	permit such a BUFFER IN to simply return an EOF status.  But what
 *	really happens is the preceding ENDFILE or READ statement sets 
 *	cup->uend, triggering an error here.  We really need a flag to
 *	store the status of the previous BUFFER IN/OUT statement which is
 *	separate from cup->uend.
 *
 *	if (cup->uend && !cup->unitchk)
 *		_ferr(css, FERDPEOF);
 */

	cup->unitchk	= 0;
	cup->uerr	= 0;
	elsize		= tip->elsize;	/* Data size in bytes */
	type90		= tip->type90;

/*
 *	Adjust the word count depending on the type.
 */
	bytshft	= ((sizeof(elsize) << 3) - 1) - _leadz(elsize); /* log2(elsize) */

	if (type90 == DVTYPE_ASCII) {	/* If character item */
		uda	= _fcdtocp(bloc.fcd);
		udax	= _fcdtocp(eloc.fcd);
		itemlen	= _fcdlen (eloc.fcd);
	}
	else {
#ifdef	_CRAYT3D
		shared	= 0;

		if (_issddptr(bloc.v)) {
			int	*tmpptr;

			/* Shared data */

			if (!_issddptr(eloc.v)) {
				_ferr(css, FEINTUNK);
			}

			shared	= 1;
			ntot	= 0;

			if ((cup->ufs == FS_FDC) && 
				(cup->uflagword & FFC_ASYNC)) {
				/* When we can do I/O from shared memory */
				/* we can support this. */
				_ferr(css, FESHRSUP);
			}
/*
 * When compiler spr 76429 (on T3D) is closed, we can try replacing 
 * the lines that use tmpptr with this.
 *			items	= _sdd_read_offset((void *)eloc.v) -
 *				_sdd_read_offset((void *)bloc.v) + 1;
 */
			uda	= bloc.v;	/* temporary */
			udax	= eloc.v;
			tmpptr	= (int *)((int)udax & 0x7fffffffffffffff);
			items	= *(tmpptr + 1);
			tmpptr	= (int *)((int)uda & 0x7fffffffffffffff);
			items	= items - *(tmpptr + 1) + 1;
		}
		else
#endif	/* _CRAYT3D */
		{
			uda	= bloc.v;
			udax	= eloc.v;
		}

		itemlen	= elsize;
	}

#ifdef	_CRAYT3D
	if (shared) {
		bytes	= items << bytshft;
	}
	else 
#endif
	{
		bytes	= (udax - uda) + itemlen;
		items	= bytes >> bytshft;
	}

	if (bytes < 0)
		_ferr(css, FEBIOFWA, "BUFFER IN");

	mode		= (*recmode < 0) ? PARTIAL : FULL;
	cup->urecmode	= mode;
	cup->uwrt	= 0;
	state		= CNT;

	if ((items << bytshft) != bytes)
		_ferr(css, FEBIOFWD);

#ifdef	_CRAYT3D
	if ( !shared && cup->uasync ) {
#else
	if (cup->uasync) {
#endif
		int	ubc = 0;

		WAITIO(cup, _ferr(css, cup->uffsw.sw_error));

#if	defined(_UNICOS) || defined(NUMERIC_DATA_CONVERSION_ENABLED)
/*
 *		Pad word-aligned numeric data on word boundaries within
 *		the record for CRI and some foreign data formats. 
 */
		if ((cup->urecpos & cup->ualignmask) != 0 &&
		    type90 != DVTYPE_ASCII && 
		    elsize > 4 ) {
			int		padubc;
			register int	pbytes;
			int		padval;

			COMPADD(cup, pbytes, padubc, padval);

			if (pbytes != 0) {
				stat	= XRCALL(cup->ufp.fdc, readrtn)
						cup->ufp.fdc,
						WPTR2BP(&padval),
						pbytes,
						&cup->uffsw,
						PARTIAL,
						&padubc);
				if (stat != pbytes ||
				    FFSTAT(cup->uffsw) != FFCNT) {
					cup->uerr	= 1;
					goto badpart;
				}
				cup->urecpos	+= (stat << 3) - padubc;
			}
		}