📄 tclmacfcmd.c
字号:
TclpObjRemoveDirectory(pathPtr, recursive, errorPtr) Tcl_Obj *pathPtr; int recursive; Tcl_Obj **errorPtr;{ Tcl_DString ds; int ret; ret = DoRemoveDirectory(Tcl_FSGetNativePath(pathPtr),recursive, &ds); if (ret != TCL_OK) { *errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); Tcl_DStringFree(&ds); Tcl_IncrRefCount(*errorPtr); } return ret;}static intDoRemoveDirectory( CONST char *path, /* Pathname of directory to be removed * (native). */ int recursive, /* If non-zero, removes directories that * are nonempty. Otherwise, will only remove * empty directories. */ Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free * DString filled with UTF-8 name of file * causing error. */{ OSErr err; FSSpec fileSpec; long dirID; int locked; Boolean isDirectory; CInfoPBRec pb; Str255 fileName; locked = 0; err = FSpLocationFromPath(strlen(path), path, &fileSpec); if (err != noErr) { goto done; } /* * Since FSpDeleteCompat will delete a file, make sure this isn't * a file first. */ isDirectory = 1; FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); if (isDirectory == 0) { errno = ENOTDIR; return TCL_ERROR; } err = FSpDeleteCompat(&fileSpec); if (err == fLckdErr) { locked = 1; FSpRstFLockCompat(&fileSpec); err = FSpDeleteCompat(&fileSpec); } if (err == noErr) { return TCL_OK; } if (err != fBsyErr) { goto done; } if (recursive == 0) { /* * fBsyErr means one of three things: file busy, directory not empty, * or working directory control block open. Determine if directory * is empty. If directory is not empty, return EEXIST. */ pb.hFileInfo.ioVRefNum = fileSpec.vRefNum; pb.hFileInfo.ioDirID = dirID; pb.hFileInfo.ioNamePtr = (StringPtr) fileName; pb.hFileInfo.ioFDirIndex = 1; if (PBGetCatInfoSync(&pb) == noErr) { err = dupFNErr; /* EEXIST */ goto done; } } /* * DeleteDirectory removes a directory and all its contents, including * any locked files. There is no interface to get the name of the * file that caused the error, if an error occurs deleting this tree, * unless we rewrite DeleteDirectory ourselves. */ err = DeleteDirectory(fileSpec.vRefNum, dirID, NULL); done: if (err != noErr) { if (errorPtr != NULL) { Tcl_UtfToExternalDString(NULL, path, -1, errorPtr); } if (locked) { FSpSetFLockCompat(&fileSpec); } errno = TclMacOSErrorToPosixError(err); return TCL_ERROR; } return TCL_OK;} /* *--------------------------------------------------------------------------- * * GetFileSpecs -- * * Gets FSSpecs for the specified path and its parent directory. * * Results: * The return value is noErr if there was no error getting FSSpecs, * otherwise it is an error describing the problem. Fills buffers * with information, as above. * * Side effects: * None. * *--------------------------------------------------------------------------- */static OSErrGetFileSpecs( CONST char *path, /* The path to query. */ FSSpec *pathSpecPtr, /* Filled with information about path. */ FSSpec *dirSpecPtr, /* Filled with information about path's * parent directory. */ Boolean *pathExistsPtr, /* Set to true if path actually exists, * false if it doesn't or there was an * error reading the specified path. */ Boolean *pathIsDirectoryPtr)/* Set to true if path is itself a directory, * otherwise false. */{ CONST char *dirName; OSErr err; int argc; CONST char **argv; long d; Tcl_DString buffer; *pathExistsPtr = false; *pathIsDirectoryPtr = false; Tcl_DStringInit(&buffer); Tcl_SplitPath(path, &argc, &argv); if (argc == 1) { dirName = ":"; } else { dirName = Tcl_JoinPath(argc - 1, argv, &buffer); } err = FSpLocationFromPath(strlen(dirName), dirName, dirSpecPtr); Tcl_DStringFree(&buffer); ckfree((char *) argv); if (err == noErr) { err = FSpLocationFromPath(strlen(path), path, pathSpecPtr); if (err == noErr) { *pathExistsPtr = true; err = FSpGetDirectoryID(pathSpecPtr, &d, pathIsDirectoryPtr); } else if (err == fnfErr) { err = noErr; } } return err;}/* *------------------------------------------------------------------------- * * FSpGetFLockCompat -- * * Determines if there exists a software lock on the specified * file. The software lock could prevent the file from being * renamed or moved. * * Results: * Standard macintosh error code. * * Side effects: * None. * * *------------------------------------------------------------------------- */ OSErrFSpGetFLockCompat( const FSSpec *specPtr, /* File to query. */ Boolean *lockedPtr) /* Set to true if file is locked, false * if it isn't or there was an error reading * specified file. */{ CInfoPBRec pb; OSErr err; pb.hFileInfo.ioVRefNum = specPtr->vRefNum; pb.hFileInfo.ioDirID = specPtr->parID; pb.hFileInfo.ioNamePtr = (StringPtr) specPtr->name; pb.hFileInfo.ioFDirIndex = 0; err = PBGetCatInfoSync(&pb); if ((err == noErr) && (pb.hFileInfo.ioFlAttrib & 0x01)) { *lockedPtr = true; } else { *lockedPtr = false; } return err;} /* *---------------------------------------------------------------------- * * Pstrequal -- * * Pascal string compare. * * Results: * Returns 1 if strings equal, 0 otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */static int Pstrequal ( ConstStr255Param stringA, /* Pascal string A */ ConstStr255Param stringB) /* Pascal string B */{ int i, len; len = *stringA; for (i = 0; i <= len; i++) { if (*stringA++ != *stringB++) { return 0; } } return 1;} /* *---------------------------------------------------------------------- * * GetFileFinderAttributes -- * * Returns a Tcl_Obj containing the value of a file attribute * which is part of the FInfo record. Which attribute is controlled * by objIndex. * * Results: * Returns a standard TCL error. If the return value is TCL_OK, * the new creator or file type object is put into attributePtrPtr. * The object will have ref count 0. If there is an error, * attributePtrPtr is not touched. * * Side effects: * A new object is allocated if the file is valid. * *---------------------------------------------------------------------- */static intGetFileFinderAttributes( Tcl_Interp *interp, /* The interp to report errors with. */ int objIndex, /* The index of the attribute option. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */{ OSErr err; FSSpec fileSpec; FInfo finfo; CONST char *native; native=Tcl_FSGetNativePath(fileName); err = FSpLLocationFromPath(strlen(native), native, &fileSpec); if (err == noErr) { err = FSpGetFInfo(&fileSpec, &finfo); } if (err == noErr) { switch (objIndex) { case MAC_CREATOR_ATTRIBUTE: *attributePtrPtr = Tcl_NewOSTypeObj(finfo.fdCreator); break; case MAC_HIDDEN_ATTRIBUTE: *attributePtrPtr = Tcl_NewBooleanObj(finfo.fdFlags & kIsInvisible); break; case MAC_TYPE_ATTRIBUTE: *attributePtrPtr = Tcl_NewOSTypeObj(finfo.fdType); break; } } else if (err == fnfErr) { long dirID; Boolean isDirectory = 0; err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); if ((err == noErr) && isDirectory) { if (objIndex == MAC_HIDDEN_ATTRIBUTE) { *attributePtrPtr = Tcl_NewBooleanObj(0); } else { *attributePtrPtr = Tcl_NewOSTypeObj('Fldr'); } } } if (err != noErr) { errno = TclMacOSErrorToPosixError(err); Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not read \"", Tcl_GetString(fileName), "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * GetFileReadOnly -- * * Returns a Tcl_Obj containing a Boolean value indicating whether * or not the file is read-only. The object will have ref count 0. * This procedure just checks the Finder attributes; it does not * check AppleShare sharing attributes. * * Results: * Returns a standard TCL error. If the return value is TCL_OK, * the new creator type object is put into readOnlyPtrPtr. * If there is an error, readOnlyPtrPtr is not touched. * * Side effects: * A new object is allocated if the file is valid. * *---------------------------------------------------------------------- */static intGetFileReadOnly( Tcl_Interp *interp, /* The interp to report errors with. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj **readOnlyPtrPtr) /* A pointer to return the object with. */{ OSErr err; FSSpec fileSpec; CInfoPBRec paramBlock; CONST char *native; native=Tcl_FSGetNativePath(fileName); err = FSpLLocationFromPath(strlen(native), native, &fileSpec); if (err == noErr) { if (err == noErr) { paramBlock.hFileInfo.ioCompletion = NULL; paramBlock.hFileInfo.ioNamePtr = fileSpec.name; paramBlock.hFileInfo.ioVRefNum = fileSpec.vRefNum; paramBlock.hFileInfo.ioFDirIndex = 0; paramBlock.hFileInfo.ioDirID = fileSpec.parID; err = PBGetCatInfo(¶mBlock, 0); if (err == noErr) { /* * For some unknown reason, the Mac does not give * symbols for the bits in the ioFlAttrib field. * 1 -> locked. */ *readOnlyPtrPtr = Tcl_NewBooleanObj( paramBlock.hFileInfo.ioFlAttrib & 1); } } } if (err != noErr) { errno = TclMacOSErrorToPosixError(err); Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not read \"", Tcl_GetString(fileName), "\": ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * SetFileFinderAttributes -- * * Sets the file to the creator or file type given by attributePtr. * objIndex determines whether the creator or file type is set. * * Results: * Returns a standard TCL error. * * Side effects: * The file's attribute is set. * *---------------------------------------------------------------------- */static intSetFileFinderAttributes( Tcl_Interp *interp, /* The interp to report errors with. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj *attributePtr) /* The command line object. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -