Ejemplo n.º 1
0
static CFTypeRef fileCopyProperty(struct _CFStream *stream, CFStringRef propertyName, void *info) {
    
    CFTypeRef result = NULL;
    _CFFileStreamContext *fileStream = (_CFFileStreamContext *)info;

    if (CFEqual(propertyName, kCFStreamPropertyFileCurrentOffset)) {
        
        // NOTE that this does a lseek of 0 from the current location in
        // order to populate the offset field which will then be used to
        // create the resulting value.
        if (!__CFBitIsSet(fileStream->flags, APPEND) && fileStream->fd != -1) {
            fileStream->offset = lseek(fileStream->fd, 0, SEEK_CUR);
        }
        
        if (fileStream->offset != -1) {
            result = CFNumberCreate(CFGetAllocator((CFTypeRef)stream), kCFNumberSInt64Type, &(fileStream->offset));
        }
#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
    } else if (CFEqual(propertyName, _kCFStreamPropertyFileNativeHandle)) {
        int fd = fileStream->fd;
        if (fd != -1) {
            result = CFDataCreate(CFGetAllocator((CFTypeRef) stream), (const uint8_t *)&fd, sizeof(fd));
        }
#endif
    }

    return result;
}
Ejemplo n.º 2
0
static Boolean fileSetProperty(struct _CFStream *stream, CFStringRef prop, CFTypeRef val, void *info) {
    
    Boolean result = FALSE;
    _CFFileStreamContext *fileStream = (_CFFileStreamContext *)info;

    if (CFEqual(prop, kCFStreamPropertyAppendToFile) && CFGetTypeID(stream) == CFWriteStreamGetTypeID() &&
        CFWriteStreamGetStatus((CFWriteStreamRef)stream) == kCFStreamStatusNotOpen)
    {
        if (val == kCFBooleanTrue) {
            __CFBitSet(fileStream->flags, APPEND);
            fileStream->offset = -1;                // Can't offset and append on the stream
        } else {
            __CFBitClear(fileStream->flags, APPEND);
        }
        result = TRUE;
    }
    
    else if (CFEqual(prop, kCFStreamPropertyFileCurrentOffset)) {
        
        if (!__CFBitIsSet(fileStream->flags, APPEND))
        {
            result = CFNumberGetValue((CFNumberRef)val, kCFNumberSInt64Type, &(fileStream->offset));
        }
        
        if ((fileStream->fd != -1) && (lseek(fileStream->fd, fileStream->offset, SEEK_SET) == -1)) {
            result = FALSE;
        }
    }
    
    return result;
}
Ejemplo n.º 3
0
static CFIndex fileRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLength, CFStreamError *errorCode, Boolean *atEOF, void *info) {
    _CFFileStreamContext *ctxt = (_CFFileStreamContext *)info;
    CFIndex result;
    result = fdRead(ctxt->fd, buffer, bufferLength, errorCode, atEOF);
#ifdef REAL_FILE_SCHEDULING
    if (__CFBitIsSet(ctxt->flags, SCHEDULE_AFTER_READ)) {
        __CFBitClear(ctxt->flags, SCHEDULE_AFTER_READ);
        if (!*atEOF && ctxt->rlInfo.cffd) {
            struct stat statbuf;
            int ret = fstat(ctxt->fd, &statbuf);
            if (0 <= ret && (S_IFREG == (statbuf.st_mode & S_IFMT))) {
                off_t offset = lseek(ctxt->fd, 0, SEEK_CUR);
                if (statbuf.st_size == offset) {
                    _CFFileDescriptorInduceFakeReadCallBack(ctxt->rlInfo.cffd);
                }
            }
        }
        if (ctxt->rlInfo.cffd) {
            CFFileDescriptorEnableCallBacks(ctxt->rlInfo.cffd, kCFFileDescriptorReadCallBack);
        }
    }
#else
    if (*atEOF)
        __CFBitSet(ctxt->flags, AT_EOF);
    if (ctxt->scheduled > 0 && !*atEOF) {
        CFReadStreamSignalEvent(stream, kCFStreamEventHasBytesAvailable, NULL);
    }
#endif
    return result;
}
Ejemplo n.º 4
0
__private_extern__ CFErrorRef _CFErrorFromStreamError(CFAllocatorRef alloc, CFStreamError *streamError) {
    CFErrorRef result;
    Boolean canUpCall;
    
    __CFSpinLock(&(CFNetworkSupport.lock));
    if (!__CFBitIsSet(CFNetworkSupport.flags, kTriedToLoad)) initializeCFNetworkSupport();
    canUpCall = (CFNetworkSupport._CFErrorCreateWithStreamError != NULL);
    __CFSpinUnlock(&(CFNetworkSupport.lock));

    if (canUpCall) {
        result = CFNETWORK_CALL(_CFErrorCreateWithStreamError, (alloc, streamError));
    } else {
        if (streamError->domain == kCFStreamErrorDomainPOSIX) {
            return CFErrorCreate(alloc, kCFErrorDomainPOSIX, streamError->error, NULL);
        } else if (streamError->domain == kCFStreamErrorDomainMacOSStatus) {
            return CFErrorCreate(alloc, kCFErrorDomainOSStatus, streamError->error, NULL);
        } else {
            CFStringRef key = CFSTR("CFStreamErrorDomainKey");
            CFNumberRef value = CFNumberCreate(alloc, kCFNumberCFIndexType, &streamError->domain);
            CFDictionaryRef dict = CFDictionaryCreate(alloc, (const void **)(&key), (const void **)(&value), 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
            result = CFErrorCreate(alloc, CFSTR("BogusCFStreamErrorCompatibilityDomain"), streamError->error, dict);
            CFRelease(value);
            CFRelease(dict);
        }
    }
    return result;
}
Ejemplo n.º 5
0
__private_extern__ CFStreamError _CFStreamErrorFromError(CFErrorRef error) {
    CFStreamError result;
    Boolean canUpCall;
    
    __CFSpinLock(&(CFNetworkSupport.lock));
    if (!__CFBitIsSet(CFNetworkSupport.flags, kTriedToLoad)) initializeCFNetworkSupport();
    canUpCall = (CFNetworkSupport._CFStreamErrorFromCFError != NULL);
    __CFSpinUnlock(&(CFNetworkSupport.lock));

    if (canUpCall) {
        result = CFNETWORK_CALL(_CFStreamErrorFromCFError, (error));
    } else {
        CFStringRef domain = CFErrorGetDomain(error); 
        if (CFEqual(domain, kCFErrorDomainPOSIX)) {
            result.domain = kCFStreamErrorDomainPOSIX;
        } else if (CFEqual(domain, kCFErrorDomainOSStatus)) {
            result.domain = kCFStreamErrorDomainMacOSStatus;
        } else if (CFEqual(domain, kCFErrorDomainMach)) {
            result.domain = 11; // kCFStreamErrorDomainMach, but that symbol is in CFNetwork
        } else {
            result.domain = kCFStreamErrorDomainCustom;
        }
        result.error = CFErrorGetCode(error);
    }
    return result;
}
Ejemplo n.º 6
0
static Boolean fileCanRead(CFReadStreamRef stream, void *info) {
    _CFFileStreamContext *ctxt = (_CFFileStreamContext *)info;
#ifdef REAL_FILE_SCHEDULING
    return fdCanRead(ctxt->fd);
#else
    return !__CFBitIsSet(ctxt->flags, AT_EOF);
#endif
}
Ejemplo n.º 7
0
static void
createPair(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFSocketNativeHandle sock, const CFSocketSignature* sig, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream)
{
    if (readStream)
        *readStream = NULL;
        
    if (writeStream)
        *writeStream = NULL;

    __CFSpinLock(&(CFNetworkSupport.lock));
    if (!__CFBitIsSet(CFNetworkSupport.flags, kTriedToLoad)) initializeCFNetworkSupport();
    __CFSpinUnlock(&(CFNetworkSupport.lock));

    CFNETWORK_CALL(_CFSocketStreamCreatePair, (alloc, host, port, sock, sig, readStream, writeStream));
}
static Boolean constructFD(_CFFileStreamContext *fileStream, CFStreamError *error, Boolean forRead, struct _CFStream *stream) {
    int flags = forRead ? O_RDONLY : (O_CREAT | O_TRUNC | O_WRONLY);
#if DEPLOYMENT_TARGET_WINDOWS
    wchar_t path[CFMaxPathSize];
    flags |= (_O_BINARY|_O_NOINHERIT);
    if (_CFURLGetWideFileSystemRepresentation(fileStream->url, TRUE, path, CFMaxPathSize) == FALSE)
#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
    char path[CFMaxPathSize];
    if (CFURLGetFileSystemRepresentation(fileStream->url, TRUE, (UInt8 *)path, CFMaxPathSize) == FALSE)
#endif
     {
        error->error = ENOENT;
        error->domain = kCFStreamErrorDomainPOSIX;
        return FALSE;
    }
    if (__CFBitIsSet(fileStream->flags, APPEND)) {
        flags |= O_APPEND;
        flags &= ~O_TRUNC;
    }
    
    do {
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        fileStream->fd = open((const char *)path, flags, 0666);
#elif DEPLOYMENT_TARGET_WINDOWS
	fileStream->fd = _wopen(path, flags, 0666);
#endif
        if (fileStream->fd < 0)
            break;
        
        if ((fileStream->offset != -1) && (lseek(fileStream->fd, fileStream->offset, SEEK_SET) == -1))
            break;

#ifdef REAL_FILE_SCHEDULING
        if (fileStream->rlInfo.rlArray != NULL) {
            constructCFFD(fileStream, forRead, stream);
        }
#endif

        return TRUE;
    } while (1);

    __CFBitSet(fileStream->flags, USE_RUNLOOP_ARRAY);
    error->error = errno;
    error->domain = kCFStreamErrorDomainPOSIX;

    return FALSE;
}
Ejemplo n.º 9
0
static CFIndex fileWrite(CFWriteStreamRef stream, const UInt8 *buffer, CFIndex bufferLength, CFStreamError *errorCode, void *info) {
    _CFFileStreamContext *fileStream = ((_CFFileStreamContext *)info);
    CFIndex result = fdWrite(fileStream->fd, buffer, bufferLength, errorCode);
#ifdef REAL_FILE_SCHEDULING
    if (__CFBitIsSet(fileStream->flags, SCHEDULE_AFTER_WRITE)) {
        __CFBitClear(fileStream->flags, SCHEDULE_AFTER_WRITE);
        if (fileStream->rlInfo.cffd) {
            CFFileDescriptorEnableCallBacks(fileStream->rlInfo.cffd, kCFFileDescriptorWriteCallBack);
        }
    }
#else
    if (fileStream->scheduled > 0) {
        CFWriteStreamSignalEvent(stream, kCFStreamEventCanAcceptBytes, NULL);
    }
#endif
    return result;
}
Ejemplo n.º 10
0
static Boolean constructFD(_CFFileStreamContext *fileStream, CFStreamError *error, Boolean forRead, struct _CFStream *stream) {
    int flags = forRead ? O_RDONLY : (O_CREAT | O_TRUNC | O_WRONLY);

    // WINOBJC: improve code reuse here by letting the underlying open implementation handle the narrow/wide conversions etc.
    char path[CFMaxPathSize];
#if DEPLOYMENT_TARGET_WINDOWS
    flags |= (_O_BINARY|_O_NOINHERIT);
#endif    
    if (CFURLGetFileSystemRepresentation(fileStream->url, TRUE, (UInt8 *)path, CFMaxPathSize) == FALSE)
    {
        error->error = ENOENT;
        error->domain = kCFStreamErrorDomainPOSIX;
        return FALSE;
    }
    if (__CFBitIsSet(fileStream->flags, APPEND)) {
        flags |= O_APPEND;
        flags &= ~O_TRUNC;
    }
    
    do {
        fileStream->fd = open((const char *)path, flags, 0666);
        if (fileStream->fd < 0)
            break;
        
        if ((fileStream->offset != -1) && (lseek(fileStream->fd, fileStream->offset, SEEK_SET) == -1))
            break;

#ifdef REAL_FILE_SCHEDULING
        if (fileStream->rlInfo.rlArray != NULL) {
            constructCFFD(fileStream, forRead, stream);
        }
#endif

        return TRUE;
    } while (1);

    __CFBitSet(fileStream->flags, USE_RUNLOOP_ARRAY);
    error->error = errno;
    error->domain = kCFStreamErrorDomainPOSIX;

    return FALSE;
}
Ejemplo n.º 11
0
static void fileUnschedule(struct _CFStream *stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void *info) {
    _CFFileStreamContext *fileStream = (_CFFileStreamContext *)info;
#ifdef REAL_FILE_SCHEDULING
    Boolean isReadStream = (CFGetTypeID(stream) == CFReadStreamGetTypeID());
    CFStreamStatus status = isReadStream ? CFReadStreamGetStatus((CFReadStreamRef)stream) : CFWriteStreamGetStatus((CFWriteStreamRef)stream);
    if (status == kCFStreamStatusNotOpen) {
        // Not opened yet
        if (fileStream->rlInfo.rlArray) {
            CFMutableArrayRef runloops = fileStream->rlInfo.rlArray;
            CFIndex i, c;
            for (i = 0, c = CFArrayGetCount(runloops); i+1 < c; i += 2) {
                if (CFEqual(CFArrayGetValueAtIndex(runloops, i), runLoop) && CFEqual(CFArrayGetValueAtIndex(runloops, i+1), runLoopMode)) {
                    CFArrayRemoveValueAtIndex(runloops, i);
                    CFArrayRemoveValueAtIndex(runloops, i);
                    break;
                }
            }
        }
    } else if (fileStream->rlInfo.cffd) {
        if (__CFBitIsSet(fileStream->flags, USE_RUNLOOP_ARRAY)) {
            // we know that fileStream->rlInfo.rlArray is non-NULL because it is in a union with fileStream->rlInfo.cffd
            CFMutableArrayRef runloops = fileStream->rlInfo.rlArray;
            CFIndex i, c;
            for (i = 0, c = CFArrayGetCount(runloops); i+1 < c; i += 2) {
                if (CFEqual(CFArrayGetValueAtIndex(runloops, i), runLoop) && CFEqual(CFArrayGetValueAtIndex(runloops, i+1), runLoopMode)) {
                    CFArrayRemoveValueAtIndex(runloops, i);
                    CFArrayRemoveValueAtIndex(runloops, i);
                    break;
                }
            }
        } else {
            CFRunLoopSourceRef rlSrc = CFFileDescriptorCreateRunLoopSource(CFGetAllocator(stream), fileStream->rlInfo.cffd, 0);
            CFRunLoopRemoveSource(runLoop, rlSrc, runLoopMode);
            CFRelease(rlSrc);
        }
    }
#else
    if (fileStream->scheduled > 0)
        fileStream->scheduled--;
#endif
}