int fd_read(char *buffer, Bit32u offset, Bit32u bytes) { OSErr err; IOParam param; param.ioRefNum=-5; // Refnum of the floppy disk driver param.ioVRefNum=1; param.ioPosMode=fsFromStart; param.ioPosOffset=offset; param.ioBuffer=buffer; param.ioReqCount=bytes; err = PBReadSync((union ParamBlockRec *)(¶m)); return param.ioActCount; }
static Handle read_handle_from_file( short refNum, long offset, long length) { OSErr error= noErr; Handle data= NULL; if (refNum!=-1) { if (data= NewHandle(length)) { ParamBlockRec param; HLock(data); param.ioParam.ioCompletion= (IOCompletionUPP) NULL; param.ioParam.ioRefNum= refNum; param.ioParam.ioBuffer= *data; param.ioParam.ioReqCount= length; param.ioParam.ioPosMode= fsFromStart; param.ioParam.ioPosOffset= offset; error= PBReadSync(¶m); if (error==noErr) { HUnlock(data); } else { DisposeHandle(data); data= NULL; } } else { error= MemError(); } } vwarn(error==noErr, csprintf(temporary, "read_handle_from_file() got error #%d", error)); return data; }
static OSStatus FSReadAtOffset(SInt16 refNum, SInt32 offset, SInt32 count, void *buffer) // A convenient wrapper around PBRead which has two advantages // over FSRead. First, it takes count as a value parameter. // Second, it reads from an arbitrary offset into the file, // which avoids a bunch of SetFPos calls. // // I guess this should go into "MoreFiles.h", but I'm not sure // how we're going to integrate such a concept into MIB yet. { ParamBlockRec pb; pb.ioParam.ioRefNum = refNum; pb.ioParam.ioBuffer = (Ptr) buffer; pb.ioParam.ioReqCount = count; pb.ioParam.ioPosMode = fsFromStart; pb.ioParam.ioPosOffset = offset; return PBReadSync(&pb); }
// ====================== 1st thread PRInt32 readWriteProc(PRFileDesc fd, void buf, PRUint32 bytes, IOOperation op) { PRInt32 refNum; OSErr err; int pbAsync_pb; int me_io_pending; // quick hack to allow PR_fprintf, etc to work with stderr, stdin, stdout // note, if a user chooses "seek" or the like as an operation in another function // this will not work if (refNum >= 0 && refNum < 3) { switch (refNum) { case 0: //stdin - not on a Mac for now err = paramErr; goto ErrorExit; break; case 1: // stdout case 2: // stderr puts(); break; } return (bytes); } else { PRBool doingAsync = PR_FALSE; // // Issue the async read call and wait for the io semaphore associated // with this thread. // Async file system calls *never* return error values, so ignore their // results (see <http://developer.apple.com/technotes/fl/fl_515.html>); // the completion routine is always called. // if (op == READ_ASYNC) { // // Skanky optimization so that reads < 20K are actually done synchronously // to optimize performance on small reads (e.g. registry reads on startup) // if ( bytes > 20480L ) { doingAsync = PR_TRUE; { __ESBMC_atomic_begin(); if (__COUNT__ == 0) { me_io_pending = PR_TRUE; // check for order violation __COUNT__ = __COUNT__ + 1; } else { assert(0); } __ESBMC_atomic_end(); } __START_ASYNC__ = True; // second thread can start (void)PBReadAsync(pbAsync_pb); } else { me_io_pending = PR_FALSE; err = PBReadSync(pbAsync_pb); if (err != noErr && err != eofErr) goto ErrorExit; } } else { doingAsync = PR_TRUE; me_io_pending = PR_TRUE; // writes are currently always async (void)PBWriteAsync(pbAsync_pb); } if (doingAsync) { WaitOnThisThread(PR_INTERVAL_NO_TIMEOUT); } } if (err != noErr) goto ErrorExit; if (err != noErr && err != eofErr) goto ErrorExit; return; ErrorExit: _MD_SetError(err); return -1; }