⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclmacchan.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 3 页
字号:
    chan = Tcl_CreateChannel(&fileChannelType, channelName, 	(ClientData) fileState, channelPermissions);    if (chan == (Tcl_Channel) NULL) {	*errorCodePtr = errno = EFAULT;	Tcl_SetErrno(errno);	FSClose(fileRef);	ckfree((char *) fileState);        return NULL;    }    fileState->fileChan = chan;    fileState->nextPtr = tsdPtr->firstFilePtr;    tsdPtr->firstFilePtr = fileState;    fileState->volumeRef = fileSpec.vRefNum;    fileState->fileRef = fileRef;    fileState->pending = 0;    fileState->watchMask = 0;    if (mode & O_APPEND) {	fileState->appendMode = true;    } else {	fileState->appendMode = false;    }            if ((mode & O_APPEND) || (mode & O_APPEND)) {        if (Tcl_Seek(chan, 0, SEEK_END) < 0) {	    *errorCodePtr = errno = EFAULT;	    Tcl_SetErrno(errno);            Tcl_Close(NULL, chan);            FSClose(fileRef);            ckfree((char *) fileState);            return NULL;        }    }        return chan;}/* *---------------------------------------------------------------------- * * Tcl_MakeFileChannel -- * *	Makes a Tcl_Channel from an existing OS level file handle. * * Results: *	The Tcl_Channel created around the preexisting OS level file handle. * * Side effects: *	None. * *---------------------------------------------------------------------- */Tcl_ChannelTcl_MakeFileChannel(handle, mode)    ClientData handle;		/* OS level handle. */    int mode;			/* ORed combination of TCL_READABLE and                                 * TCL_WRITABLE to indicate file mode. */{    /*     * Not implemented yet.     */    return NULL;}/* *---------------------------------------------------------------------- * * FileBlockMode -- * *	Set blocking or non-blocking mode on channel.  Macintosh files *	can never really be set to blocking or non-blocking modes. *	However, we don't generate an error - we just return success. * * Results: *	0 if successful, errno when failed. * * Side effects: *	Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */static intFileBlockMode(    ClientData instanceData,		/* Unused. */    int mode)				/* The mode to set. */{    return 0;}/* *---------------------------------------------------------------------- * * FileClose -- * *	Closes the IO channel. * * Results: *	0 if successful, the value of errno if failed. * * Side effects: *	Closes the physical channel * *---------------------------------------------------------------------- */static intFileClose(    ClientData instanceData,	/* Unused. */    Tcl_Interp *interp)		/* Unused. */{    FileState *fileState = (FileState *) instanceData;    int errorCode = 0;    OSErr err;    err = FSClose(fileState->fileRef);    FlushVol(NULL, fileState->volumeRef);    if (err != noErr) {	errorCode = errno = TclMacOSErrorToPosixError(err);	panic("error during file close");    }    ckfree((char *) fileState);    Tcl_SetErrno(errorCode);    return errorCode;}/* *---------------------------------------------------------------------- * * FileInput -- * *	Reads input from the IO channel into the buffer given. Returns *	count of how many bytes were actually read, and an error indication. * * Results: *	A count of how many bytes were read is returned and an error *	indication is returned in an output argument. * * Side effects: *	Reads input from the actual channel. * *---------------------------------------------------------------------- */intFileInput(    ClientData instanceData,	/* Unused. */    char *buffer,				/* Where to store data read. */    int bufSize,				/* How much space is available                                 * in the buffer? */    int *errorCodePtr)			/* Where to store error code. */{    FileState *fileState = (FileState *) instanceData;    OSErr err;    long length = bufSize;    *errorCodePtr = 0;    errno = 0;    err = FSRead(fileState->fileRef, &length, buffer);    if ((err == noErr) || (err == eofErr)) {	return length;    } else {	switch (err) {	    case ioErr:		*errorCodePtr = errno = EIO;	    case afpAccessDenied:		*errorCodePtr = errno = EACCES;	    default:		*errorCodePtr = errno = EINVAL;	}        return -1;	    }    *errorCodePtr = errno;    return -1;}/* *---------------------------------------------------------------------- * * FileOutput-- * *	Writes the given output on the IO channel. Returns count of how *	many characters were actually written, and an error indication. * * Results: *	A count of how many characters were written is returned and an *	error indication is returned in an output argument. * * Side effects: *	Writes output on the actual channel. * *---------------------------------------------------------------------- */static intFileOutput(    ClientData instanceData,		/* Unused. */    CONST char *buffer,			/* The data buffer. */    int toWrite,			/* How many bytes to write? */    int *errorCodePtr)			/* Where to store error code. */{    FileState *fileState = (FileState *) instanceData;    long length = toWrite;    OSErr err;    *errorCodePtr = 0;    errno = 0;        if (fileState->appendMode == true) {	FileSeek(instanceData, 0, SEEK_END, errorCodePtr);	*errorCodePtr = 0;    }        err = FSWrite(fileState->fileRef, &length, buffer);    if (err == noErr) {	err = FlushFile(fileState->fileRef);    } else {	*errorCodePtr = errno = TclMacOSErrorToPosixError(err);	return -1;    }    return length;}/* *---------------------------------------------------------------------- * * FileSeek -- * *	Seeks on an IO channel. Returns the new position. * * Results: *	-1 if failed, the new position if successful. If failed, it *	also sets *errorCodePtr to the error code. * * Side effects: *	Moves the location at which the channel will be accessed in *	future operations. * *---------------------------------------------------------------------- */static intFileSeek(    ClientData instanceData,	/* Unused. */    long offset,		/* Offset to seek to. */    int mode,			/* Relative to where should we seek? */    int *errorCodePtr)		/* To store error code. */{    FileState *fileState = (FileState *) instanceData;    IOParam pb;    OSErr err;    *errorCodePtr = 0;    pb.ioCompletion = NULL;    pb.ioRefNum = fileState->fileRef;    if (mode == SEEK_SET) {	pb.ioPosMode = fsFromStart;    } else if (mode == SEEK_END) {	pb.ioPosMode = fsFromLEOF;    } else if (mode == SEEK_CUR) {	err = PBGetFPosSync((ParmBlkPtr) &pb);	if (pb.ioResult == noErr) {	    if (offset == 0) {		return pb.ioPosOffset;	    }	    offset += pb.ioPosOffset;	}	pb.ioPosMode = fsFromStart;    }    pb.ioPosOffset = offset;    err = PBSetFPosSync((ParmBlkPtr) &pb);    if (pb.ioResult == noErr){	return pb.ioPosOffset;    } else if (pb.ioResult == eofErr) {	long currentEOF, newEOF;	long buffer, i, length;		err = PBGetEOFSync((ParmBlkPtr) &pb);	currentEOF = (long) pb.ioMisc;	if (mode == SEEK_SET) {	    newEOF = offset;	} else if (mode == SEEK_END) {	    newEOF = offset + currentEOF;	} else if (mode == SEEK_CUR) {	    err = PBGetFPosSync((ParmBlkPtr) &pb);	    newEOF = offset + pb.ioPosOffset;	}		/*	 * Write 0's to the new EOF.	 */	pb.ioPosOffset = 0;	pb.ioPosMode = fsFromLEOF;	err = PBGetFPosSync((ParmBlkPtr) &pb);	length = 1;	buffer = 0;	for (i = 0; i < (newEOF - currentEOF); i++) {	    err = FSWrite(fileState->fileRef, &length, &buffer);	}	err = PBGetFPosSync((ParmBlkPtr) &pb);	if (pb.ioResult == noErr){	    return pb.ioPosOffset;	}    }    *errorCodePtr = errno = TclMacOSErrorToPosixError(err);    return -1;}/* *---------------------------------------------------------------------- * * CommonWatch -- * *	Initialize the notifier to watch handles from this channel. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */static voidCommonWatch(    ClientData instanceData,		/* The file state. */    int mask)				/* Events of interest; an OR-ed                                         * combination of TCL_READABLE,                                         * TCL_WRITABLE and TCL_EXCEPTION. */{    FileState *infoPtr = (FileState *) instanceData;    Tcl_Time blockTime = { 0, 0 };    infoPtr->watchMask = mask;    if (infoPtr->watchMask) {	Tcl_SetMaxBlockTime(&blockTime);    }}/* *---------------------------------------------------------------------- * * TclpCutFileChannel -- * *	Remove any thread local refs to this channel. See *	Tcl_CutChannel for more info. * * Results: *	None. * * Side effects: *	Changes thread local list of valid channels. * *---------------------------------------------------------------------- */voidTclpCutFileChannel(chan)    Tcl_Channel chan;			/* The channel being removed. Must                                         * not be referenced in any                                         * interpreter. */{    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);    Channel *chanPtr = (Channel *) chan;    FileState *infoPtr;    FileState **nextPtrPtr;    int removed = 0;    if (chanPtr->typePtr != &fileChannelType)        return;    infoPtr = (FileState *) chanPtr->instanceData;    for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;	 nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {	if ((*nextPtrPtr) == infoPtr) {	    (*nextPtrPtr) = infoPtr->nextPtr;	    removed = 1;	    break;	}    }    /*     * This could happen if the channel was created in one thread     * and then moved to another without updating the thread     * local data in each thread.     */    if (!removed)        panic("file info ptr not on thread channel list");}/* *---------------------------------------------------------------------- * * TclpSpliceFileChannel -- * *	Insert thread local ref for this channel. *	Tcl_SpliceChannel for more info. * * Results: *	None. * * Side effects: *	Changes thread local list of valid channels. * *---------------------------------------------------------------------- */voidTclpSpliceFileChannel(chan)    Tcl_Channel chan;			/* The channel being removed. Must                                         * not be referenced in any                                         * interpreter. */{    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);    Channel *chanPtr = (Channel *) chan;    FileState *infoPtr;    if (chanPtr->typePtr != &fileChannelType)        return;    infoPtr = (FileState *) chanPtr->instanceData;    infoPtr->nextPtr = tsdPtr->firstFilePtr;    tsdPtr->firstFilePtr = infoPtr;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -