[英]execve of /usr/bin/xfce4-terminal gives “Session manager variable not defined”
我试图有一个进程派生并在子进程中运行execve
,以便它将打开一个新的终端窗口并在那里执行自定义命令。
我要执行的程序是gestore
这些是我传递给execve
的参数:
char * argv_exec[5];
argv_exec[0]="/usr/bin/xfce4-terminal";
argv_exec[1]="--geometry";
argv_exec[2]="480x320";
argv_exec[3]="-x";
argv_exec[4]="./gestore"; // the program I want to execute in new window
argv_exec[5]=NULL;
char sess_m[80];
strcat(sess_m,"SESSION_MANAGER=");
strcat(sess_m,getenv("SESSION_MANAGER"));
char * envp[3];
envp[0]="DISPLAY=:0.0";
envp[1]=sess_m;
envp[2]=NULL;
这里我叫execve
:
if(pid_tv==0)
if(execve(argv_exec[0],argv_exec,&envp)==-1) {...}
但是我一直在获取Session manager variable not defined
。
有人对为什么这种方法不起作用或如何更好地提出建议吗?
进行了一些重写,既显示了对过程环境的更多惯用用法(请参阅environ(7)
),又演示了避免硬连接数组大小的一些方法:始终是C语言中篱笆墙错误的源头。
有关某些说明/理由,请参见代码注释。
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char **environ; /* see environ(7) */
int
main(void)
{
char *argv_exec[] = {
"/usr/bin/xfce4-terminal",
"--geometry",
"480x320",
"-x",
"./gestore",
NULL };
/*
* Structure to drive search for a few variables present in
* current environment, and construct a new, minimal, environment
* containing just those values. Use the direct value from the
* current process's environ variable to set "value" (the string
* of the form "NAME=VALUE"). Just add more entries to nv to handle
* more variables; the code below will adjust sizes.
*
* Any value missing in the environment will be an error.
*/
struct {
char *name;
char *value;
} nv[] = {
{ "DISPLAY", NULL },
{ "SESSION_MANAGER", NULL }
};
/* size new_envp to have one more entry than nv */
char *new_envp[sizeof(nv) / sizeof(nv[0]) + 1];
char **e;
int i, error_flag;
pid_t pid;
/*
* For each variable needed...
*/
for (i = 0; i < sizeof(nv) / sizeof(nv[0]); i++) {
/* ...search in current environment */
for (e = environ; *e; e++) {
size_t slen = strlen(nv[i].name);
if (strncmp(*e, nv[i].name, slen) == 0 && (*e)[slen] == '=') {
nv[i].value = *e;
break;
}
}
}
/*
* Check that we found all values, setting up new_envp as we go.
*/
error_flag = 0;
for (i = 0; i < sizeof(nv) / sizeof(nv[0]); i++) {
if (nv[i].value == NULL) {
(void) fprintf(stderr, "%s not set in environment\n",
nv[i].name);
error_flag = 1;
} else {
new_envp[i] = nv[i].value;
}
}
if (error_flag) {
return 1;
}
new_envp[i] = NULL;
/* very minimal fork/exec processing */
pid = fork();
if (pid == -1) {
perror("fork");
return 1;
}
if (pid == 0) {
(void) execve(argv_exec[0], argv_exec, new_envp);
/*
* If execve succeeded, the invoked program has
* replaced this process, and will either run or
* (presumably) report its own errors. If we're
* still in control, the execve failed, so print
* an error and exit.
*/
perror(argv_exec[0]);
return 1;
} else {
if (wait(0) != pid) {
perror("wait");
return 1;
}
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.