Hi -
Slice 2/3, the debuginfod_client get_url function. This new
version works during or after the progressfn callback.
Author: Frank Ch. Eigler
Date: Fri Mar 20 21:33:52 2020 -0400
debuginfod client API: add get_url function
This function lets a client know, during or after a progressfn
callback, what the url of the winning outgoing download is/was.
Signed-off-by: Frank Ch. Eigler
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
index 2730dbf7aee5..2a1c267b712c 100644
--- a/debuginfod/debuginfod-client.c
+++ b/debuginfod/debuginfod-client.c
@@ -82,6 +82,9 @@ struct debuginfod_client
/* Stores user data. */
void* user_data;
+ /* Stores current/last url. */
+ char url[PATH_MAX];
+
/* Can contain all other context, like cache_path, server_urls,
timeout or other info gotten from environment variables, the
handle data, etc. So those don't have to be reparsed and
@@ -128,6 +131,9 @@ struct handle_data
/* This handle. */
CURL *handle;
+ /* The client object whom we're serving. */
+ debuginfod_client *client;
+
/* Pointer to handle that should write to fd. Initially points to NULL,
then points to the first handle that begins writing the target file
to the cache. Used to ensure that a file is not downloaded from
@@ -144,7 +150,11 @@ debuginfod_write_callback (char *ptr, size_t size, size_t
nmemb, void *data)
/* Indicate to other handles that they can abort their transfer. */
if (*d->target_handle == NULL)
-*d->target_handle = d->handle;
+{
+ *d->target_handle = d->handle;
+ /* update the client object */
+ strncpy(d->client->url, d->url, sizeof(d->client->url));
+}
/* If this handle isn't the target handle, abort transfer. */
if (*d->target_handle != d->handle)
@@ -410,6 +420,9 @@ debuginfod_query_server (debuginfod_client *c,
char build_id_bytes[MAX_BUILD_ID_BYTES * 2 + 1];
int rc;
+ /* Clear the saved url. */
+ c->url[0] = '\0';
+
/* Is there any server we can query? If not, don't do any work,
just return with ENOSYS. Don't even access the cache. */
urls_envvar = getenv(server_urls_envvar);
@@ -620,6 +633,7 @@ debuginfod_query_server (debuginfod_client *c,
data[i].fd = fd;
data[i].target_handle = &target_handle;
data[i].handle = curl_easy_init();
+ data[i].client = c;
if (data[i].handle == NULL)
{
@@ -877,12 +891,20 @@ debuginfod_query_server (debuginfod_client *c,
static int
default_progressfn (debuginfod_client *c, long a, long b)
{
- (void) c;
-
- dprintf(STDERR_FILENO,
- "Downloading from debuginfod %ld/%ld%s", a, b,
- ((a == b) ? "\n" : "\r"));
- /* XXX: include URL - stateful */
+ const char* url = debuginfod_get_url (c);
+ assert (url != NULL); /* undocumented guarantee, might change later */
+
+ if (b == 0 || url[0]=='\0') /* early stage */
+dprintf(STDERR_FILENO,
+"Downloading %c\r", "-/|\\"[a % 4]);
+ else if (b < 0) /* download in progress but unknown total length */
+dprintf(STDERR_FILENO,
+"Downloading %s %ld\r",
+url, a);
+ else /* download in progress, and known total length */
+dprintf(STDERR_FILENO,
+"Downloading %s %ld/%ld\r",
+url, a, b);
return 0;
}
@@ -894,13 +916,11 @@ debuginfod_begin (void)
{
debuginfod_client *client;
size_t size = sizeof (struct debuginfod_client);
- client = (debuginfod_client *) malloc (size);
+ client = (debuginfod_client *) calloc (1, size);
if (client != NULL)
{
if (getenv(DEBUGINFOD_PROGRESS_ENV_VAR))
client->progressfn = default_progressfn;
- else
- client->progressfn = NULL;
}
return client;
}
@@ -918,6 +938,12 @@ debuginfod_get_user_data(debuginfod_client *client)
return client->user_data;
}
+const char *
+debuginfod_get_url(debuginfod_client *client)
+{
+ return client->url;
+}
+
void
debuginfod_end (debuginfod_client *client)
{
diff --git a/debuginfod/debuginfod.h b/debuginfod/debuginfod.h
index fe72f16e9bd8..2ace5f350488 100644
--- a/debuginfod/debuginfod.h
+++ b/debuginfod/debuginfod.h
@@ -81,6 +81,9 @@ void debuginfod_set_user_data (debuginfod_client *client,
void *value);
/* Get the user parameter. */
void* debuginfod_get_user_data (debuginfod_client *client);
+/* Get the current or last active URL, if known. */
+const char* debuginfod_get_url (debuginfod_client *client);
+
/* Release debuginfod client connection context handle. */
void debuginfod_end (debuginfod_client *client);
diff --git a/debuginfod/libdebuginfod.map b/debuginfod/libdebuginfod.map
index a919630dacce..d84e8924f7f8 100644
--- a/debuginfod/libdebuginfod.map
+++ b/debuginfod/libdebuginfod.map
@@ -12,4 +12,5 @@ ELFUTILS_0.179 {
global:
debuginfod_set_user_data;
debuginfod_get_user_data;
+ debuginfod_get_url;
};
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 87d1fee03302.