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

📄 tclmacfcmd.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
    Boolean srcIsDirectory, srcLocked;    Boolean dstIsDirectory, dstExists;    Str31 tmpName;    err = FSpLocationFromPath(strlen(src), src, &srcFileSpec);    if (err == noErr) {    	err = FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory);    }    if (err == noErr) {        if (srcIsDirectory == false) {            err = afpObjectTypeErr;	/* ENOTDIR. */        }    }    if (err == noErr) {        err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists,        	&dstIsDirectory);    }    if (dstExists) {        if (dstIsDirectory == false) {            err = afpObjectTypeErr;	/* ENOTDIR. */        } else {            err = dupFNErr;		/* EEXIST. */        }    }    if (err != noErr) {        goto done;    }            if ((srcFileSpec.vRefNum == dstFileSpec.vRefNum) &&    	    (srcFileSpec.parID == dstFileSpec.parID) &&            (Pstrequal(srcFileSpec.name, dstFileSpec.name) != 0)) {        /*         * Copying on top of self.  No-op.         */                            goto done;    }    /*     * This algorthm will work making a copy of the source directory in     * the current directory with a new name, in a new directory with the     * same name, and in a new directory with a new name:     *     * 1. Make dstDir/tmpDir.     * 2. Copy srcDir/src to dstDir/tmpDir/src     * 3. Rename dstDir/tmpDir/src to dstDir/tmpDir/dst (if necessary).     * 4. CatMove dstDir/tmpDir/dst to dstDir/dst.     * 5. Remove dstDir/tmpDir.     */                    err = FSpGetFLockCompat(&srcFileSpec, &srcLocked);    if (srcLocked) {        FSpRstFLockCompat(&srcFileSpec);    }    if (err == noErr) {        err = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID,     	        dstFileSpec.parID, tmpName);    }    if (err == noErr) {        FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID,        	tmpName, &tmpDirSpec);        err = FSpDirCreateCompat(&tmpDirSpec, smSystemScript, &tmpDirID);    }    if (err == noErr) {	err = FSpDirectoryCopy(&srcFileSpec, &tmpDirSpec, NULL, 0, true,	    	CopyErrHandler);    }        /*      * Even if the Copy failed, Rename/Move whatever did get copied to the     * appropriate final destination, if possible.       */         saveErr = err;    err = noErr;    if (Pstrequal(srcFileSpec.name, dstFileSpec.name) == 0) {        err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID,         	srcFileSpec.name, &tmpFileSpec);        if (err == noErr) {            err = FSpRenameCompat(&tmpFileSpec, dstFileSpec.name);        }    }    if (err == noErr) {        err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID,        	dstFileSpec.name, &tmpFileSpec);    }    if (err == noErr) {        err = FSpCatMoveCompat(&tmpFileSpec, &dstDirSpec);    }    if (err == noErr) {        if (srcLocked) {            FSpSetFLockCompat(&dstFileSpec);        }    }        FSpDeleteCompat(&tmpDirSpec);        if (saveErr != noErr) {        err = saveErr;    }        done:    if (err != noErr) {        errno = TclMacOSErrorToPosixError(err);        if (errorPtr != NULL) {            Tcl_DStringAppend(errorPtr, dst, -1);        }        return TCL_ERROR;    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * CopyErrHandler -- * *      This procedure is called from the MoreFiles procedure  *      FSpDirectoryCopy whenever an error occurs. * * Results: *      False if the condition should not be considered an error, true *      otherwise. * * Side effects: *      Since FSpDirectoryCopy() is called only after removing any  *      existing target directories, there shouldn't be any errors. *       *---------------------------------------------------------------------- */static pascal Boolean CopyErrHandler(    OSErr error,		/* Error that occured */    short failedOperation,	/* operation that caused the error */    short srcVRefNum,		/* volume ref number of source */    long srcDirID,		/* directory id of source */    StringPtr srcName,		/* name of source */    short dstVRefNum,		/* volume ref number of dst */    long dstDirID,		/* directory id of dst */    StringPtr dstName)		/* name of dst directory */{    return true;}/* *--------------------------------------------------------------------------- * * TclpRemoveDirectory -- * *	Removes directory (and its contents, if the recursive flag is set). * * Results: *	If the directory was successfully removed, returns TCL_OK. *	Otherwise the return value is TCL_ERROR, errno is set to indicate *	the error, and the pathname of the file that caused the error *	is stored in errorPtr.  Some possible values for errno are: * *	EACCES:     path directory can't be read and/or written. *	EEXIST:	    path is a non-empty directory. *	EINVAL:	    path is a root directory. *	ENOENT:	    path doesn't exist or is "". * 	ENOTDIR:    path is not a directory. * * Side effects: *	Directory removed.  If an error occurs, the error will be returned *	immediately, and remaining files will not be deleted. * *--------------------------------------------------------------------------- */ intTclpRemoveDirectory(    char *path,			/* Pathname of directory to be removed. */    int recursive,		/* If non-zero, removes directories that				 * are nonempty.  Otherwise, will only remove				 * empty directories. */    Tcl_DString *errorPtr)	/* If non-NULL, initialized DString for				 * error reporting. */{				     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_DStringAppend(errorPtr, path, -1);	}        if (locked) {            FSpSetFLockCompat(&fileSpec);        }    	errno = TclMacOSErrorToPosixError(err);    	return TCL_ERROR;    }    return TCL_OK;}/* *-------------------------------------------------------------------------- * * MoveRename -- * *	Helper function for TclpRenameFile.  Renames a file or directory *	into the same directory or another directory.  The target name * 	must not already exist in the destination directory. * *	Don't use FSpMoveRenameCompat because it doesn't work with *	directories or with locked files.  * * Results: *	Returns a mac error indicating the cause of the failure. * * Side effects: *	Creates a temp file in the target directory to handle a rename *	between directories. * *-------------------------------------------------------------------------- */  static OSErr		MoveRename(    const FSSpec *srcFileSpecPtr,   /* Source object. */    const FSSpec *dstDirSpecPtr,    /* Destination directory. */    StringPtr copyName)		    /* New name for object in destination     				     * directory. */{    OSErr err;    long srcID, dstID;    Boolean srcIsDir, dstIsDir;    Str31 tmpName;    FSSpec dstFileSpec, srcDirSpec, tmpSrcFileSpec, tmpDstFileSpec;    Boolean locked;        if (srcFileSpecPtr->parID == 1) {        /*         * Trying to rename a volume.         */                  return badMovErr;    }    if (srcFileSpecPtr->vRefNum != dstDirSpecPtr->vRefNum) {	/*	 * Renaming across volumes.	 */	         return diffVolErr;    }    err = FSpGetFLockCompat(srcFileSpecPtr, &locked);    if (locked) {        FSpRstFLockCompat(srcFileSpecPtr);    }    if (err == noErr) {	err = FSpGetDirectoryID(dstDirSpecPtr, &dstID, &dstIsDir);    }    if (err == noErr) {        if (srcFileSpecPtr->parID == dstID) {            /*             * Renaming object within directory.              */                        err = FSpRenameCompat(srcFileSpecPtr, copyName);            goto done;         }        if (Pstrequal(srcFileSpecPtr->name, copyName)) {	    /*	     * Moving object to another directory (under same name). 	     */	 	    err = FSpCatMoveCompat(srcFileSpecPtr, dstDirSpecPtr);	    goto done;         }         err = FSpGetDirectoryID(srcFileSpecPtr, &srcID, &srcIsDir);    }     if (err == noErr) {        /*         * Fullblown: rename source object to temp name, move temp to         * dest directory, and rename temp to target.         */                  err = GenerateUniqueName(srcFileSpecPtr->vRefNum,        		srcFileSpecPtr->parID, dstID, tmpName);        FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID,         	tmpName, &tmpSrcFileSpec);        FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, dstID, tmpName,         	&tmpDstFileSpec);    }    if (err == noErr) {        err = FSpRenameCompat(srcFileSpecPtr, tmpName);    }    if (err == noErr) {        err = FSpCatMoveCompat(&tmpSrcFileSpec, dstDirSpecPtr);        if (err == noErr) {            err = FSpRenameCompat(&tmpDstFileSpec, copyName);            if (err == noErr) {                goto done;            }            FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID,             	    NULL, &srcDirSpec);            FSpCatMoveCompat(&tmpDstFileSpec, &srcDirSpec);        }                         FSpRenameCompat(&tmpSrcFileSpec, srcFileSpecPtr->name);    }        done:    if (locked != false) {    	if (err == noErr) {	    FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, 	    	    dstID, copyName, &dstFileSpec);            FSpSetFLockCompat(&dstFileSpec);        } else {            FSpSetFLockCompat(srcFileSpecPtr);        }    }    return err;}     			    /* *--------------------------------------------------------------------------- * * GetFileSpecs -- * * 	Generate a filename that is not in either of the two specified *	directories (on the same volume).  * * Results: *	Standard macintosh error.  On success, uniqueName is filled with  *	the name of the temporary file. * * Side effects: *	None. * *--------------------------------------------------------------------------- */  static OSErrGenerateUniqueName(    short vRefNum,		/* Volume on which the following directories    				 * are located. */		    long dirID1,		/* ID of first directory. */    long dirID2,		/* ID of second directory.  May be the same    				 * as the first. */    Str31 uniqueName)		/* Filled with filename for a file that is    				 * not located in either of the above two    				 * directories. */{    OSErr err;    long i;    CInfoPBRec pb;    static unsigned char hexStr[16] = "0123456789ABCDEF";    static long startSeed = 248923489;        pb.hFileInfo.ioVRefNum = vRefNum;    pb.hFileInfo.ioFDirIndex = 0;    pb.hFileInfo.ioNamePtr = uniqueName;    while (1) {        startSeed++;			pb.hFileInfo.ioNamePtr[0] = 8;	for (i = 1; i <= 8; i++) {	    pb.hFileInfo.ioNamePtr[i] = hexStr[((startSeed >> ((8-i)*4)) & 0xf)];	}	pb.hFileInfo.ioDirID = dirID1;	err = PBGetCatInfoSync(&pb);	if (err == fnfErr) {	    if (dirID1 != dirID2) {		pb.hFileInfo.ioDirID = dirID2;		err = PBGetCatInfoSync(&pb);	    }	    if (err == fnfErr) {	        return noErr;	    }	}	if (err == noErr) {	    continue;	} 	return err;    }} /* *--------------------------------------------------------------------------- * * 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(    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. */{

⌨️ 快捷键说明

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