Loading adb/adb.cpp +21 −13 Original line number Diff line number Diff line Loading @@ -956,8 +956,8 @@ int launch_server(const std::string& socket_spec) { // Try to handle a network forwarding request. // This returns 1 on success, 0 on failure, and -1 to indicate this is not // a forwarding-related request. int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd) { int handle_forward_request(const char* service, TransportType type, const char* serial, TransportId transport_id, int reply_fd) { if (!strcmp(service, "list-forward")) { // Create the list of forward redirections. std::string listeners = format_listeners(); Loading Loading @@ -1010,7 +1010,8 @@ int handle_forward_request(const char* service, TransportType type, const char* } std::string error_msg; atransport* transport = acquire_one_transport(type, serial, nullptr, &error_msg); atransport* transport = acquire_one_transport(type, serial, transport_id, nullptr, &error_msg); if (!transport) { SendFail(reply_fd, error_msg); return 1; Loading Loading @@ -1068,8 +1069,8 @@ static int SendOkay(int fd, const std::string& s) { return 0; } int handle_host_request(const char* service, TransportType type, const char* serial, int reply_fd, asocket* s) { int handle_host_request(const char* service, TransportType type, const char* serial, TransportId transport_id, int reply_fd, asocket* s) { if (strcmp(service, "kill") == 0) { fprintf(stderr, "adb server killed by remote request\n"); fflush(stdout); Loading @@ -1089,7 +1090,14 @@ int handle_host_request(const char* service, TransportType type, if (!strncmp(service, "transport", strlen("transport"))) { TransportType type = kTransportAny; if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { if (!strncmp(service, "transport-id:", strlen("transport-id:"))) { service += strlen("transport-id:"); transport_id = strtoll(service, const_cast<char**>(&service), 10); if (*service != '\0') { SendFail(reply_fd, "invalid transport id"); return 1; } } else if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { type = kTransportUsb; } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { type = kTransportLocal; Loading @@ -1101,7 +1109,7 @@ int handle_host_request(const char* service, TransportType type, } std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t != nullptr) { s->transport = t; SendOkay(reply_fd); Loading Loading @@ -1144,7 +1152,7 @@ int handle_host_request(const char* service, TransportType type, if (!strcmp(service, "features")) { std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t != nullptr) { SendOkay(reply_fd, FeatureSetToString(t->features())); } else { Loading Loading @@ -1197,7 +1205,7 @@ int handle_host_request(const char* service, TransportType type, // These always report "unknown" rather than the actual error, for scripts. if (!strcmp(service, "get-serialno")) { std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->serial ? t->serial : "unknown"); } else { Loading @@ -1206,7 +1214,7 @@ int handle_host_request(const char* service, TransportType type, } if (!strcmp(service, "get-devpath")) { std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->devpath ? t->devpath : "unknown"); } else { Loading @@ -1215,7 +1223,7 @@ int handle_host_request(const char* service, TransportType type, } if (!strcmp(service, "get-state")) { std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->connection_state_name()); } else { Loading @@ -1233,7 +1241,7 @@ int handle_host_request(const char* service, TransportType type, if (!strcmp(service, "reconnect")) { std::string response; atransport* t = acquire_one_transport(type, serial, nullptr, &response, true); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &response, true); if (t != nullptr) { kick_transport(t); response = Loading @@ -1242,7 +1250,7 @@ int handle_host_request(const char* service, TransportType type, return SendOkay(reply_fd, response); } int ret = handle_forward_request(service, type, serial, reply_fd); int ret = handle_forward_request(service, type, serial, transport_id, reply_fd); if (ret >= 0) return ret - 1; return -1; Loading adb/adb.h +6 −3 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ std::string adb_version(); // Increment this when we want to force users to start a new adb server. #define ADB_SERVER_VERSION 39 using TransportId = uint64_t; class atransport; struct amessage { Loading Loading @@ -149,7 +150,7 @@ atransport* find_emulator_transport_by_console_port(int console_port); int service_to_fd(const char* name, const atransport* transport); #if ADB_HOST asocket *host_service_to_socket(const char* name, const char *serial); asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id); #endif #if !ADB_HOST Loading @@ -159,7 +160,8 @@ asocket* create_jdwp_tracker_service_socket(); int create_jdwp_connection_fd(int jdwp_pid); #endif int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd); int handle_forward_request(const char* service, TransportType type, const char* serial, TransportId transport_id, int reply_fd); #if !ADB_HOST void framebuffer_service(int fd, void *cookie); Loading Loading @@ -216,7 +218,8 @@ extern int SHELL_EXIT_NOTIFY_FD; #define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2) #endif int handle_host_request(const char* service, TransportType type, const char* serial, int reply_fd, asocket *s); int handle_host_request(const char* service, TransportType type, const char* serial, TransportId transport_id, int reply_fd, asocket* s); void handle_online(atransport *t); void handle_offline(atransport *t); Loading adb/adb_client.cpp +23 −8 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "adb_client.h" #include <errno.h> #include <inttypes.h> #include <limits.h> #include <stdarg.h> #include <stdio.h> Loading @@ -46,12 +47,20 @@ static TransportType __adb_transport = kTransportAny; static const char* __adb_serial = NULL; static TransportId __adb_transport_id = 0; static const char* __adb_server_socket_spec; void adb_set_transport(TransportType type, const char* serial) { void adb_set_transport(TransportType type, const char* serial, TransportId transport_id) { __adb_transport = type; __adb_serial = serial; __adb_transport_id = transport_id; } void adb_get_transport(TransportType* type, const char** serial, TransportId* transport_id) { if (type) *type = __adb_transport; if (serial) *serial = __adb_serial; if (transport_id) *transport_id = __adb_transport_id; } void adb_set_socket_spec(const char* socket_spec) { Loading @@ -63,7 +72,10 @@ void adb_set_socket_spec(const char* socket_spec) { static int switch_socket_transport(int fd, std::string* error) { std::string service; if (__adb_serial) { if (__adb_transport_id) { service += "host:transport-id:"; service += std::to_string(__adb_transport_id); } else if (__adb_serial) { service += "host:transport:"; service += __adb_serial; } else { Loading Loading @@ -292,15 +304,18 @@ bool adb_query(const std::string& service, std::string* result, std::string* err return true; } std::string format_host_command(const char* command, TransportType type, const char* serial) { if (serial) { return android::base::StringPrintf("host-serial:%s:%s", serial, command); std::string format_host_command(const char* command) { if (__adb_transport_id) { return android::base::StringPrintf("host-transport-id:%" PRIu64 ":%s", __adb_transport_id, command); } else if (__adb_serial) { return android::base::StringPrintf("host-serial:%s:%s", __adb_serial, command); } const char* prefix = "host"; if (type == kTransportUsb) { if (__adb_transport == kTransportUsb) { prefix = "host-usb"; } else if (type == kTransportLocal) { } else if (__adb_transport == kTransportLocal) { prefix = "host-local"; } return android::base::StringPrintf("%s:%s", prefix, command); Loading @@ -308,7 +323,7 @@ std::string format_host_command(const char* command, TransportType type, const c bool adb_get_feature_set(FeatureSet* feature_set, std::string* error) { std::string result; if (adb_query(format_host_command("features", __adb_transport, __adb_serial), &result, error)) { if (adb_query(format_host_command("features"), &result, error)) { *feature_set = StringToFeatureSet(result); return true; } Loading adb/adb_client.h +4 −3 Original line number Diff line number Diff line Loading @@ -40,7 +40,9 @@ bool adb_query(const std::string& service, std::string* _Nonnull result, std::string* _Nonnull error); // Set the preferred transport to connect to. void adb_set_transport(TransportType type, const char* _Nullable serial); void adb_set_transport(TransportType type, const char* _Nullable serial, TransportId transport_id); void adb_get_transport(TransportType* _Nullable type, const char* _Nullable* _Nullable serial, TransportId* _Nullable transport_id); // Set the socket specification for the adb server. // This function can only be called once, and the argument must live to the end of the process. Loading @@ -57,8 +59,7 @@ int adb_send_emulator_command(int argc, const char* _Nonnull* _Nonnull argv, bool adb_status(int fd, std::string* _Nonnull error); // Create a host command corresponding to selected transport type/serial. std::string format_host_command(const char* _Nonnull command, TransportType type, const char* _Nullable serial); std::string format_host_command(const char* _Nonnull command); // Get the feature set of the current preferred transport. bool adb_get_feature_set(FeatureSet* _Nonnull feature_set, std::string* _Nonnull error); Loading adb/bugreport.cpp +6 −7 Original line number Diff line number Diff line Loading @@ -195,13 +195,13 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback); }; int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) { int Bugreport::DoIt(int argc, const char** argv) { if (argc > 2) return syntax_error("adb bugreport [PATH]"); // Gets bugreportz version. std::string bugz_stdout, bugz_stderr; DefaultStandardStreamsCallback version_callback(&bugz_stdout, &bugz_stderr); int status = SendShellCommand(transport_type, serial, "bugreportz -v", false, &version_callback); int status = SendShellCommand("bugreportz -v", false, &version_callback); std::string bugz_version = android::base::Trim(bugz_stderr); std::string bugz_output = android::base::Trim(bugz_stdout); Loading @@ -214,7 +214,7 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, fprintf(stderr, "Failed to get bugreportz version, which is only available on devices " "running Android 7.0 or later.\nTrying a plain-text bug report instead.\n"); return SendShellCommand(transport_type, serial, "bugreport", false); return SendShellCommand("bugreport", false); } // But if user explicitly asked for a zipped bug report, fails instead (otherwise calling Loading Loading @@ -265,7 +265,7 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, bugz_command = "bugreportz"; } BugreportStandardStreamsCallback bugz_callback(dest_dir, dest_file, show_progress, this); return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback); return SendShellCommand(bugz_command, false, &bugz_callback); } void Bugreport::UpdateProgress(const std::string& message, int progress_percentage) { Loading @@ -274,10 +274,9 @@ void Bugreport::UpdateProgress(const std::string& message, int progress_percenta LinePrinter::INFO); } int Bugreport::SendShellCommand(TransportType transport_type, const char* serial, const std::string& command, bool disable_shell_protocol, int Bugreport::SendShellCommand(const std::string& command, bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) { return send_shell_command(transport_type, serial, command, disable_shell_protocol, callback); return send_shell_command(command, disable_shell_protocol, callback); } bool Bugreport::DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs, Loading Loading
adb/adb.cpp +21 −13 Original line number Diff line number Diff line Loading @@ -956,8 +956,8 @@ int launch_server(const std::string& socket_spec) { // Try to handle a network forwarding request. // This returns 1 on success, 0 on failure, and -1 to indicate this is not // a forwarding-related request. int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd) { int handle_forward_request(const char* service, TransportType type, const char* serial, TransportId transport_id, int reply_fd) { if (!strcmp(service, "list-forward")) { // Create the list of forward redirections. std::string listeners = format_listeners(); Loading Loading @@ -1010,7 +1010,8 @@ int handle_forward_request(const char* service, TransportType type, const char* } std::string error_msg; atransport* transport = acquire_one_transport(type, serial, nullptr, &error_msg); atransport* transport = acquire_one_transport(type, serial, transport_id, nullptr, &error_msg); if (!transport) { SendFail(reply_fd, error_msg); return 1; Loading Loading @@ -1068,8 +1069,8 @@ static int SendOkay(int fd, const std::string& s) { return 0; } int handle_host_request(const char* service, TransportType type, const char* serial, int reply_fd, asocket* s) { int handle_host_request(const char* service, TransportType type, const char* serial, TransportId transport_id, int reply_fd, asocket* s) { if (strcmp(service, "kill") == 0) { fprintf(stderr, "adb server killed by remote request\n"); fflush(stdout); Loading @@ -1089,7 +1090,14 @@ int handle_host_request(const char* service, TransportType type, if (!strncmp(service, "transport", strlen("transport"))) { TransportType type = kTransportAny; if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { if (!strncmp(service, "transport-id:", strlen("transport-id:"))) { service += strlen("transport-id:"); transport_id = strtoll(service, const_cast<char**>(&service), 10); if (*service != '\0') { SendFail(reply_fd, "invalid transport id"); return 1; } } else if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { type = kTransportUsb; } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { type = kTransportLocal; Loading @@ -1101,7 +1109,7 @@ int handle_host_request(const char* service, TransportType type, } std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t != nullptr) { s->transport = t; SendOkay(reply_fd); Loading Loading @@ -1144,7 +1152,7 @@ int handle_host_request(const char* service, TransportType type, if (!strcmp(service, "features")) { std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t != nullptr) { SendOkay(reply_fd, FeatureSetToString(t->features())); } else { Loading Loading @@ -1197,7 +1205,7 @@ int handle_host_request(const char* service, TransportType type, // These always report "unknown" rather than the actual error, for scripts. if (!strcmp(service, "get-serialno")) { std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->serial ? t->serial : "unknown"); } else { Loading @@ -1206,7 +1214,7 @@ int handle_host_request(const char* service, TransportType type, } if (!strcmp(service, "get-devpath")) { std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->devpath ? t->devpath : "unknown"); } else { Loading @@ -1215,7 +1223,7 @@ int handle_host_request(const char* service, TransportType type, } if (!strcmp(service, "get-state")) { std::string error; atransport* t = acquire_one_transport(type, serial, nullptr, &error); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->connection_state_name()); } else { Loading @@ -1233,7 +1241,7 @@ int handle_host_request(const char* service, TransportType type, if (!strcmp(service, "reconnect")) { std::string response; atransport* t = acquire_one_transport(type, serial, nullptr, &response, true); atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &response, true); if (t != nullptr) { kick_transport(t); response = Loading @@ -1242,7 +1250,7 @@ int handle_host_request(const char* service, TransportType type, return SendOkay(reply_fd, response); } int ret = handle_forward_request(service, type, serial, reply_fd); int ret = handle_forward_request(service, type, serial, transport_id, reply_fd); if (ret >= 0) return ret - 1; return -1; Loading
adb/adb.h +6 −3 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ std::string adb_version(); // Increment this when we want to force users to start a new adb server. #define ADB_SERVER_VERSION 39 using TransportId = uint64_t; class atransport; struct amessage { Loading Loading @@ -149,7 +150,7 @@ atransport* find_emulator_transport_by_console_port(int console_port); int service_to_fd(const char* name, const atransport* transport); #if ADB_HOST asocket *host_service_to_socket(const char* name, const char *serial); asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id); #endif #if !ADB_HOST Loading @@ -159,7 +160,8 @@ asocket* create_jdwp_tracker_service_socket(); int create_jdwp_connection_fd(int jdwp_pid); #endif int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd); int handle_forward_request(const char* service, TransportType type, const char* serial, TransportId transport_id, int reply_fd); #if !ADB_HOST void framebuffer_service(int fd, void *cookie); Loading Loading @@ -216,7 +218,8 @@ extern int SHELL_EXIT_NOTIFY_FD; #define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2) #endif int handle_host_request(const char* service, TransportType type, const char* serial, int reply_fd, asocket *s); int handle_host_request(const char* service, TransportType type, const char* serial, TransportId transport_id, int reply_fd, asocket* s); void handle_online(atransport *t); void handle_offline(atransport *t); Loading
adb/adb_client.cpp +23 −8 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "adb_client.h" #include <errno.h> #include <inttypes.h> #include <limits.h> #include <stdarg.h> #include <stdio.h> Loading @@ -46,12 +47,20 @@ static TransportType __adb_transport = kTransportAny; static const char* __adb_serial = NULL; static TransportId __adb_transport_id = 0; static const char* __adb_server_socket_spec; void adb_set_transport(TransportType type, const char* serial) { void adb_set_transport(TransportType type, const char* serial, TransportId transport_id) { __adb_transport = type; __adb_serial = serial; __adb_transport_id = transport_id; } void adb_get_transport(TransportType* type, const char** serial, TransportId* transport_id) { if (type) *type = __adb_transport; if (serial) *serial = __adb_serial; if (transport_id) *transport_id = __adb_transport_id; } void adb_set_socket_spec(const char* socket_spec) { Loading @@ -63,7 +72,10 @@ void adb_set_socket_spec(const char* socket_spec) { static int switch_socket_transport(int fd, std::string* error) { std::string service; if (__adb_serial) { if (__adb_transport_id) { service += "host:transport-id:"; service += std::to_string(__adb_transport_id); } else if (__adb_serial) { service += "host:transport:"; service += __adb_serial; } else { Loading Loading @@ -292,15 +304,18 @@ bool adb_query(const std::string& service, std::string* result, std::string* err return true; } std::string format_host_command(const char* command, TransportType type, const char* serial) { if (serial) { return android::base::StringPrintf("host-serial:%s:%s", serial, command); std::string format_host_command(const char* command) { if (__adb_transport_id) { return android::base::StringPrintf("host-transport-id:%" PRIu64 ":%s", __adb_transport_id, command); } else if (__adb_serial) { return android::base::StringPrintf("host-serial:%s:%s", __adb_serial, command); } const char* prefix = "host"; if (type == kTransportUsb) { if (__adb_transport == kTransportUsb) { prefix = "host-usb"; } else if (type == kTransportLocal) { } else if (__adb_transport == kTransportLocal) { prefix = "host-local"; } return android::base::StringPrintf("%s:%s", prefix, command); Loading @@ -308,7 +323,7 @@ std::string format_host_command(const char* command, TransportType type, const c bool adb_get_feature_set(FeatureSet* feature_set, std::string* error) { std::string result; if (adb_query(format_host_command("features", __adb_transport, __adb_serial), &result, error)) { if (adb_query(format_host_command("features"), &result, error)) { *feature_set = StringToFeatureSet(result); return true; } Loading
adb/adb_client.h +4 −3 Original line number Diff line number Diff line Loading @@ -40,7 +40,9 @@ bool adb_query(const std::string& service, std::string* _Nonnull result, std::string* _Nonnull error); // Set the preferred transport to connect to. void adb_set_transport(TransportType type, const char* _Nullable serial); void adb_set_transport(TransportType type, const char* _Nullable serial, TransportId transport_id); void adb_get_transport(TransportType* _Nullable type, const char* _Nullable* _Nullable serial, TransportId* _Nullable transport_id); // Set the socket specification for the adb server. // This function can only be called once, and the argument must live to the end of the process. Loading @@ -57,8 +59,7 @@ int adb_send_emulator_command(int argc, const char* _Nonnull* _Nonnull argv, bool adb_status(int fd, std::string* _Nonnull error); // Create a host command corresponding to selected transport type/serial. std::string format_host_command(const char* _Nonnull command, TransportType type, const char* _Nullable serial); std::string format_host_command(const char* _Nonnull command); // Get the feature set of the current preferred transport. bool adb_get_feature_set(FeatureSet* _Nonnull feature_set, std::string* _Nonnull error); Loading
adb/bugreport.cpp +6 −7 Original line number Diff line number Diff line Loading @@ -195,13 +195,13 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback); }; int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) { int Bugreport::DoIt(int argc, const char** argv) { if (argc > 2) return syntax_error("adb bugreport [PATH]"); // Gets bugreportz version. std::string bugz_stdout, bugz_stderr; DefaultStandardStreamsCallback version_callback(&bugz_stdout, &bugz_stderr); int status = SendShellCommand(transport_type, serial, "bugreportz -v", false, &version_callback); int status = SendShellCommand("bugreportz -v", false, &version_callback); std::string bugz_version = android::base::Trim(bugz_stderr); std::string bugz_output = android::base::Trim(bugz_stdout); Loading @@ -214,7 +214,7 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, fprintf(stderr, "Failed to get bugreportz version, which is only available on devices " "running Android 7.0 or later.\nTrying a plain-text bug report instead.\n"); return SendShellCommand(transport_type, serial, "bugreport", false); return SendShellCommand("bugreport", false); } // But if user explicitly asked for a zipped bug report, fails instead (otherwise calling Loading Loading @@ -265,7 +265,7 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, bugz_command = "bugreportz"; } BugreportStandardStreamsCallback bugz_callback(dest_dir, dest_file, show_progress, this); return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback); return SendShellCommand(bugz_command, false, &bugz_callback); } void Bugreport::UpdateProgress(const std::string& message, int progress_percentage) { Loading @@ -274,10 +274,9 @@ void Bugreport::UpdateProgress(const std::string& message, int progress_percenta LinePrinter::INFO); } int Bugreport::SendShellCommand(TransportType transport_type, const char* serial, const std::string& command, bool disable_shell_protocol, int Bugreport::SendShellCommand(const std::string& command, bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) { return send_shell_command(transport_type, serial, command, disable_shell_protocol, callback); return send_shell_command(command, disable_shell_protocol, callback); } bool Bugreport::DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs, Loading