mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
guestfs_readlinklist: Reimplement to avoid protocol limits.
This commit is contained in:
2
TODO
2
TODO
@@ -564,5 +564,3 @@ These would be changed from daemon_functions to non_daemon_functions,
|
||||
with the non-daemon versions implemented using guestfs_upload and
|
||||
guestfs_download (and others). This change should be transparent from
|
||||
the p.o.v of the API and ABI.
|
||||
|
||||
- guestfs_readlinklist
|
||||
|
||||
@@ -53,7 +53,7 @@ do_readlink (const char *path)
|
||||
}
|
||||
|
||||
char **
|
||||
do_readlinklist (const char *path, char *const *names)
|
||||
do_internal_readlinklist (const char *path, char *const *names)
|
||||
{
|
||||
int fd_cwd;
|
||||
size_t i;
|
||||
|
||||
@@ -2196,6 +2196,29 @@ list a directory contents without making many round-trips.
|
||||
See also C<guestfs_lstatlist> for a similarly efficient call
|
||||
for getting standard stats." };
|
||||
|
||||
{ defaults with
|
||||
name = "readlinklist";
|
||||
style = RStringList "links", [Pathname "path"; StringList "names"], [];
|
||||
shortdesc = "readlink on multiple files";
|
||||
longdesc = "\
|
||||
This call allows you to do a C<readlink> operation
|
||||
on multiple files, where all files are in the directory C<path>.
|
||||
C<names> is the list of files from this directory.
|
||||
|
||||
On return you get a list of strings, with a one-to-one
|
||||
correspondence to the C<names> list. Each string is the
|
||||
value of the symbolic link.
|
||||
|
||||
If the C<readlink(2)> operation fails on any name, then
|
||||
the corresponding result string is the empty string C<\"\">.
|
||||
However the whole operation is completed even if there
|
||||
were C<readlink(2)> errors, and so you can call this
|
||||
function with names where you don't know if they are
|
||||
symbolic links already (albeit slightly less efficient).
|
||||
|
||||
This call is intended for programs that want to efficiently
|
||||
list a directory contents without making many round-trips." };
|
||||
|
||||
]
|
||||
|
||||
(* daemon_functions are any functions which cause some action
|
||||
@@ -6379,9 +6402,10 @@ this call to fail. The caller must split up such requests
|
||||
into smaller groups of names." };
|
||||
|
||||
{ defaults with
|
||||
name = "readlinklist";
|
||||
name = "internal_readlinklist";
|
||||
style = RStringList "links", [Pathname "path"; StringList "names"], [];
|
||||
proc_nr = Some 206;
|
||||
in_docs = false; in_fish = false;
|
||||
shortdesc = "readlink on multiple files";
|
||||
longdesc = "\
|
||||
This call allows you to do a C<readlink> operation
|
||||
|
||||
41
src/file.c
41
src/file.c
@@ -494,3 +494,44 @@ guestfs__lxattrlist (guestfs_h *g, const char *dir, char *const *names)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define READLINK_MAX 1000
|
||||
|
||||
char **
|
||||
guestfs__readlinklist (guestfs_h *g, const char *dir, char *const *names)
|
||||
{
|
||||
size_t len = count_strings (names);
|
||||
char **first;
|
||||
size_t old_len, ret_len = 0;
|
||||
char **ret = NULL, **links;
|
||||
|
||||
while (len > 0) {
|
||||
first = take_strings (g, names, READLINK_MAX, &names);
|
||||
len = len <= READLINK_MAX ? 0 : len - READLINK_MAX;
|
||||
|
||||
links = guestfs_internal_readlinklist (g, dir, first);
|
||||
/* Note we don't need to free up the strings because take_strings
|
||||
* does not do a deep copy.
|
||||
*/
|
||||
free (first);
|
||||
|
||||
if (links == NULL) {
|
||||
guestfs___free_string_list (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Append links to ret. */
|
||||
old_len = ret_len;
|
||||
ret_len += count_strings (links);
|
||||
ret = safe_realloc (g, ret, ret_len * sizeof (char *));
|
||||
memcpy (&ret[old_len], links, (ret_len-old_len) * sizeof (char *));
|
||||
|
||||
free (links);
|
||||
}
|
||||
|
||||
/* NULL-terminate the list. */
|
||||
ret = safe_realloc (g, ret, (ret_len+1) * sizeof (char *));
|
||||
ret[ret_len] = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user