コード例 #1
0
ファイル: elio.c プロジェクト: dmlb2000/nwchem-cml
/*\ Check if asynchronous I/O operation completed. If yes, invalidate id.
\*/
int elio_probe(io_request_t *req_id, int* status)
{
  int    errval=-1;
  int    aio_i = 0;
     
#ifdef PABLO
  int pablo_code = PABLO_elio_probe;
  PABLO_start( pablo_code );
#endif

  if(*req_id == ELIO_DONE){
      *status = ELIO_DONE;
  } else {
      
#ifdef AIO
#    if defined(CRAY)

#     if defined(FFIO)
      {
         struct ffsw dumstat, *prdstat=&(cb_fout[*req_id].stat);
         fffcntl(cb_fout[*req_id].filedes, FC_ASPOLL, prdstat, &dumstat);
         errval = (FFSTAT(*prdstat) == 0) ? INPROGRESS: 0;
      }
#     else

         errval = ( IO_DONE(cb_fout[*req_id].stat) == 0)? INPROGRESS: 0;

#     endif

#   elif defined(AIX)
      errval = aio_error(cb_fout[(int)*req_id].aio_handle);
#   else
      errval = aio_error(cb_fout+(int)*req_id);
#   endif
#endif
      switch (errval) {
      case 0: 
          while(aio_req[aio_i] != *req_id && aio_i < MAX_AIO_REQ) aio_i++;
          if(aio_i >= MAX_AIO_REQ) ELIO_ERROR(HANDFAIL, aio_i);

      *req_id = ELIO_DONE; 
      *status = ELIO_DONE;
      aio_req[aio_i] = NULL_AIO;
      break;
      case INPROGRESS:
      *status = ELIO_PENDING; 
      break;
      default:
          return PROBFAIL;
      }
  }

#ifdef PABLO
  PABLO_end(pablo_code);
#endif

  return ELIO_OK;
}
コード例 #2
0
int
_er90b_writea(struct fdinfo *fio, bitptr bufptr, int nbytes, 
	struct ffsw *retstat, int fulp, int *ubc)
{
int ret = 0;
char *buf;
ER90BYT *f;
int zero = 0;
struct ffsw dumstat;

	buf = BPTR2CP(bufptr);
	if ((BPBITOFF(bufptr) & 7) != 0 || *ubc != 0)
		ERETURN(retstat, FDC_ERR_UBC, 0);

	if (fio->rwflag == POSITIN) {
		f = (ER90BYT *)fio->lyr_info;
		if (f->tpos) {
			ret = _tape_tpwait(f->fd, &(f->tpos));
			if (ret < 0)
				ERETURN(retstat, errno, 0);
		}		
	}
	else if (fio->rwflag == READIN) {
		/* write after read requires position to zero */
		ret = _er90b_pos(fio, FP_RSEEK, &zero, 1,
			&dumstat);
		if (ret < 0) {
			*retstat = dumstat;
			return(ERR);
		}
	}

	if (nbytes > 0) {
		CLRFFSTAT(*retstat);	/* flag async in progress */
		ret=   writea(fio->realfd, buf, nbytes,
			(struct iosw *)retstat, 0);
		if (ret < 0)
			ERETURN(retstat, errno, 0);
	}
	else if (nbytes < 0) {
		ERETURN(retstat, FDC_ERR_REQ, 0);
	}
	else {	/* nbytes == 0 */
		retstat->sw_flag = 1;
		FFSTAT(*retstat) = FFCNT; /* I/O is done, and other stat */
					/* fields are already set. */
	}
	fio->rwflag = WRITIN;
	return (ret);
}
コード例 #3
0
ファイル: elio.c プロジェクト: dmlb2000/nwchem-cml
/*\ Wait for asynchronous I/O operation to complete. Invalidate id.
\*/
int elio_wait(io_request_t *req_id)
{
  int  aio_i=0;
  int  rc;

  rc=0; /* just to remove the compiler warning */
#ifdef PABLO
  int pablo_code = PABLO_elio_wait;
  PABLO_start( pablo_code );
#endif

  if(*req_id != ELIO_DONE ) { 

#    ifdef AIO
#      if defined(CRAY)

#        if defined(FFIO)
         {
            struct ffsw dumstat, *prdstat=&(cb_fout[*req_id].stat);
            fffcntl(cb_fout[*req_id].filedes, FC_RECALL, prdstat, &dumstat);
            if (FFSTAT(*prdstat) == FFERR) ELIO_ERROR(SUSPFAIL,0);
         }
#        else
         {
            struct iosw *statlist[1];
            statlist[0] = &(cb_fout[*req_id].stat);
            recall(cb_fout[*req_id].filedes, 1, statlist); 
         }
#        endif

#      elif defined(AIX) 
#         if    !defined(AIX52) && !defined(_AIO_AIX_SOURCE)
              do {    /* I/O can be interrupted on SP through rcvncall ! */
                   rc =(int)aio_suspend(1, cb_fout_arr+(int)*req_id);
              } while(rc == -1 && errno == EINTR); 
#         endif

#  else
      if((int)aio_suspend((const struct aiocb *const*)(cb_fout_arr+(int)*req_id), 1, NULL) != 0) rc =-1;
#  endif
      if(rc ==-1) ELIO_ERROR(SUSPFAIL,0);

#  if defined(DECOSF)
      /* on DEC aio_return is required to clean internal data structures */
      if(aio_return(cb_fout+(int)*req_id) == -1) ELIO_ERROR(RETUFAIL,0);
#  endif
#endif

      while(aio_req[aio_i] != *req_id && aio_i < MAX_AIO_REQ) aio_i++;
      if(aio_i >= MAX_AIO_REQ) ELIO_ERROR(HANDFAIL, aio_i);

      aio_req[aio_i] = NULL_AIO;
      *req_id = ELIO_DONE;
   }

#ifdef PABLO
   PABLO_end(pablo_code);
#endif

   return ELIO_OK;
}
コード例 #4
0
ファイル: aqstat.c プロジェクト: sharugupta/OpenUH
void
AQSTAT(
_f_int	*aqp,
_f_int	*reply,
_f_int	*reqid,
_f_int	*status,
_f_int	*wait)
{
	AQFIL		*f;
	struct fflistreq *base, *limit, *ptr, *busy, *eptr;
	struct ffsw	*istat;
	struct ffsw	dumstat;
	int		indx;
	int		ret;
	int		max;
	int		isbusy;

	f	= (AQFIL *) *aqp;

	if (f == NULL || f->aq_chk != AQ_CHK) {
		*status = -FEAQBADH;    /* file handle is not valid */
		return;
	}

	base	= f->aq_base;
	limit	= f->aq_limit;
	max	= limit - base;
/*
 *	Lock the tail of the queue so no one can stomp on the entry for
 *	which we are searching.
 */
	AQ_LOCK(aq_lknxtq);
	AQ_LOCK(aq_lkbusy);		/* don't nobody move */
	busy	= f->aq_busy;
/*
 *	Examine the entire queue, regardless of pointers
 */
	for (indx = 0 ; indx < max ; indx++) {
		if ( f->aq_reqid[indx] == *reqid ) {
			eptr = &base[indx];
			istat = base[indx].li_status;
			ptr = f->aq_ptr;	/* Grab stable copy */
						/* If it moves, that's OK. */
/*
 *			If the user requested that we wait for this one...
 */
			if (_numargs() > 4 && *wait != 0) {
/*
 *				Determine if the entry in question is
 *				between busy and ptr.
 */
				isbusy = NO;
				if (busy <= ptr) {
					if (busy <= eptr && eptr < ptr)
						isbusy = YES;
				}
				else {
					if (eptr < ptr || busy <= eptr)
						isbusy = YES;
				}
/*
 *				Now pointing to entry in question.
 *				Wait for its completion,  if btwn busy and ptr,
 *				Unlock queue head to allow additions
 *				to the queue while waiting.
 */
				AQ_UNLOCK(aq_lknxtq);
/*
 *				If the requested reqid has not been fired,
 *				fire the listio before the wait.
 */
				if (isbusy == NO) {
					_aqcall(f);
				}
				goto finish_io2;
			}
/*
 *			If user did not request wait, just return the status,
 *			but first check to see if it is done.  If it is, Give
 *			the recall routine a shot at cleanup and finish up as
 *			though a wait had been requested.
 */
			if (f->aq_ffio == YES) {
				AQPOLL(eptr, &dumstat);
				if (FFSTAT(*istat) != FFBSY) {
					goto finish_io1;
				}
			}
			else if ( istat->sw_flag != 0 ) {
					goto finish_io1;
			}

/* 
 *			If the entry is found, but not complete, it is
 *			either QUEUED and active or QUEUED and not yet
 *			activated.
 *			If eptr is between busy and ptr, it is active.
 */
			*status = LQUEUED;	/* not yet active */
			if (busy <= ptr) {
				if (busy <= eptr && eptr < ptr)
					/* queued and active */
					*status = QUEUED;
			}
			else {
				if (eptr < ptr || busy <= eptr)
					/* queued and active */
					*status = QUEUED;
			}

			goto done;
		}
	}
	*status = NOTFOUND;

done:
	AQ_UNLOCK(aq_lkbusy);
	AQ_UNLOCK(aq_lknxtq);
	return;

finish_io1:
	AQ_UNLOCK(aq_lknxtq);

finish_io2:
/*
 *	Do the 'recall' on the request.
 */
	ret = _aqrcl(f, eptr);
/*
 *	The request is now done.  Now that we are about to return the status
 *	of the request, check if this entry is at tail of queue.
 *	If the request is at the tail of the queue free up the entry.
 *	This is probably silly.
 */
	if (f->aq_busy == eptr)
		INC_QP(f->aq_busy, limit, max);

/*
 *	Set return status
 */
	*status = IOCOMPLETE;
	if (ret != 0)
		{
		*status = -ret;
		if (ret == FERDWRER)
			*reply = eptr->li_status->sw_count;
		}
/*
 *	Flag the status as delivered
 */
	f->aq_told[indx] = 1;	/* mark status as having been sent to user */

	AQ_UNLOCK(aq_lkbusy);

	return;
}
コード例 #5
0
long
_frch(
	unit	*cup,
	long	*uda,
	long	chars,
	int	mode,
	long	*status)
{
	register int	bytsiz;
	register int	chr;
	register long	nchr;
	register long	ncnt;
	unsigned char	tbuf[TBUFSZB], *tp;	/* Line buffer */
	FILE		*fptr;
	struct ffsw	stat;
	struct fdinfo	*fio;
#if	defined(_SOLARIS) || (defined(_LITTLE_ENDIAN) && !defined(__sv2))
	register long	count;
	char		*tpinterim;
#endif
 
	switch (cup->ufs) {

	case FS_TEXT:
	case STD:
		fptr	= cup->ufp.std;
/*
 *		Switch the FILE structure into read mode
 */
#if	!defined(_LITTLE_ENDIAN) || (defined(_LITTLE_ENDIAN) && defined(__sv2))
		if ((FILE_FLAG(fptr) & (_IOREAD | _IORW)) == _IORW) {

			if (FILE_FLAG(fptr) & _IOWRT)
				(void) fseek(fptr, 0, SEEK_CUR);

			FILE_FLAG(fptr) |= _IOREAD;
		}
#endif
/*
 * 		Loop on getc until the character count has been 
 *		exhausted, an end of file is encountered, or end
 *		of record.
 */
		nchr	= 0;
#if	defined(_SOLARIS) || (defined(_LITTLE_ENDIAN) && !defined(__sv2))
		while (nchr < chars) {
fill:
			errno	= 0;
			count	= chars - nchr;
			tp	= tbuf;
			count	= MIN(TBUFSZB, (count + 1));
			tpinterim	= fgets((char *)tp, count, fptr);
			if (tpinterim == NULL) {
			/*
			 * Search for the newline char in the buffer, but
			 * search only the number of characters left in
			 * the request, plus one in case it is the
			 * newline (if it is in the buffer).  If we find
			 * newline, we're done.
			 */
			/* EOF here means incomplete record. */
				if (ferror(fptr)) {
					if ( errno == EINTR  && _GINTIO == 0) {
						clearerr(fptr);
						goto fill;
					}
					if (errno == 0)
						errno	= FESTIOER;
					return(IOERR);
				}
				/*
				 * If nchr > zero, file has no newline.
				 * Make sure we handle it properly.
				 */
				if (feof(fptr)) {
					if (nchr == 0) {
						*status	= EOD;
						return(0);
					}
					*status	= CNT;
					return(nchr);
				}
			} else {
				unsigned char	*tmpptr;
				ncnt	= count - 1;
#ifdef KEY /* Bug 3797 */
				/* no newline if fgets encountered eof */
				tmpptr	= strchr(tp, '\n');
#ifdef KEY /* Bug 3975 */
				char *nlptr	= memchr(tp, '\n', ncnt);
				/* Temporary fix to deal with the situation
				 * in which nulls appear before the newline.
				 * Correct fix is to eliminate those nulls.
				 */
				if (NULL == tmpptr && NULL != nlptr) {
					tmpptr = nlptr;
				}
#endif /* KEY Bug 3975 */
#else
				tmpptr	= memchr(tp, '\n', ncnt);
#endif /* KEY Bug 3797 */
				if (tmpptr != NULL) {	/* eor */
					*status	= EOR;
					ncnt	= tmpptr - tp;
					nchr	+= ncnt;
					_unpack(tp, uda, ncnt, -1);
					/* Return number of chars read */
					return(nchr);
				}
#ifdef KEY /* Bug 3797 */
				/* fgets got chars ending in eof, not newline */
				else if (feof(fptr)) {
					*status = EOR;
					ncnt = strlen(tp);
					nchr += ncnt;
					_unpack(tp, uda, ncnt, -1);
					return nchr;
				}
#endif /* KEY Bug 3797 */
				_unpack(tp, uda, ncnt, -1);
				nchr		+= ncnt;
				uda		+= ncnt;

				/* go refill the buffer */
			}
		}
#else
		while (nchr < chars) {
			if (FILE_CNT(fptr) <= 0) {
fill:
				errno	= 0;
				chr	= _filbuf(fptr);

				/* EOF here means incomplete record. */

				if (chr == EOF) {

					if (ferror(fptr)) {

						if ( errno == EINTR &&
						 _GINTIO == 0 ) {
							clearerr(fptr);
							goto fill;
						}

						if (errno == 0)
							errno	= FESTIOER;

						return(IOERR);
					}
/*
 *					If nchr > zero, file has no newline.
 *					Make sure we handle it properly.
 */
					if (nchr == 0) {
						*status	= EOD;
						return(0);
					}

					*status	= CNT;
					return(nchr);
				}
/*
 *				Put character returned by filbuf() back
 */
				FILE_CNT(fptr)++;
				FILE_PTR(fptr)--;
			}
/*
 *			Search for a newline char in the buffer, but search
 *			only the number of characters left in the request,
 *			plus one in case it is the newline (if it is in
 *			the buffer).  If we find the newline, we're done.
 */
			if ((chars - nchr) < FILE_CNT(fptr)) {
				ncnt	= chars - nchr;
				tp	= memchr(FILE_PTR(fptr), '\n', ncnt + 1);
			}
			else {
				ncnt	= FILE_CNT(fptr);	/* assume no EOR yet */
				tp	= memchr(FILE_PTR(fptr), '\n', ncnt);
			}

			if (tp != NULL) {	/* Found end of record */

				*status	= EOR;
				ncnt	= tp - FILE_PTR(fptr);
				nchr	+= ncnt;

				_unpack((char *)FILE_PTR(fptr), uda, ncnt, -1);

				FILE_CNT(fptr)	-= ncnt + 1;
				FILE_PTR(fptr)	+= ncnt + 1;

				return(nchr);	/* Return number of characters read */
			}

			_unpack((char *)FILE_PTR(fptr), uda, ncnt, -1);

			FILE_CNT(fptr)	-= ncnt;
			FILE_PTR(fptr)	+= ncnt;
			nchr		+= ncnt;
			uda		+= ncnt;

			/* go refill the buffer */
		}
#endif
/*
 *		Get the next character to see if at end of record.
 * 		Set the user's status word accordingly.
 */
		chr	= getc(fptr);

		*status	= CNT;

		if (chr == '\n' ) {
			*status	= EOR;
			return(nchr);	/* Return number of characters read */
		}
/*
 *		We are not at end of record.  Thus if reading in full
 *		record mode skip until EOR is found.  If reading in 
 *		partial record mode, unget the last character read.
 */
		if (mode == FULL)
#if	defined(_SOLARIS) || (defined(_LITTLE_ENDIAN) && !defined(__sv2))
		{
fill2:
			count	= TBUFSZB;
			tp	= tbuf;
			tpinterim = fgets((char *)tp, count, fptr);
			if (tpinterim == NULL) {
				/* EOF means incomplete record. */
				if (ferror(fptr)) {
					if ( errno == EINTR && _GINTIO == 0 ) {
						clearerr(fptr);
						goto fill2;
					}
				}
				/* Return number of chars read. */
				return(nchr);
			} else {
				unsigned char	*tmpptr;
				ncnt	= count - 1;
				tmpptr	= memchr(tp, '\n', ncnt);
				if (tmpptr != NULL) {	/* Found eor */
					/* Return number of chars read */
					return(nchr);
				} else
					goto fill2;
			}
		}
#else
			while (1) {
				if (FILE_CNT(fptr) <= 0) {
fill2:
					chr	= _filbuf(fptr);

					/* EOF here means incomplete record. */

					if (chr == EOF) {

						if (ferror(fptr)) {

							if ( errno == EINTR &&
							 _GINTIO == 0 ) {
								clearerr(fptr);
								goto fill2;
							}

						}

						/* Return number of characters read */

						return(nchr);
					}

					FILE_CNT(fptr)++;
					FILE_PTR(fptr)--;
				}

				tp	= memchr(FILE_PTR(fptr), '\n', FILE_CNT(fptr));

				if (tp != NULL) {

					tp++;
					FILE_CNT(fptr)	-= tp - FILE_PTR(fptr);
					FILE_PTR(fptr)	= tp;

					return(nchr);
				}
				else
					FILE_CNT(fptr)	= 0;
			}
#endif
		else {
			ungetc ((char) chr, fptr);
		}

		return(nchr);	/* return number of character read */

	case FS_FDC:
		nchr	= 0;
		fio	= cup->ufp.fdc;
/*
 *		If no conversion is to be done, or no characters requested
 *		(usually for null request, FULL mode), make it simple and direct.
 */
		if (cup->ucharset == 0 || chars == 0) {
			register long	breq;
			register int	ffstat;
			register int	ret;
/*
 *			If file is direct access, we know that all reads are
 *			going to be whole records in FULL mode.  We also
 *			know that the open code would not let us get this far
 *			if we were not dealing with a stream layer.
 */

			breq	= chars;

			ret	= XRCALL(fio, readcrtn) fio, CPTR2BP(uda),
					breq, &stat, mode);

			if (ret < 0) {
				errno	= stat.sw_error;
				return(IOERR);
			}

			ffstat	= FFSTAT(stat);

			if (!cup->useq && !cup->ublkd && ffstat == FFCNT)
				ffstat	= FFEOR;

			*status	= FF2FTNST(ffstat);
			nchr	= ret;

			return(nchr);	/* Return number of characters read */
		}
/*
 *		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
		FFSTAT(cup->uffsw)	= FFCNT;
		*status	= CNT;

		while (nchr < chars && FFSTAT(cup->uffsw) != FFEOR) {
			register long	bgot;
			register long	breq;
			register long	padc;
			register int	ret;
			register long	totbits;
			int		ubc;
/*
 *			Calculate the number of bits that need to be taken
 *			from the foreign data stream.
 *
 *			ncnt	= number of resultant bytes
 */
			ncnt	= chars - nchr;

			if (ncnt > TBUFSZB)
				ncnt	= TBUFSZB;

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

			ret	= XRCALL(fio, readrtn) fio, CPTR2BP(tbuf),
					breq, &cup->uffsw, PARTIAL, &ubc);

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

			/* if end of file */

			if (ret == 0) {
				if (nchr == 0)
					*status	= FF2FTNST(FFSTAT(stat));
				return(nchr);	/* Return number of characters read */
			}

/*
 *			how many bits did we get?  Convert back to foreign
 *			character count.
 */
			totbits	= (ret << 3) - ubc;
			bgot	= totbits / bytsiz;	/* foreign bytes */
			ubc	= totbits - (bgot * bytsiz);

			if (ubc != 0) {
				errno	= FEINTUNK;
				return(IOERR);
			}

			padc	= 0;

			if (FFSTAT(cup->uffsw) == FFEOR) {
				padc	= chars - (bgot + nchr);
				*status	= EOR;
			}

			if (_fdc_unpackc(tbuf, &uda[nchr], bgot, padc,
				cup->ucharset) < 0) {
				return(IOERR);
			}

			nchr	+= bgot;
		}

		/* check for null request, non-EOR */

		if (FFSTAT(cup->uffsw) == FFCNT && mode == FULL) {
			register int	ret;
			int		ubc;

			ret	= XRCALL(fio, readrtn) fio, CPTR2BP(tbuf), 0,
					&cup->uffsw, FULL, &ubc);

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

	case FS_AUX:
		errno	= FEMIXAUX;
		return(IOERR);

	default:
		errno	= FEINTFST;
		return(IOERR);
	}
コード例 #6
0
ファイル: rb.c プロジェクト: sharugupta/OpenUH
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;
			}
		}
コード例 #7
0
int
_sqb_pos(struct fdinfo *fio, int cmd, long *arg, int len, struct ffsw *stat)
{
int ret = 0;
struct sqb_f *sqb_info;
struct sqbio *sqbptr;
struct sqbio *sqborig;
struct sqbio *s;
struct fdinfo *llfio;
int found = 0;
int nbits;
int sync = -1;

	llfio = fio->fioptr;
	sqb_info = (struct sqb_f *)fio->lyr_info;

	if (fio->rwflag == WRITIN) {
		/* flush buffers and wait for outstanding I/O to finish. */
		if (_sqb_flush(fio, stat) < 0) {
			return(ERR);
		}
	}

	switch(cmd) {
/* For now, this is not supported on SGI systems. */
/* We need to work out what "arg" should be. */
#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
		case FP_RSEEK:
			if ((fio->rwflag == READIN) || 
			   (fio->rwflag == POSITIN)) {
			   if (*arg < 0) {
				/* Seeking backwards */
				/* Are we seeking within the current */
				/* buffer? */
				sqbptr = sqb_info->sqbio_cur;
				if (sqbptr->status == IOACTIVE) {
				   while (sqbptr->iostat.sw_flag == 0 ||
					sqbptr->iostat.sw_stat == 0) {
					ret = XRCALL(llfio,fcntlrtn) llfio,
					FC_RECALL, &(sqbptr->iostat), stat);
					if (ret < 0) {
						return(ERR);
					}
				   }
				   if (FFSTAT(sqbptr->iostat) == FFERR) {
					ERETURN(stat, sqbptr->iostat.sw_error,0);
				   }
				   sqbptr->_cnt = sqbptr->iostat.sw_count<<3;
				   sqbptr->status = IODATA;
				}
				if (sqbptr->status == IODATA) {
					nbits = -(*arg); /* convert to positive */
					nbits = nbits<<3;
					if (nbits <=
					 SUBT_BPTR(sqb_info->_ptr,sqbptr->_base)){
						SET_BPTR(sqb_info->_ptr,
						 INC_BPTR(sqb_info->_ptr,-nbits));
						sqbptr->_cnt += nbits;
						break;
					  }
				}
			   }
			   else {
				/* seeking forward */
				/* Any chance that the position would be in */
				/* our buffers? */
				nbits = *arg << 3;
				if (nbits > sqb_info->nbuf * sqb_info->bufsiz){
					/* won't be in any of the buffers */
					goto a1;
				}
				sqbptr = sqb_info->sqbio_cur;
				sqborig = sqbptr;
				do {
				   if (sqbptr->status == IOACTIVE) {
				      while (sqbptr->iostat.sw_flag == 0 ||
					sqbptr->iostat.sw_stat == 0) {
				   	   ret = XRCALL(llfio,fcntlrtn) llfio,
					   FC_RECALL, &(sqbptr->iostat), stat);
					   if (ret < 0) {
						return(ERR);
					   }
				      }
				      if (FFSTAT(sqbptr->iostat) == FFERR) {
					ERETURN(stat, sqbptr->iostat.sw_error,0);
				      }
				      sqbptr->_cnt = sqbptr->iostat.sw_count<<3;
				      sqbptr->status = IODATA;
				   }
				   if (sqbptr->status == IODATA) {
					if (nbits <= sqbptr->_cnt) {
						/* Desired position is in this buffer */
						sqbptr->_cnt -= nbits;
						/* Clear out buffers that preceeded this */
						s = sqborig;
						for (; s != sqbptr; s= s->nxt) {
							s->status = EMPTY;
							CLRFFSTAT(s->iostat);
						}
						sqb_info->sqbio_cur = sqbptr;
						if (sqbptr != sqborig)
							sqb_info->_ptr = sqbptr->_base;
						SET_BPTR(sqb_info->_ptr,
						 INC_BPTR(sqb_info->_ptr,nbits));
						found = 1;
						break;
					}
					else {
						nbits -= sqbptr->_cnt;
					}
				   }
				   else
					goto a1;	/* all out of data */
				   sqbptr = sqbptr->nxt;
				} while (sqbptr != sqborig);
			   }
			   }