Domanda

I'm writing this program on Ubuntu. If I type this command into a shell

groups root sys bin

it outputs

root : root
sys : sys
bin : bin

However I'm writing a c++ program that calls groups with execlp using

execlp("groups", "groups", args.c_str(), NULL);

where args = "root sys bin". I just get a :No such user error since groups' is obviously just looking at that entire string as argv[0] which is the equivalent of running

groups "root sys bin" 

How do i create the proper variable argument for execlp to run groups on each user, one at a time?

È stato utile?

Soluzione

One option is to ask /bin/sh to deal with the input the way it normally would. Of course in addition to dealing with spaces, this would also deal with characters like $, #, ~, *, etc., which may or may not be what you want.

execl("/bin/sh", "sh", "-c", ("groups " + args).c_str(), nullptr);

Obviously, don't use this way if the data is user-entered and might contain nasty strings like:

root ;rm *

Otherwise, execl type functions won't work unless you know the number of command-line arguments at compile time. Assuming your args string could have varying numbers of arguments, you'll need execv type functions instead.

std::string args = "root sys bin";

std::vector<std::string> arg_vec;
std::istringstream arg_iss(args);
std::copy(std::istream_iterator<std::string>(arg_iss),
          std::istream_iterator<std::string>(),
          std::back_inserter(arg_vec));

char groups_exec[] = "groups";
std::vector<char*> arg_ptr_vec{ groups_exec };
std::for_each(arg_vec.begin(), arg_vec.end(),
              [&](std::string& arg){ arg_ptr_vec.push_back(&arg[0]); } );
arg_ptr_vec.push_back(nullptr);
execvp("groups", arg_ptr_vec.data());

Altri suggerimenti

The args parameter to execlp is defined as "char *const argv[]", so I think you could do something like

const char *myArgs[3] = {"root, "sys", "bin"};

and then replace args.c_str() with myArgs.

I should admit to having zero experience of writing software for Ubuntu - this is what I would try next were I trying to get execlp to work.

EDIT: This is wrong - I had got mixed up and was looking at execv(), bobah and sleepy42 seem to have got it.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top