Reputation: 4681
I'm successfully using popen()
to run commands from within my C program. As I understand, it uses fork()
and exec()
(or variants of those) behind the curtains. This works very well:
FILE *fd = popen("xterm", "r");
pclose(fd);
... will bring up a new xterm window, as expected.
Now I'm trying to achieve the same with posix_spawn()
, which I understand to be possibly more resource-friendly, especially if we don't plan on communicating with the new child process:
/* p.we_wordv contains the argv, index 0 holds the actual command */
pid_t pid;
posix_spawnp(&pid, p.we_wordv[0], NULL, NULL, p.we_wordv, NULL);
... but this, for xterm
as the command, yields the following on the parent's output:
xterm: Xt error: Can't open display:
xterm: DISPLAY is not set
Trying to launch other processes will yield other error messages, fail silently, or, in some cases like ls
, work as expected. This makes it a bit hard for me to actually see a pattern yet.
Can you point out what is causing the second approach to behave differently than the first?
Upvotes: 3
Views: 1759
Reputation: 28278
The message DISPLAY is not set
tells you that xterm
didn't find the DISPLAY
environment variable. All graphical-output programs use this environment variable to connect to your screen.
It didn't find the variable because the environment was empty (it's the last NULL
in your posix_spawnp
function call). It seems that popen
reuses the environment of current process, so it doesn't have this problem.
You might want to pass a manually-created environment, containing only the needed stuff, or just pass whatever environment your process has. The latter is more flexible (xterm
will inherit various configuration settings from your process, which inherits them from your shell) but may be a security risk.
To access the environment of your process, use the environ
global variable or change your main
function to receive an additional parameter:
int main(int argc, char *argv[], char *envp[])
{
...
posix_spawnp(&pid, p.we_wordv[0], NULL, NULL, p.we_wordv, envp);
}
Upvotes: 4