Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

109 lines
2.7 KiB
C

static char sccsid[] = "@(#)03 1.3 src/bos/usr/bin/dosdir/dread.c, cmdpcdos, bos411, 9428A410j 6/16/90 01:58:56";
/*
* COMPONENT_NAME: CMDDOS routines to read dos floppies
*
* FUNCTIONS: dread
*
* ORIGINS: 10,27
*
* IBM CONFIDENTIAL -- (IBM Confidential Restricted when
* combined with the aggregated modules for this product)
* SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1985, 1989
* All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
#include "pcdos.h"
#include "doserrno.h"
/*
* DREAD returns # bytes read or -1 on error
*/
dread(file, buffer, length)
int length;
register FCB *file;
byte *buffer;
{
register int absseek, lread, rspace, readtot;
int read();
TRACE(("dread(file = %x, buffer = %x, length = %d)\n", file, buffer, length));
readtot = 0;
if (file->magic != FCBMAGIC)
{ doserrno = DE_INVAL;
return (-1);
}
if ((file->oflag & 3) == DO_WRONLY)
{ doserrno = DE_ACCES;
return(-1);
}
{
int i, ret;
extern int dos_pid;
for(i=0;i<LOCK_RETRY_COUNT;i++){
if((ret = dlock(dos_pid, file,
file->offset, length, L_TEST)) == -1){
/* hit a lock, try again */
sleep(LOCK_RETRY_TIME);
} else break;
}
if(ret == -1){
doserrno = DE_DEADLK;
return(-1);
}
}
/* determine if read will cross cluster boundary */
rspace = file->clustsize - file->clseek;
if ((file->size - file->offset) < length)
length = file->size - file->offset;
_DFsetlock(file->disk);
while (length >= rspace)
{ absseek = file->seek + file->clseek;
if (lseek(file->disk->fd,absseek,0) < 0) /* find current clust*/
{ doserrno = errno;
_DFunlock(file->disk);
return(-1);
}
lread = _devio(read,file->disk->fd,buffer+readtot,rspace);
if (lread < 0)
{ doserrno = errno;
_DFunlock(file->disk);
return(-1);
}
readtot += lread;
length -= lread;
file->offset += lread;
rspace = file->clustsize;
file->nowcluster = getnextcluster(file->disk,file->nowcluster);
file->seek = file->disk->data + file->clustsize
* ((file->nowcluster)-2);
file->clseek = 0;
}
if (length>0)
{ absseek = file->seek+file->clseek;
if (lseek(file->disk->fd,absseek,0) < 0) /* find current real disk posn*/
{ doserrno = errno;
_DFunlock(file->disk);
return(-1);
}
lread = _devio(read,file->disk->fd,buffer+readtot,length);
if (lread < 0)
{ doserrno = errno;
_DFunlock(file->disk);
return(-1);
}
readtot += lread;
file->offset += lread;
file->clseek += lread;
}
_DFunlock(file->disk);
return(readtot);
}