📄 tclmacchan.c
字号:
tsdPtr->stderrChannel = NULL; } else { panic("recieved invalid std file"); } if (close(fd) < 0) { errorCode = errno; } } return errorCode;}/* *---------------------------------------------------------------------- * * CommonGetHandle -- * * Called from Tcl_GetChannelHandle to retrieve OS handles from inside * a file based channel. * * Results: * The appropriate handle or NULL if not present. * * Side effects: * None. * *---------------------------------------------------------------------- */static intCommonGetHandle( ClientData instanceData, /* The file state. */ int direction, /* Which handle to retrieve? */ ClientData *handlePtr){ if ((direction == TCL_READABLE) || (direction == TCL_WRITABLE)) { *handlePtr = (ClientData) ((FileState*)instanceData)->fileRef; return TCL_OK; } return TCL_ERROR;}/* *---------------------------------------------------------------------- * * StdIOInput -- * * 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. * *---------------------------------------------------------------------- */intStdIOInput( ClientData instanceData, /* Unused. */ char *buf, /* Where to store data read. */ int bufSize, /* How much space is available * in the buffer? */ int *errorCode) /* Where to store error code. */{ int fd; int bytesRead; /* How many bytes were read? */ *errorCode = 0; errno = 0; fd = (int) ((FileState*)instanceData)->fileRef; bytesRead = read(fd, buf, (size_t) bufSize); if (bytesRead > -1) { return bytesRead; } *errorCode = errno; return -1;}/* *---------------------------------------------------------------------- * * StdIOOutput-- * * 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 intStdIOOutput( ClientData instanceData, /* Unused. */ CONST char *buf, /* The data buffer. */ int toWrite, /* How many bytes to write? */ int *errorCode) /* Where to store error code. */{ int written; int fd; *errorCode = 0; errno = 0; fd = (int) ((FileState*)instanceData)->fileRef; written = write(fd, (void*)buf, (size_t) toWrite); if (written > -1) { return written; } *errorCode = errno; return -1;}/* *---------------------------------------------------------------------- * * StdIOSeek -- * * 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 intStdIOSeek( ClientData instanceData, /* Unused. */ long offset, /* Offset to seek to. */ int mode, /* Relative to where should we seek? */ int *errorCodePtr) /* To store error code. */{ int newLoc; int fd; *errorCodePtr = 0; fd = (int) ((FileState*)instanceData)->fileRef; newLoc = lseek(fd, offset, mode); if (newLoc > -1) { return newLoc; } *errorCodePtr = errno; return -1;}/* *---------------------------------------------------------------------- * * Tcl_PidObjCmd -- * * This procedure is invoked to process the "pid" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ /* ARGSUSED */intTcl_PidObjCmd(dummy, interp, objc, objv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST *objv; /* Argument strings. */{ ProcessSerialNumber psn; char buf[20]; Tcl_Channel chan; Tcl_Obj *resultPtr; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?channelId?"); return TCL_ERROR; } if (objc == 1) { resultPtr = Tcl_GetObjResult(interp); GetCurrentProcess(&psn); sprintf(buf, "0x%08x%08x", psn.highLongOfPSN, psn.lowLongOfPSN); Tcl_SetStringObj(resultPtr, buf, -1); } else { chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), NULL); if (chan == (Tcl_Channel) NULL) { return TCL_ERROR; } /* * We can't create pipelines on the Mac so * this will always return an empty list. */ } return TCL_OK;}/* *---------------------------------------------------------------------- * * TclpGetDefaultStdChannel -- * * Constructs a channel for the specified standard OS handle. * * Results: * Returns the specified default standard channel, or NULL. * * Side effects: * May cause the creation of a standard channel and the underlying * file. * *---------------------------------------------------------------------- */Tcl_ChannelTclpGetDefaultStdChannel( int type) /* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */{ Tcl_Channel channel = NULL; int fd = 0; /* Initializations needed to prevent */ int mode = 0; /* compiler warning (used before set). */ char *bufMode = NULL; char channelName[16 + TCL_INTEGER_SPACE]; int channelPermissions; FileState *fileState; /* * If the channels were not created yet, create them now and * store them in the static variables. */ switch (type) { case TCL_STDIN: fd = 0; channelPermissions = TCL_READABLE; bufMode = "line"; break; case TCL_STDOUT: fd = 1; channelPermissions = TCL_WRITABLE; bufMode = "line"; break; case TCL_STDERR: fd = 2; channelPermissions = TCL_WRITABLE; bufMode = "none"; break; default: panic("TclGetDefaultStdChannel: Unexpected channel type"); break; } sprintf(channelName, "console%d", (int) fd); fileState = (FileState *) ckalloc((unsigned) sizeof(FileState)); channel = Tcl_CreateChannel(&consoleChannelType, channelName, (ClientData) fileState, channelPermissions); fileState->fileChan = channel; fileState->fileRef = fd; /* * Set up the normal channel options for stdio handles. */ Tcl_SetChannelOption(NULL, channel, "-translation", "cr"); Tcl_SetChannelOption(NULL, channel, "-buffering", bufMode); return channel;}/* *---------------------------------------------------------------------- * * TclpOpenFileChannel -- * * Open a File based channel on MacOS systems. * * Results: * The new channel or NULL. If NULL, the output argument * errorCodePtr is set to a POSIX error. * * Side effects: * May open the channel and may cause creation of a file on the * file system. * *---------------------------------------------------------------------- */Tcl_ChannelTclpOpenFileChannel( Tcl_Interp *interp, /* Interpreter for error reporting; * can be NULL. */ Tcl_Obj *pathPtr, /* Name of file to open. */ int mode, /* POSIX open mode. */ int permissions) /* If the open involves creating a * file, with what modes to create * it? */{ Tcl_Channel chan; CONST char *native; int errorCode; native = Tcl_FSGetNativePath(pathPtr); if (native == NULL) { return NULL; } chan = OpenFileChannel(native, mode, permissions, &errorCode); if (chan == NULL) { Tcl_SetErrno(errorCode); if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "couldn't open \"", Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), (char *) NULL); } return NULL; } return chan;}/* *---------------------------------------------------------------------- * * OpenFileChannel-- * * Opens a Macintosh file and creates a Tcl channel to control it. * * Results: * A Tcl channel. * * Side effects: * Will open a Macintosh file. * *---------------------------------------------------------------------- */static Tcl_ChannelOpenFileChannel( CONST char *fileName, /* Name of file to open (native). */ int mode, /* Mode for opening file. */ int permissions, /* If the open involves creating a * file, with what modes to create * it? */ int *errorCodePtr) /* Where to store error code. */{ int channelPermissions; Tcl_Channel chan; char macPermision; FSSpec fileSpec; OSErr err; short fileRef; FileState *fileState; char channelName[16 + TCL_INTEGER_SPACE]; ThreadSpecificData *tsdPtr; tsdPtr = FileInit(); /* * Note we use fsRdWrShPerm instead of fsRdWrPerm which allows shared * writes on a file. This isn't common on a mac but is common with * Windows and UNIX and the feature is used by Tcl. */ switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) { case O_RDWR: channelPermissions = (TCL_READABLE | TCL_WRITABLE); macPermision = fsRdWrShPerm; break; case O_WRONLY: /* * Mac's fsRdPerm permission actually defaults to fsRdWrPerm because * the Mac OS doesn't realy support write only access. We explicitly * set the permission fsRdWrShPerm so that we can have shared write * access. */ channelPermissions = TCL_WRITABLE; macPermision = fsRdWrShPerm; break; case O_RDONLY: default: channelPermissions = TCL_READABLE; macPermision = fsRdPerm; break; } err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec); if ((err != noErr) && (err != fnfErr)) { *errorCodePtr = errno = TclMacOSErrorToPosixError(err); Tcl_SetErrno(errno); return NULL; } if ((err == fnfErr) && (mode & O_CREAT)) { err = HCreate(fileSpec.vRefNum, fileSpec.parID, fileSpec.name, TCL_FILE_CREATOR, 'TEXT'); if (err != noErr) { *errorCodePtr = errno = TclMacOSErrorToPosixError(err); Tcl_SetErrno(errno); return NULL; } } else if ((mode & O_CREAT) && (mode & O_EXCL)) { *errorCodePtr = errno = EEXIST; Tcl_SetErrno(errno); return NULL; } err = HOpenDF(fileSpec.vRefNum, fileSpec.parID, fileSpec.name, macPermision, &fileRef); if (err != noErr) { *errorCodePtr = errno = TclMacOSErrorToPosixError(err); Tcl_SetErrno(errno); return NULL; } if (mode & O_TRUNC) { SetEOF(fileRef, 0); } sprintf(channelName, "file%d", (int) fileRef); fileState = (FileState *) ckalloc((unsigned) sizeof(FileState));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -