if (op == READ_ASYNC) bytesDone = fread(buf, 1, bytes, systemFP); else bytesDone = fwrite(buf, 1, bytes, systemFP);  if (errno) { err = errno; goto ErrorExit; } else return (bytesDone);
return (bytes);
PRInt32 ReadWriteProc(PRFileDesc *fd, void *buf, PRUint32 bytes, IOOperation op){	PRInt32 refNum = fd->secret->md.osfd;	OSErr				err; 	ExtendedParamBlock 	pbAsync;	PRThread			*me = _PR_MD_CURRENT_THREAD();    _PRCPU *cpu = _PR_MD_CURRENT_CPU();#if 0	/* 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 */	FILE*	systemFP = NULL;	extern int errno;				switch (refNum)	{			case 0:				systemFP = stdin;				break;			case 1:				systemFP = stdout;				break;			case 2:				systemFP = stderr;			break;	}			if (systemFP)	{		size_t bytesDone;				if (op == READ_ASYNC)			bytesDone = fread(buf, 1, bytes, systemFP);		else			bytesDone = fwrite(buf, 1, bytes, systemFP);				if (errno)		{			err = errno;			goto ErrorExit;		}		else			return (bytesDone);	}	else#else	if (refNum >= 0 && refNum < 3)	{		PR_ASSERT(FALSE);	/* writing to these is hazardous to a Mac's health (refNum 2 is the system file) */		err = paramErr;		goto ErrorExit;	}#endif	{		static IOCompletionUPP	sCompletionUPP = NULL;				/* allocate the callback Universal Procedure Pointer (UPP). This actually allocates		   a 32 byte Ptr in the heap, so only do this once		*/		if (!sCompletionUPP)			sCompletionUPP = NewIOCompletionProc((ProcPtr)&AsyncIOCompletion);					/* grab the thread so we know which one to post to at completion */		pbAsync.thread	= me;		pbAsync.pb.ioParam.ioCompletion	= sCompletionUPP;		pbAsync.pb.ioParam.ioResult		= noErr;		pbAsync.pb.ioParam.ioRefNum		= refNum;		pbAsync.pb.ioParam.ioBuffer		= buf;		pbAsync.pb.ioParam.ioReqCount	= bytes;		pbAsync.pb.ioParam.ioPosMode	= fsAtMark;		pbAsync.pb.ioParam.ioPosOffset	= 0;		/* 		** Issue the async read call and wait for the io semaphore associated		** with this thread.		** Don't compute error code from async call. Bug in OS returns a garbage value.		*/	    me->io_pending = PR_TRUE;	    me->io_fd = refNum;		me->md.osErrCode = noErr;		if (op == READ_ASYNC)			(void) PBReadAsync(&pbAsync);		else			(void) PBWriteAsync(&pbAsync);				/* See if the i/o call is still pending before we actually yield */		if (pbAsync.pb.ioParam.ioResult == 1)			WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);	}		err = me->md.osErrCode;	if (err != noErr)		goto ErrorExit;	err = pbAsync.pb.ioParam.ioResult;	if (err != noErr && err != eofErr)		goto ErrorExit;	else		return pbAsync.pb.ioParam.ioActCount;ErrorExit:	me->md.osErrCode = err;	_MD_SetError(err);    return -1;}