C - 执行 /usr/bin/xfce4-terminal 给出"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.中fence post错误的来源

有关某些解释/理由,请参阅代码注释。

#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 environmentn",
                        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;
}

最新更新