buffet / kiwmi

A fully programmable Wayland Compositor
Mozilla Public License 2.0
585 stars 22 forks source link

[FR] allow spawning process via `execv(argv)` rather than `sh -c` #80

Open benaryorg opened 1 year ago

benaryorg commented 1 year ago

The spawn method already uses execl(2) under the hood, it would be nice to expose that interface to Lua, to allow spawning of processes without arduous shell escaping.

https://github.com/buffet/kiwmi/blob/17814972abe6a8811a586fa87c99a2b16a86075f/kiwmi/luak/kiwmi_server.c#L238-L260

I'm not familiar with the C interfaces of Lua, but considering Lua is dynamically typed, would it be possible (or idiomatic) to reuse the same method and distinguish based on type (i.e. string vs. list of string) and based on that call the appropriate method? Something along those lines:

if (is_string(arg))
{
  // fork off
  execl("sh", "-c", arg);
}
else
{
  assert_list(arg);
  assert_not_empty(arg);
  assert_all_elements_string(arg);

  // fork off

  unsigned int length = len(arg);
  const char *argv = malloc(sizeof(char *) * (length + 1));
  if(!argv) { err(1, "malloc for argv"); }
  argv[length] = NULL;
  for(int i = 0;i < length; i++)
  {
    argv[i] = lua_tostring(lua_index(arg, i));
  }
  execv(argv[0], argv);
}

That was a lot more verbose than I intended, and the lua functions are definitely not what they should be, also err(3) is from libbsd, and my C is generally rusty so I'm not at all sure whether this resembles modern coding style. Considering that all the heavy lifting would be done after the fork (to avoid (de)allocations in the parent) at least the cleanup is cheap thanks to the exec-or-err handling.

If squashing the functionality into the same method is not an idiomatic thing then a separate kiwmi:exec([command]) would be nice.