diff options
Diffstat (limited to 'macosx/tclMacOSXFCmd.c')
-rw-r--r-- | macosx/tclMacOSXFCmd.c | 301 |
1 files changed, 138 insertions, 163 deletions
diff --git a/macosx/tclMacOSXFCmd.c b/macosx/tclMacOSXFCmd.c index 3adc808..dce15fc 100644 --- a/macosx/tclMacOSXFCmd.c +++ b/macosx/tclMacOSXFCmd.c @@ -22,37 +22,26 @@ #ifdef HAVE_COPYFILE #ifdef HAVE_COPYFILE_H #include <copyfile.h> -#if defined(HAVE_WEAK_IMPORT) && (MAC_OS_X_VERSION_MIN_REQUIRED < 1040) +#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040 /* Support for weakly importing copyfile. */ #define WEAK_IMPORT_COPYFILE -extern int copyfile(const char *from, const char *to, - copyfile_state_t state, copyfile_flags_t flags) - WEAK_IMPORT_ATTRIBUTE; +extern int copyfile(const char *from, const char *to, copyfile_state_t state, + copyfile_flags_t flags) WEAK_IMPORT_ATTRIBUTE; #endif /* HAVE_WEAK_IMPORT */ #else /* HAVE_COPYFILE_H */ -int copyfile(const char *from, const char *to, - void *state, uint32_t flags); -#define COPYFILE_ACL (1<<0) -#define COPYFILE_XATTR (1<<2) -#define COPYFILE_NOFOLLOW_SRC (1<<18) -#if defined(HAVE_WEAK_IMPORT) && (MAC_OS_X_VERSION_MIN_REQUIRED < 1040) +int copyfile(const char *from, const char *to, void *state, uint32_t flags); +#define COPYFILE_ACL (1<<0) +#define COPYFILE_XATTR (1<<2) +#define COPYFILE_NOFOLLOW_SRC (1<<18) +#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040 /* Support for weakly importing copyfile. */ #define WEAK_IMPORT_COPYFILE -extern int copyfile(const char *from, const char *to, - void *state, uint32_t flags) - WEAK_IMPORT_ATTRIBUTE; +extern int copyfile(const char *from, const char *to, void *state, + uint32_t flags) WEAK_IMPORT_ATTRIBUTE; #endif /* HAVE_WEAK_IMPORT */ #endif /* HAVE_COPYFILE_H */ #endif /* HAVE_COPYFILE */ -#ifdef WEAK_IMPORT_COPYFILE -#define MayUseCopyFile() (copyfile != NULL) -#elif defined(HAVE_COPYFILE) -#define MayUseCopyFile() (1) -#else -#define MayUseCopyFile() (0) -#endif - #include <libkern/OSByteOrder.h> /* @@ -83,7 +72,7 @@ static Tcl_Obj * NewOSTypeObj(const OSType newOSType); static int SetOSTypeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void UpdateStringOfOSType(Tcl_Obj *objPtr); -static const Tcl_ObjType tclOSTypeType = { +static Tcl_ObjType tclOSTypeType = { "osType", /* name */ NULL, /* freeIntRepProc */ NULL, /* dupIntRepProc */ @@ -92,10 +81,10 @@ static const Tcl_ObjType tclOSTypeType = { }; enum { - kIsInvisible = 0x4000, + kIsInvisible = 0x4000, }; -#define kFinfoIsInvisible (OSSwapHostToBigConstInt16(kIsInvisible)) +#define kFinfoIsInvisible (OSSwapHostToBigConstInt16(kIsInvisible)) typedef struct finderinfo { u_int32_t type; @@ -106,7 +95,7 @@ typedef struct finderinfo { u_int32_t extendedFileInfo[4]; } __attribute__ ((__packed__)) finderinfo; -typedef struct { +typedef struct fileinfobuf { u_int32_t info_length; u_int32_t data[8]; } fileinfobuf; @@ -141,16 +130,15 @@ TclMacOSXGetFileAttribute( Tcl_StatBuf statBuf; struct attrlist alist; fileinfobuf finfo; - finderinfo *finder = (finderinfo *) &finfo.data; - off_t *rsrcForkSize = (off_t *) &finfo.data; + finderinfo *finder = (finderinfo*)(&finfo.data); + off_t *rsrcForkSize = (off_t*)(&finfo.data); const char *native; result = TclpObjStat(fileName, &statBuf); if (result != 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "could not read \"%s\": %s", - TclGetString(fileName), Tcl_PosixError(interp))); + Tcl_AppendResult(interp, "could not read \"", + TclGetString(fileName), "\": ", Tcl_PosixError(interp), NULL); return TCL_ERROR; } @@ -160,8 +148,8 @@ TclMacOSXGetFileAttribute( */ errno = EISDIR; - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "invalid attribute: %s", Tcl_PosixError(interp))); + Tcl_AppendResult(interp, "invalid attribute: ", + Tcl_PosixError(interp), NULL); return TCL_ERROR; } @@ -176,9 +164,8 @@ TclMacOSXGetFileAttribute( result = getattrlist(native, &alist, &finfo, sizeof(fileinfobuf), 0); if (result != 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "could not read attributes of \"%s\": %s", - TclGetString(fileName), Tcl_PosixError(interp))); + Tcl_AppendResult(interp, "could not read attributes of \"", + TclGetString(fileName), "\": ", Tcl_PosixError(interp), NULL); return TCL_ERROR; } @@ -201,11 +188,9 @@ TclMacOSXGetFileAttribute( } return TCL_OK; #else - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "Mac OS X file attributes not supported", -1)); - Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL); + Tcl_AppendResult(interp, "Mac OS X file attributes not supported", NULL); return TCL_ERROR; -#endif /* HAVE_GETATTRLIST */ +#endif } /* @@ -237,16 +222,15 @@ TclMacOSXSetFileAttribute( Tcl_StatBuf statBuf; struct attrlist alist; fileinfobuf finfo; - finderinfo *finder = (finderinfo *) &finfo.data; - off_t *rsrcForkSize = (off_t *) &finfo.data; + finderinfo *finder = (finderinfo*)(&finfo.data); + off_t *rsrcForkSize = (off_t*)(&finfo.data); const char *native; result = TclpObjStat(fileName, &statBuf); if (result != 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "could not read \"%s\": %s", - TclGetString(fileName), Tcl_PosixError(interp))); + Tcl_AppendResult(interp, "could not read \"", + TclGetString(fileName), "\": ", Tcl_PosixError(interp), NULL); return TCL_ERROR; } @@ -256,8 +240,8 @@ TclMacOSXSetFileAttribute( */ errno = EISDIR; - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "invalid attribute: %s", Tcl_PosixError(interp))); + Tcl_AppendResult(interp, "invalid attribute: ", + Tcl_PosixError(interp), NULL); return TCL_ERROR; } @@ -272,9 +256,8 @@ TclMacOSXSetFileAttribute( result = getattrlist(native, &alist, &finfo, sizeof(fileinfobuf), 0); if (result != 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "could not read attributes of \"%s\": %s", - TclGetString(fileName), Tcl_PosixError(interp))); + Tcl_AppendResult(interp, "could not read attributes of \"", + TclGetString(fileName), "\": ", Tcl_PosixError(interp), NULL); return TCL_ERROR; } @@ -311,15 +294,15 @@ TclMacOSXSetFileAttribute( &finfo.data, sizeof(finfo.data), 0); if (result != 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "could not set attributes of \"%s\": %s", - TclGetString(fileName), Tcl_PosixError(interp))); + Tcl_AppendResult(interp, "could not set attributes of \"", + TclGetString(fileName), "\": ", + Tcl_PosixError(interp), NULL); return TCL_ERROR; } } else { Tcl_WideInt newRsrcForkSize; - if (TclGetWideIntFromObj(interp, attributePtr, + if (Tcl_GetWideIntFromObj(interp, attributePtr, &newRsrcForkSize) != TCL_OK) { return TCL_ERROR; } @@ -332,10 +315,9 @@ TclMacOSXSetFileAttribute( * supported. */ - if (newRsrcForkSize != 0) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "setting nonzero rsrclength not supported", -1)); - Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL); + if(newRsrcForkSize != 0) { + Tcl_AppendResult(interp, + "setting nonzero rsrclength not supported", NULL); return TCL_ERROR; } @@ -350,13 +332,11 @@ TclMacOSXSetFileAttribute( result = truncate(Tcl_DStringValue(&ds), (off_t)0); if (result != 0) { /* - * truncate() on a valid resource fork path may fail with a - * permission error in some OS releases, try truncating with - * open() instead: + * truncate() on a valid resource fork path may fail with + * a permission error in some OS releases, try truncating + * with open() instead: */ - int fd = open(Tcl_DStringValue(&ds), O_WRONLY | O_TRUNC); - if (fd > 0) { result = close(fd); } @@ -365,18 +345,17 @@ TclMacOSXSetFileAttribute( Tcl_DStringFree(&ds); if (result != 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "could not truncate resource fork of \"%s\": %s", - TclGetString(fileName), Tcl_PosixError(interp))); + Tcl_AppendResult(interp, + "could not truncate resource fork of \"", + TclGetString(fileName), "\": ", + Tcl_PosixError(interp), NULL); return TCL_ERROR; } } } return TCL_OK; #else - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "Mac OS X file attributes not supported", -1)); - Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL); + Tcl_AppendResult(interp, "Mac OS X file attributes not supported", NULL); return TCL_ERROR; #endif } @@ -401,84 +380,89 @@ TclMacOSXSetFileAttribute( int TclMacOSXCopyFileAttributes( - const char *src, /* Path name of source file (native). */ - const char *dst, /* Path name of target file (native). */ - const Tcl_StatBuf *statBufPtr) + CONST char *src, /* Path name of source file (native). */ + CONST char *dst, /* Path name of target file (native). */ + CONST Tcl_StatBuf *statBufPtr) /* Stat info for source file */ { - if (MayUseCopyFile()) { +#ifdef WEAK_IMPORT_COPYFILE + if (copyfile != NULL) { +#endif #ifdef HAVE_COPYFILE - if (0 == copyfile(src, dst, NULL, (S_ISLNK(statBufPtr->st_mode) - ? COPYFILE_XATTR | COPYFILE_NOFOLLOW_SRC - : COPYFILE_XATTR | COPYFILE_ACL))) { - return TCL_OK; - } + if (copyfile(src, dst, NULL, COPYFILE_XATTR | + (S_ISLNK(statBufPtr->st_mode) ? COPYFILE_NOFOLLOW_SRC : + COPYFILE_ACL)) < 0) { + return TCL_ERROR; + } + return TCL_OK; #endif /* HAVE_COPYFILE */ +#ifdef WEAK_IMPORT_COPYFILE } else { -#if (!defined(HAVE_COPYFILE) || defined(WEAK_IMPORT_COPYFILE)) && defined(HAVE_GETATTRLIST) - struct attrlist alist; - fileinfobuf finfo; - off_t *rsrcForkSize = (off_t *) &finfo.data; - Tcl_DString srcBuf, dstBuf; - int result; - - bzero(&alist, sizeof(struct attrlist)); - alist.bitmapcount = ATTR_BIT_MAP_COUNT; - alist.commonattr = ATTR_CMN_FNDRINFO; +#endif +#if !defined(HAVE_COPYFILE) || defined(WEAK_IMPORT_COPYFILE) +#ifdef HAVE_GETATTRLIST + struct attrlist alist; + fileinfobuf finfo; + off_t *rsrcForkSize = (off_t*)(&finfo.data); - if (getattrlist(src, &alist, &finfo, sizeof(fileinfobuf), 0)) { - return TCL_ERROR; - } - if (setattrlist(dst, &alist, &finfo.data, sizeof(finfo.data), 0)) { - return TCL_ERROR; - } + bzero(&alist, sizeof(struct attrlist)); + alist.bitmapcount = ATTR_BIT_MAP_COUNT; + alist.commonattr = ATTR_CMN_FNDRINFO; - /* - * If we're a directory, we're done as they never have resource forks. - */ + if (getattrlist(src, &alist, &finfo, sizeof(fileinfobuf), 0)) { + return TCL_ERROR; + } - if (S_ISDIR(statBufPtr->st_mode)) { - return TCL_OK; - } + if (setattrlist(dst, &alist, &finfo.data, sizeof(finfo.data), 0)) { + return TCL_ERROR; + } + if (!S_ISDIR(statBufPtr->st_mode)) { /* - * We only copy a non-empty resource fork, so determine if that's the - * case first. + * Only copy non-empty resource fork. */ alist.commonattr = 0; alist.fileattr = ATTR_FILE_RSRCLENGTH; + if (getattrlist(src, &alist, &finfo, sizeof(fileinfobuf), 0)) { return TCL_ERROR; - } else if (*rsrcForkSize == 0) { - return TCL_OK; } - /* - * Construct paths to resource forks. - */ + if(*rsrcForkSize > 0) { + int result; + Tcl_DString ds_src, ds_dst; - Tcl_DStringInit(&srcBuf); - Tcl_DStringAppend(&srcBuf, src, -1); - Tcl_DStringAppend(&srcBuf, _PATH_RSRCFORKSPEC, -1); - Tcl_DStringInit(&dstBuf); - Tcl_DStringAppend(&dstBuf, dst, -1); - Tcl_DStringAppend(&dstBuf, _PATH_RSRCFORKSPEC, -1); + /* + * Construct paths to resource forks. + */ - /* - * Do the copy. - */ + Tcl_DStringInit(&ds_src); + Tcl_DStringAppend(&ds_src, src, -1); + Tcl_DStringAppend(&ds_src, _PATH_RSRCFORKSPEC, -1); + Tcl_DStringInit(&ds_dst); + Tcl_DStringAppend(&ds_dst, dst, -1); + Tcl_DStringAppend(&ds_dst, _PATH_RSRCFORKSPEC, -1); - result = TclUnixCopyFile(Tcl_DStringValue(&srcBuf), - Tcl_DStringValue(&dstBuf), statBufPtr, 1); - Tcl_DStringFree(&srcBuf); - Tcl_DStringFree(&dstBuf); - if (result == 0) { - return TCL_OK; + result = TclUnixCopyFile(Tcl_DStringValue(&ds_src), + Tcl_DStringValue(&ds_dst), statBufPtr, 1); + + Tcl_DStringFree(&ds_src); + Tcl_DStringFree(&ds_dst); + + if (result != 0) { + return TCL_ERROR; + } } -#endif /* (!HAVE_COPYFILE || WEAK_IMPORT_COPYFILE) && HAVE_GETATTRLIST */ } + return TCL_OK; +#else return TCL_ERROR; +#endif /* HAVE_GETATTRLIST */ +#endif /* !defined(HAVE_COPYFILE) || defined(WEAK_IMPORT_COPYFILE) */ +#ifdef WEAK_IMPORT_COPYFILE + } +#endif } /* @@ -486,13 +470,13 @@ TclMacOSXCopyFileAttributes( * * TclMacOSXMatchType -- * - * This routine is used by the globbing code to check if a file matches a - * given mac type and/or creator code. + * This routine is used by the globbing code to check if a file + * matches a given mac type and/or creator code. * * Results: - * The return value is 1, 0 or -1 indicating whether the file matches the - * given criteria, does not match them, or an error occurred (in wich - * case an error is left in interp). + * The return value is 1, 0 or -1 indicating whether the file + * matches the given criteria, does not match them, or an error + * occurred (in wich case an error is left in interp). * * Side effects: * None. @@ -502,16 +486,16 @@ TclMacOSXCopyFileAttributes( int TclMacOSXMatchType( - Tcl_Interp *interp, /* Interpreter to receive errors. */ - const char *pathName, /* Native path to check. */ - const char *fileName, /* Native filename to check. */ - Tcl_StatBuf *statBufPtr, /* Stat info for file to check */ - Tcl_GlobTypeData *types) /* Type description to match against. */ + Tcl_Interp *interp, /* Interpreter to receive errors. */ + CONST char *pathName, /* Native path to check. */ + CONST char *fileName, /* Native filename to check. */ + Tcl_StatBuf *statBufPtr, /* Stat info for file to check */ + Tcl_GlobTypeData *types) /* Type description to match against. */ { #ifdef HAVE_GETATTRLIST struct attrlist alist; fileinfobuf finfo; - finderinfo *finder = (finderinfo *) &finfo.data; + finderinfo *finder = (finderinfo*)(&finfo.data); OSType osType; bzero(&alist, sizeof(struct attrlist)); @@ -524,12 +508,8 @@ TclMacOSXMatchType( !((finder->fdFlags & kFinfoIsInvisible) || (*fileName == '.'))) { return 0; } - if (S_ISDIR(statBufPtr->st_mode) - && (types->macType || types->macCreator)) { - /* - * Directories don't support types or creators. - */ - + if (S_ISDIR(statBufPtr->st_mode) && (types->macType || types->macCreator)) { + /* Directories don't support types or creators */ return 0; } if (types->macType) { @@ -578,8 +558,8 @@ GetOSTypeFromObj( int result = TCL_OK; if (objPtr->typePtr != &tclOSTypeType) { - result = SetOSTypeFromAny(interp, objPtr); - } + result = tclOSTypeType.setFromAnyProc(interp, objPtr); + }; *osTypePtr = (OSType) objPtr->internalRep.longValue; return result; } @@ -602,8 +582,7 @@ GetOSTypeFromObj( static Tcl_Obj * NewOSTypeObj( - const OSType osType) /* OSType used to initialize the new - * object. */ + const OSType osType) /* OSType used to initialize the new object. */ { Tcl_Obj *objPtr; @@ -635,30 +614,29 @@ SetOSTypeFromAny( Tcl_Interp *interp, /* Tcl interpreter */ Tcl_Obj *objPtr) /* Pointer to the object to convert */ { - const char *string; - int result = TCL_OK; + char *string; + int length, result = TCL_OK; Tcl_DString ds; Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman"); - string = TclGetString(objPtr); - Tcl_UtfToExternalDString(encoding, string, objPtr->length, &ds); + string = Tcl_GetStringFromObj(objPtr, &length); + Tcl_UtfToExternalDString(encoding, string, length, &ds); if (Tcl_DStringLength(&ds) > 4) { if (interp) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "expected Macintosh OS type but got \"%s\": ", string)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "MAC_OSTYPE", NULL); + Tcl_AppendResult(interp, "expected Macintosh OS type but got \"", + string, "\": ", NULL); } result = TCL_ERROR; } else { OSType osType; - char bytes[4] = {'\0','\0','\0','\0'}; - - memcpy(bytes, Tcl_DStringValue(&ds), (size_t)Tcl_DStringLength(&ds)); - osType = (OSType) bytes[0] << 24 | - (OSType) bytes[1] << 16 | - (OSType) bytes[2] << 8 | - (OSType) bytes[3]; + char string[4] = {'\0','\0','\0','\0'}; + memcpy(string, Tcl_DStringValue(&ds), + (size_t) Tcl_DStringLength(&ds)); + osType = (OSType) string[0] << 24 | + (OSType) string[1] << 16 | + (OSType) string[2] << 8 | + (OSType) string[3]; TclFreeIntRep(objPtr); objPtr->internalRep.longValue = (long) osType; objPtr->typePtr = &tclOSTypeType; @@ -689,14 +667,12 @@ SetOSTypeFromAny( static void UpdateStringOfOSType( - register Tcl_Obj *objPtr) /* OSType object whose string rep to - * update. */ + register Tcl_Obj *objPtr) /* OSType object whose string rep to update. */ { char string[5]; OSType osType = (OSType) objPtr->internalRep.longValue; Tcl_DString ds; Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman"); - unsigned len; string[0] = (char) (osType >> 24); string[1] = (char) (osType >> 16); @@ -704,9 +680,8 @@ UpdateStringOfOSType( string[3] = (char) (osType); string[4] = '\0'; Tcl_ExternalToUtfDString(encoding, string, -1, &ds); - len = (unsigned) Tcl_DStringLength(&ds) + 1; - objPtr->bytes = ckalloc(len); - memcpy(objPtr->bytes, Tcl_DStringValue(&ds), len); + objPtr->bytes = ckalloc((unsigned) Tcl_DStringLength(&ds) + 1); + strcpy(objPtr->bytes, Tcl_DStringValue(&ds)); objPtr->length = Tcl_DStringLength(&ds); Tcl_DStringFree(&ds); Tcl_FreeEncoding(encoding); |