The previous patch was a raw code move.
This patch takes care of simplifying argv
preparation.

Also get rid of the _argc extra variable.

Signed-off-by: Benoît Canet <[email protected]>
---
 core/app.cc        | 58 ++++++++++++++++++++++++++----------------------------
 include/osv/app.hh | 10 +++-------
 2 files changed, 31 insertions(+), 37 deletions(-)

diff --git a/core/app.cc b/core/app.cc
index 515096e..c76b168 100644
--- a/core/app.cc
+++ b/core/app.cc
@@ -294,67 +294,65 @@ void application::main()
     // _entry_point() doesn't return
 }
 
-void application::prepare_argc_argv()
+void application::prepare_argv()
 {
-    // C main wants mutable arguments, so we have can't use strings directly
-    transform(_args, back_inserter(_mut_args),
-            [](std::string s) { return std::vector<char>(s.data(), s.data() + 
s.size() + 1); });
-    std::vector<char*> argv;
-    transform(_mut_args.begin(), _mut_args.end(), back_inserter(argv),
-            [](std::vector<char>& s) { return s.data(); });
-    _argc = argv.size();
-    argv.push_back(nullptr);
-
-    char **argv_data = argv.data();
-
+    // Prepare program_* variable used by the libc
     char *c_path = (char *)(_command.c_str());
-    // path is guaranteed to keep existing this function
     program_invocation_name = c_path;
     program_invocation_short_name = basename(c_path);
 
-    auto sz = _argc; // for the trailing 0's.
-    for (int i = 0; i < _argc; ++i) {
-        sz += strlen(argv_data[i]);
+    // Allocate a continuous buffer for arguments: _argv_buf
+    // First count the trailing zeroes
+    auto sz = _args.size();
+    // Then add the sum of each argument size to sz
+    for (auto &str: _args) {
+        sz += str.size();
     }
-
     _argv_buf.reset(new char[sz]);
-    char *ab = _argv_buf.get();
+
     // In Linux, the pointer arrays argv[] and envp[] are continguous.
     // Unfortunately, some programs rely on this fact (e.g., libgo's
     // runtime_goenvs_unix()) so it is useful that we do this too.
+
+    // First count the number of environment variables
     int envcount = 0;
     while (environ[envcount]) {
         envcount++;
     }
-    _contig_argv.reset(new char*[_argc + 1 + envcount + 1]);
-    char **contig_argv = _contig_argv.get();
 
-    for (int i = 0; i < _argc; ++i) {
-        size_t asize = strlen(argv_data[i]);
-        memcpy(ab, argv_data[i], asize);
-        ab[asize] = '\0';
+    // Allocate the continuous buffer for argv[] and envp[]
+    _argv.reset(new char*[_args.size() + 1 + envcount + 1]);
+
+    // Fill the argv part of these buffers
+    char *ab = _argv_buf.get();
+    char **contig_argv = _argv.get();
+    for (size_t i = 0; i < _args.size(); i++) {
+       auto &str = _args[i];
+        memcpy(ab, str.c_str(), str.size());
+        ab[str.size()] = '\0';
         contig_argv[i] = ab;
-        ab += asize + 1;
+        ab += str.size() + 1;
     }
-    contig_argv[_argc] = nullptr;
+    contig_argv[_args.size()] = nullptr;
 
+    // Do the same for environ
     for (int i = 0; i < envcount; i++) {
-        contig_argv[_argc + 1 + i] = environ[i];
+        contig_argv[_args.size() + 1 + i] = environ[i];
     }
-    contig_argv[_argc + 1 + envcount] = nullptr;
+    contig_argv[_args.size() + 1 + envcount] = nullptr;
 }
 
 void application::run_main()
 {
     trace_app_main(this, _command.c_str());
 
-    prepare_argc_argv();
+    prepare_argv();
 
     // make sure to have a fresh optind across calls
     // FIXME: fails if run() is executed in parallel
     int old_optind = optind;
     optind = 0;
-    _return_code = _main(_argc, _contig_argv.get());
+    _return_code = _main(_args.size(), _argv.get());
     optind = old_optind;
 
     if (_return_code) {
diff --git a/include/osv/app.hh b/include/osv/app.hh
index 3ecf1a8..62fd406 100644
--- a/include/osv/app.hh
+++ b/include/osv/app.hh
@@ -194,7 +194,7 @@ private:
     void start_and_join(waiter* setup_waiter);
     void main();
     void run_main(std::string path, int argc, char** argv);
-    void prepare_argc_argv();
+    void prepare_argv();
     void run_main();
     friend void ::__libc_start_main(int(*)(int, char**), int, char**, 
void(*)(),
         void(*)(), void(*)(), void*);
@@ -215,12 +215,8 @@ private:
     void (*_entry_point)();
     static app_registry apps;
 
-    // argc and argv variables
-    std::vector<std::vector<char>> _mut_args;
-    std::unique_ptr<char *> _contig_argv;
-    std::unique_ptr<char []> _argv_buf;
-    std::vector<char*> _argv;
-    int _argc;
+    std::unique_ptr<char *[]> _argv; // uniqueptr to argv
+    std::unique_ptr<char []> _argv_buf; // actual arguments content
 
     // Must be destroyed before _lib, because contained function objects may
     // have destructors which are part of the application's code.
-- 
2.7.4

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to