diff options
| -rw-r--r-- | src/core/download.c | 97 | ||||
| -rw-r--r-- | src/net/tcp/http.c | 103 |
2 files changed, 97 insertions, 103 deletions
diff --git a/src/core/download.c b/src/core/download.c index f748d0233..bc8901272 100644 --- a/src/core/download.c +++ b/src/core/download.c @@ -30,6 +30,8 @@ #include <gpxe/ebuffer.h> #include <gpxe/download.h> +static struct async_operations download_async_operations; + /** Registered download protocols */ static struct download_protocol download_protocols[0] __table_start ( struct download_protocol, download_protocols ); @@ -53,53 +55,6 @@ static struct download_protocol * find_protocol ( const char *name ) { return NULL; } -/** Free download resources */ -static void download_reap ( struct async *async ) { - struct download *download = - container_of ( async, struct download, async ); - - free ( download ); -} - -/** - * Handle download termination - * - * @v async Download asynchronous operation - * @v signal SIGCHLD - */ -static void download_sigchld ( struct async *async, - enum signal signal __unused ) { - struct download *download = - container_of ( async, struct download, async ); - int rc; - - /* Reap child */ - async_wait ( async, &rc, 1 ); - - /* Clean up */ - if ( rc == 0 ) { - /* Transfer ownership of buffer to parent */ - *(download->data) = download->buffer.addr; - *(download->len) = download->buffer.fill; - } else { - /* Discard the buffer */ - ufree ( download->buffer.addr ); - } - free_uri ( download->uri ); - download->uri = NULL; - - /* Terminate ourselves */ - async_done ( async, rc ); -} - -/** Download asynchronous operations */ -static struct async_operations download_async_operations = { - .reap = download_reap, - .signal = { - [SIGCHLD] = download_sigchld, - }, -}; - /** * Start download * @@ -170,3 +125,51 @@ int start_download ( const char *uri_string, struct async *parent, free ( download ); return rc; } + +/** + * Handle download termination + * + * @v async Download asynchronous operation + * @v signal SIGCHLD + */ +static void download_sigchld ( struct async *async, + enum signal signal __unused ) { + struct download *download = + container_of ( async, struct download, async ); + int rc; + + /* Reap child */ + async_wait ( async, &rc, 1 ); + + /* Clean up */ + if ( rc == 0 ) { + /* Transfer ownership of buffer to parent */ + *(download->data) = download->buffer.addr; + *(download->len) = download->buffer.fill; + } else { + /* Discard the buffer */ + ufree ( download->buffer.addr ); + } + free_uri ( download->uri ); + download->uri = NULL; + + /* Terminate ourselves */ + async_done ( async, rc ); +} + +/** + * Free download resources + * + * @v async Download asynchronous operation + */ +static void download_reap ( struct async *async ) { + free ( container_of ( async, struct download, async ) ); +} + +/** Download asynchronous operations */ +static struct async_operations download_async_operations = { + .reap = download_reap, + .signal = { + [SIGCHLD] = download_sigchld, + }, +}; diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index 6ae664ad8..84b8e1664 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -37,6 +37,8 @@ #include <gpxe/download.h> #include <gpxe/http.h> +static struct async_operations http_async_operations; + static inline struct http_request * tcp_to_http ( struct tcp_application *app ) { return container_of ( app, struct http_request, tcp ); @@ -357,15 +359,45 @@ static struct tcp_operations http_tcp_operations = { }; /** - * Reap asynchronous operation + * Initiate a HTTP connection * - * @v async Asynchronous operation + * @v uri Uniform Resource Identifier + * @v buffer Buffer into which to download file + * @v parent Parent asynchronous operation + * @ret rc Return status code */ -static void http_reap ( struct async *async ) { - struct http_request *http = - container_of ( async, struct http_request, async ); +int http_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) { + struct http_request *http = NULL; + int rc; + + /* Allocate and populate HTTP structure */ + http = malloc ( sizeof ( *http ) ); + if ( ! http ) + return -ENOMEM; + memset ( http, 0, sizeof ( *http ) ); + http->uri = uri; + http->buffer = buffer; + async_init ( &http->async, &http_async_operations, parent ); + + +#warning "Quick name resolution hack" + extern int dns_resolv ( const char *name, + struct sockaddr *sa, + struct async *parent ); + + if ( ( rc = dns_resolv ( uri->host, &http->server, + &http->async ) ) != 0 ) + goto err; + + return 0; + + err: + DBGC ( http, "HTTP %p could not create request: %s\n", + http, strerror ( rc ) ); + async_uninit ( &http->async ); free ( http ); + return rc; } /** @@ -380,10 +412,8 @@ static void http_sigchld ( struct async *async, enum signal signal __unused ) { struct sockaddr_tcpip *st = ( struct sockaddr_tcpip * ) &http->server; int rc; - /* Reap child */ - async_wait ( async, &rc, 1 ); - /* If name resolution failed, abort now */ + async_wait ( async, &rc, 1 ); if ( rc != 0 ) { http_done ( http, rc ); return; @@ -400,6 +430,15 @@ static void http_sigchld ( struct async *async, enum signal signal __unused ) { } } +/** + * Free HTTP connection + * + * @v async Asynchronous operation + */ +static void http_reap ( struct async *async ) { + free ( container_of ( async, struct http_request, async ) ); +} + /** HTTP asynchronous operations */ static struct async_operations http_async_operations = { .reap = http_reap, @@ -408,54 +447,6 @@ static struct async_operations http_async_operations = { }, }; -/** - * Initiate a HTTP connection - * - * @v uri Uniform Resource Identifier - * @v buffer Buffer into which to download file - * @v parent Parent asynchronous operation - * @ret rc Return status code - */ -int http_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) { - struct http_request *http = NULL; - int rc; - - /* Sanity check */ - if ( ! uri->host ) { - rc = -EINVAL; - goto err; - } - - /* Allocate and populate HTTP structure */ - http = malloc ( sizeof ( *http ) ); - if ( ! http ) - return -ENOMEM; - memset ( http, 0, sizeof ( *http ) ); - http->uri = uri; - http->buffer = buffer; - async_init ( &http->async, &http_async_operations, parent ); - - -#warning "Quick name resolution hack" - extern int dns_resolv ( const char *name, - struct sockaddr *sa, - struct async *parent ); - - if ( ( rc = dns_resolv ( uri->host, &http->server, - &http->async ) ) != 0 ) - goto err; - - - return 0; - - err: - DBGC ( http, "HTTP %p could not create request: %s\n", - http, strerror ( rc ) ); - async_uninit ( &http->async ); - free ( http ); - return rc; -} - /** HTTP download protocol */ struct download_protocol http_download_protocol __download_protocol = { .name = "http", |
