From 3d2224869c32e9628da3259cb7557e6147017579 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Tue, 5 Jan 2010 05:44:28 +0000 Subject: [PATCH] OMG I hate Apple's lame attempt at a stream API. --- LockScreen.mm | 119 +++++++++++++++++++++++++++++++++----------------- control | 2 +- 2 files changed, 79 insertions(+), 42 deletions(-) diff --git a/LockScreen.mm b/LockScreen.mm index 3b11d39..fc8cc25 100644 --- a/LockScreen.mm +++ b/LockScreen.mm @@ -36,6 +36,7 @@ */ #include +#include #import #import @@ -972,6 +973,8 @@ MSHook(bool, _ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6 /* }}} */ /* Cydget-PHP:// Protocol {{{ */ @interface CydgetPHPURLProtocol : NSURLProtocol { + pid_t pid_; + CFHTTPMessageRef http_; } @end @@ -992,6 +995,12 @@ MSHook(bool, _ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6 return request; } +- (id) initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)response client:(id)client { + if ((self = [super initWithRequest:request cachedResponse:response client:client]) != nil) { + pid_ = -1; + } return self; +} + - (void) startLoading { id client([self client]); NSURLRequest *request([self request]); @@ -1009,13 +1018,19 @@ MSHook(bool, _ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6 return; } - NSLog(@"%@::%@", path, [url query]); - int fds[2]; _assert(pipe(fds) != -1); - pid_t pid(fork()); - if (pid == 0) { + _assert(pid_ == -1); + pid_ = fork(); + if (pid_ == -1) { + _assert(close(fds[0]) != -1); + _assert(close(fds[1]) != -1); + [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]]; + return; + } + + if (pid_ == 0) { setenv("GATEWAY_INTERFACE", "CGI/1.1", true); setenv("SCRIPT_FILENAME", [path UTF8String], true); NSString *query([url query]); @@ -1033,55 +1048,67 @@ MSHook(bool, _ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6 _assert(close(fds[1]) != -1); - CFHTTPMessageRef http(CFHTTPMessageCreateEmpty(kCFAllocatorDefault, FALSE)); + _assert(http_ == NULL); + http_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, FALSE); + CFHTTPMessageAppendBytes(http_, (const uint8_t *) "HTTP/1.1 200 OK\r\n", 17); - CFHTTPMessageAppendBytes(http, (const uint8_t *) "HTTP/1.1 200 OK\r\n", 17); + NSFileHandle *handle([[NSFileHandle alloc] initWithFileDescriptor:fds[0] closeOnDealloc:YES]); - if (FILE *file = fdopen(fds[0], "r")) { - uint8_t buffer[16*1024]; - read: - size_t count(fread(buffer, 1, sizeof(buffer), file)); - if (count != 0) { - fwrite(buffer, 1, count, stderr); - CFHTTPMessageAppendBytes(http, buffer, count); - } - if (count == sizeof(buffer)) - goto read; - if (ferror(file)) { - [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorNetworkConnectionLost userInfo:nil]]; - fclose(file); - goto fail; - } - fclose(file); - } else _assert(close(fds[0])); + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(onRead:) + name:@"NSFileHandleReadCompletionNotification" + object:handle + ]; - { - CFStringRef mime(CFHTTPMessageCopyHeaderFieldValue(http, CFSTR("Content-type"))); - if (mime == NULL) { - [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorBadServerResponse userInfo:nil]]; - goto fail; - } + [handle readInBackgroundAndNotify]; - NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:(NSString *)mime expectedContentLength:-1 textEncodingName:nil] autorelease]); - CFRelease(mime); + [handle release]; +} - [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; +- (void) onRead:(NSNotification *)notification { + NSFileHandle *handle([notification object]); - CFDataRef data(CFHTTPMessageCopyBody(http)); - [client URLProtocol:self didLoadData:(NSData *)data]; - CFRelease(data); + NSData *data([[notification userInfo] objectForKey:NSFileHandleNotificationDataItem]); - [client URLProtocolDidFinishLoading:self]; - } + if (size_t length = [data length]) { + CFHTTPMessageAppendBytes(http_, reinterpret_cast([data bytes]), length); + [handle readInBackgroundAndNotify]; + } else { + id client([self client]); + + CFStringRef mime(CFHTTPMessageCopyHeaderFieldValue(http_, CFSTR("Content-type"))); + if (mime == NULL) + [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorBadServerResponse userInfo:nil]]; + else { + NSURLRequest *request([self request]); + + NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:(NSString *)mime expectedContentLength:-1 textEncodingName:nil] autorelease]); + CFRelease(mime); - fail: - CFRelease(http); + [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - int status; - _syscall(waitpid(pid, &status, 0)); + CFDataRef body(CFHTTPMessageCopyBody(http_)); + [client URLProtocol:self didLoadData:(NSData *)body]; + CFRelease(body); + + [client URLProtocolDidFinishLoading:self]; + } + + CFRelease(http_); + http_ = NULL; + } } + //[client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorNetworkConnectionLost userInfo:nil]]; + - (void) stopLoading { + if (pid_ != -1) { + kill(pid_, SIGTERM); + int status; + _syscall(waitpid(pid_, &status, 0)); + pid_ = -1; + } } @end @@ -1104,6 +1131,16 @@ static void dlset(Type_ &function, const char *name) { @implementation WebCycriptLockScreenController + (void) initialize { + int maxproc; + size_t size(sizeof(maxproc)); + if (sysctlbyname("kern.maxproc", &maxproc, &size, NULL, 0) == -1) + NSLog(@"sysctlbyname(\"kern.maxproc\", ?)"); + else if (maxproc < 72) { + maxproc = 72; + if (sysctlbyname("kern.maxproc", NULL, NULL, &maxproc, sizeof(maxproc)) == -1) + NSLog(@"sysctlbyname(\"kern.maxproc\", #)"); + } + apr_initialize(); [NSURLProtocol registerClass:[CydgetURLProtocol class]]; diff --git a/control b/control index 570b80a..e0deae1 100644 --- a/control +++ b/control @@ -3,7 +3,7 @@ Priority: optional Section: Development Maintainer: Jay Freeman (saurik) Architecture: iphoneos-arm -Version: 0.9.3101-1 +Version: 0.9.3105-1 Description: framework for managing lock screen plugins Name: Cydget Depends: mobilesubstrate (>= 0.9.2587-1), firmware (>= 2.2), preferenceloader, apr-lib, pcre, cycript (>= 0.9.292-1) -- 2.45.2