尝试通过Execve发送消息ID

问题描述 投票:0回答:1

[我编辑了帖子,希望更符合格式]

所以问题是我试图使用 execve 将消息队列 ID 从父级传递给子级。然而每次这样做,我都能编译它,但收到错误消息

[xcb] Unknown sequence number while processing queue
[xcb] You called XInitThreads, this is not your fault
[xcb] Aborting, sorry about that.

线程工作,只是使用 execve 创建一个新窗口给了我这个错误,该程序旨在通过在窗口中按 C 创建另一个窗口。

编译器代码: gcc [ ].c -Wall -lX11 -pthread

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <pthread.h>
#include <sys/msg.h>
#include <sys/types.h>


struct Global {
    Display *dpy;
    Window win;
    GC gc;
    int xres, yres;
} g;

struct mesg_buffer {
    long type;
    char text[100];
} mymsg;


int done = 0;
void x11_cleanup_xwindows(void);
void x11_init_xwindows(void);
void x11_clear_window(void);
void check_mouse(XEvent *e);
int check_keys(XEvent *e);
void render(void);
int mqid;
int myargc;
char **myargv;
char **myenvp;

void *Thread(void *arg){
    return (void *)0;
}

int main(int argc, char *argv[], char *envp[])
{
    myargc = argc;
    myargv = argv;
    myenvp = envp;
    XEvent e;
    int countdown = 0;
    int IP_check = 0;
    pthread_t tid;

    if (argc > 1)
        countdown = atoi(argv[1]);

    if (argc > 2){
        if (strcmp(argv[2], "Child") == 0)
           pthread_create(&tid, NULL, Thread, (void *)1);}

    if (argc > 3){
        mqid = atoi(argv[3]);
        ++IP_check;}

if(IP_check == 0)
mqid = msgget(IPC_PRIVATE, IPC_CREAT | 0666);


x11_init_xwindows();
while (!done) {
    /* Check the event queue */
    while (XPending(g.dpy)) {
        XNextEvent(g.dpy, &e);
        done = check_keys(&e);
        render();
    }
    usleep(4000);
    if (countdown > 0){
        if (--countdown == 0){
            done = 1;
        }

    }
}
x11_cleanup_xwindows();
return 0;
}

void x11_cleanup_xwindows(void)
{
    XDestroyWindow(g.dpy, g.win);
    XCloseDisplay(g.dpy);
}

void x11_init_xwindows(void)
{
    int scr;

    if (!(g.dpy = XOpenDisplay(NULL))) {
        fprintf(stderr, "ERROR: could not open display!\n");
        exit(EXIT_FAILURE);
    }
    scr = DefaultScreen(g.dpy);
    g.xres = 400;
    g.yres = 200;
    g.win = XCreateSimpleWindow(g.dpy, RootWindow(g.dpy, scr), 1, 1,
                        g.xres, g.yres, 0, 0x00ffffff, 0x00000000);
XStoreName(g.dpy, g.win, "cs3600 xwin sample");
g.gc = XCreateGC(g.dpy, g.win, 0, NULL);
XMapWindow(g.dpy, g.win);
XSelectInput(g.dpy, g.win, ExposureMask | StructureNotifyMask |
                            PointerMotionMask | ButtonPressMask |
                            ButtonReleaseMask | KeyPressMask);
}
//
//Where I believe the issue happens
//removing temp from xargv[] will get it to run normally
// though I need to send temp through. 
//
void make_child_win(){
    char temp [50];
    sprintf(temp, "%i", mqid);
    int cpid = fork();
    if (cpid == 0){
        char *xargv[] = {myargv[0], "0" , "Child", temp};
        execve(myargv[0], xargv, myenvp);
        }

}

int check_keys(XEvent *e)
{
    int key;

    if (e->type != KeyPress && e->type != KeyRelease)
        return 0;
    key = XLookupKeysym(&e->xkey, 0);
if (e->type == KeyPress) {
    switch (key) {
        case XK_c:
              make_child_win();
            break;
        case XK_Escape:
          msgctl(mqid, IPC_RMID, NULL);
        return 1;
    }
}
    return 0;
}

void render(void)
{
} 
c pthreads execve
1个回答
0
投票

将我的评论转化为答案。

你有:

char *xargv[] = {myargv[0], "0" , "Child", temp};
execve(myargv[0], xargv, myenvp);

您需要一个空指针来终止传递给

execve()
的 argv,因此您应该使用:

char *xargv[] = { myargv[0], "0" , "Child", temp, 0 };

您可以写

NULL
而不是裸露的
0
,但这在这种情况下没有操作上的差异(但在其他情况下差异可能很大,例如使用
execl()
代替
execve()
)。

© www.soinside.com 2019 - 2024. All rights reserved.