📄 tclmacfile.c
字号:
OSErr err; FSSpec fileSpec; Boolean isDirectory; long dirID; int full_mode = 0; err = FspLLocationFromFsPath(pathPtr, &fileSpec); if (err != noErr) { errno = TclMacOSErrorToPosixError(err); return -1; } /* * Fill the fpb & vpb struct up with info about file or directory. */ FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum; vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name; if (isDirectory) { fpb.ioDirID = fileSpec.parID; } else { fpb.ioDirID = dirID; } fpb.ioFDirIndex = 0; err = PBGetCatInfoSync((CInfoPBPtr)&fpb); if (err == noErr) { vpb.ioVolIndex = 0; err = PBHGetVInfoSync((HParmBlkPtr)&vpb); if (err == noErr) { /* * Use the Volume Info & File Info to determine * access information. If we have got this far * we know the directory is searchable or the file * exists. (We have F_OK) */ /* * Check to see if the volume is hardware or * software locked. If so we arn't W_OK. */ if (mode & W_OK) { if ((vpb.ioVAtrb & 0x0080) || (vpb.ioVAtrb & 0x8000)) { errno = EROFS; return -1; } if (fpb.ioFlAttrib & 0x01) { errno = EACCES; return -1; } } /* * Directories are always searchable and executable. But only * files of type 'APPL' are executable. */ if (!(fpb.ioFlAttrib & 0x10) && (mode & X_OK) && (fpb.ioFlFndrInfo.fdType != 'APPL')) { return -1; } } } if (err != noErr) { errno = TclMacOSErrorToPosixError(err); return -1; } return 0;}/* *---------------------------------------------------------------------- * * TclpObjChdir -- * * This function replaces the library version of chdir(). * * Results: * See chdir() documentation. * * Side effects: * See chdir() documentation. Also the cache maintained used by * Tcl_FSGetCwd() is deallocated and set to NULL. * *---------------------------------------------------------------------- */int TclpObjChdir(pathPtr) Tcl_Obj *pathPtr;{ FSSpec spec; OSErr err; Boolean isFolder; long dirID; err = FspLocationFromFsPath(pathPtr, &spec); if (err != noErr) { errno = ENOENT; return -1; } err = FSpGetDirectoryID(&spec, &dirID, &isFolder); if (err != noErr) { errno = ENOENT; return -1; } if (isFolder != true) { errno = ENOTDIR; return -1; } err = FSpSetDefaultDir(&spec); if (err != noErr) { switch (err) { case afpAccessDenied: errno = EACCES; break; default: errno = ENOENT; } return -1; } return 0;}/* *---------------------------------------------------------------------- * * TclpObjGetCwd -- * * This function replaces the library version of getcwd(). * * Results: * The result is a pointer to a string specifying the current * directory, or NULL if the current directory could not be * determined. If NULL is returned, an error message is left in the * interp's result. Storage for the result string is allocated in * bufferPtr; the caller must call Tcl_DStringFree() when the result * is no longer needed. * * Side effects: * None. * *---------------------------------------------------------------------- */Tcl_Obj* TclpObjGetCwd(interp) Tcl_Interp *interp;{ Tcl_DString ds; if (TclpGetCwd(interp, &ds) != NULL) { Tcl_Obj *cwdPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); Tcl_IncrRefCount(cwdPtr); Tcl_DStringFree(&ds); return cwdPtr; } else { return NULL; }}CONST char *TclpGetCwd( Tcl_Interp *interp, /* If non-NULL, used for error reporting. */ Tcl_DString *bufferPtr) /* Uninitialized or free DString filled * with name of current directory. */{ FSSpec theSpec; int length; Handle pathHandle = NULL; if (FSpGetDefaultDir(&theSpec) != noErr) { if (interp != NULL) { Tcl_SetResult(interp, "error getting working directory name", TCL_STATIC); } return NULL; } if (FSpPathFromLocation(&theSpec, &length, &pathHandle) != noErr) { if (interp != NULL) { Tcl_SetResult(interp, "error getting working directory name", TCL_STATIC); } return NULL; } HLock(pathHandle); Tcl_ExternalToUtfDString(NULL, *pathHandle, length, bufferPtr); HUnlock(pathHandle); DisposeHandle(pathHandle); return Tcl_DStringValue(bufferPtr);}/* *---------------------------------------------------------------------- * * TclpReadlink -- * * This function replaces the library version of readlink(). * * Results: * The result is a pointer to a string specifying the contents * of the symbolic link given by 'path', or NULL if the symbolic * link could not be read. Storage for the result string is * allocated in bufferPtr; the caller must call Tcl_DStringFree() * when the result is no longer needed. * * Side effects: * See readlink() documentation. * *--------------------------------------------------------------------------- */char *TclpReadlink( CONST char *path, /* Path of file to readlink (UTF-8). */ Tcl_DString *linkPtr) /* Uninitialized or free DString filled * with contents of link (UTF-8). */{ HFileInfo fpb; OSErr err; FSSpec fileSpec; Boolean isDirectory; Boolean wasAlias; long dirID; char fileName[257]; char *end; Handle theString = NULL; int pathSize; Tcl_DString ds; Tcl_UtfToExternalDString(NULL, path, -1, &ds); /* * Remove ending colons if they exist. */ while ((Tcl_DStringLength(&ds) != 0) && (Tcl_DStringValue(&ds)[Tcl_DStringLength(&ds) - 1] == ':')) { Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) - 1); } end = strrchr(Tcl_DStringValue(&ds), ':'); if (end == NULL ) { strcpy(fileName + 1, Tcl_DStringValue(&ds)); } else { strcpy(fileName + 1, end + 1); Tcl_DStringSetLength(&ds, end + 1 - Tcl_DStringValue(&ds)); } fileName[0] = (char) strlen(fileName + 1); /* * Create the file spec for the directory of the file * we want to look at. */ if (end != NULL) { err = FSpLocationFromPath(Tcl_DStringLength(&ds), Tcl_DStringValue(&ds), &fileSpec); if (err != noErr) { Tcl_DStringFree(&ds); errno = EINVAL; return NULL; } } else { FSMakeFSSpecCompat(0, 0, NULL, &fileSpec); } Tcl_DStringFree(&ds); /* * Fill the fpb struct up with info about file or directory. */ FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); fpb.ioVRefNum = fileSpec.vRefNum; fpb.ioDirID = dirID; fpb.ioNamePtr = (StringPtr) fileName; fpb.ioFDirIndex = 0; err = PBGetCatInfoSync((CInfoPBPtr)&fpb); if (err != noErr) { errno = TclMacOSErrorToPosixError(err); return NULL; } else { if (fpb.ioFlAttrib & 0x10) { errno = EINVAL; return NULL; } else { if (fpb.ioFlFndrInfo.fdFlags & 0x8000) { /* * The file is a link! */ } else { errno = EINVAL; return NULL; } } } /* * If we are here it's really a link - now find out * where it points to. */ err = FSMakeFSSpecCompat(fileSpec.vRefNum, dirID, (StringPtr) fileName, &fileSpec); if (err == noErr) { err = ResolveAliasFile(&fileSpec, true, &isDirectory, &wasAlias); } if ((err == fnfErr) || wasAlias) { err = FSpPathFromLocation(&fileSpec, &pathSize, &theString); if (err != noErr) { DisposeHandle(theString); errno = ENAMETOOLONG; return NULL; } } else { errno = EINVAL; return NULL; } Tcl_ExternalToUtfDString(NULL, *theString, pathSize, linkPtr); DisposeHandle(theString); return Tcl_DStringValue(linkPtr);}static int TclpObjStatAlias _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *bufPtr, Boolean resolveLink));/* *---------------------------------------------------------------------- * * TclpObjLstat -- * * This function replaces the library version of lstat(). * * Results: * See lstat() documentation. * * Side effects: * See lstat() documentation. * *---------------------------------------------------------------------- */int TclpObjLstat(pathPtr, buf) Tcl_Obj *pathPtr; Tcl_StatBuf *buf;{ return TclpObjStatAlias(pathPtr, buf, FALSE);}/* *---------------------------------------------------------------------- * * TclpObjStat -- * * This function replaces the library version of stat(). * * Results: * See stat() documentation. * * Side effects: * See stat() documentation. * *---------------------------------------------------------------------- */int TclpObjStat(pathPtr, bufPtr) Tcl_Obj *pathPtr; Tcl_StatBuf *bufPtr;{ return TclpObjStatAlias(pathPtr, bufPtr, TRUE);}static intTclpObjStatAlias (Tcl_Obj *pathPtr, Tcl_StatBuf *bufPtr, Boolean resolveLink){ HFileInfo fpb; HVolumeParam vpb; OSErr err; FSSpec fileSpec; Boolean isDirectory; long dirID; if (resolveLink) err = FspLocationFromFsPath(pathPtr, &fileSpec); else err = FspLLocationFromFsPath(pathPtr, &fileSpec); if (err != noErr) { errno = TclMacOSErrorToPosixError(err); return -1; } /* * Fill the fpb & vpb struct up with info about file or directory. */ FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum; vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name; if (isDirectory) { fpb.ioDirID = fileSpec.parID; } else { fpb.ioDirID = dirID; } fpb.ioFDirIndex = 0; err = PBGetCatInfoSync((CInfoPBPtr)&fpb); if (err == noErr) { vpb.ioVolIndex = 0; err = PBHGetVInfoSync((HParmBlkPtr)&vpb); if (err == noErr && bufPtr != NULL) { /* * Files are always readable by everyone. */ bufPtr->st_mode = S_IRUSR | S_IRGRP | S_IROTH; /* * Use the Volume Info & File Info to fill out stat buf. */ if (fpb.ioFlAttrib & 0x10) { bufPtr->st_mode |= S_IFDIR; bufPtr->st_nlink = 2; } else { bufPtr->st_nlink = 1; if (fpb.ioFlFndrInfo.fdFlags & 0x8000) { bufPtr->st_mode |= S_IFLNK; } else { bufPtr->st_mode |= S_IFREG; } } if ((fpb.ioFlAttrib & 0x10) || (fpb.ioFlFndrInfo.fdType == 'APPL')) { /* * Directories and applications are executable by everyone. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -