cpthreadsexecve

Trying to send Message ID through Execve


The problem is I'm trying to pass a message queue ID from a parent to child using execve. However, each time to do, I am able to compile it but get the error message of:

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

The threads work; it's just that making a new window using execve gives me that error. The program is meant to create another window by pressing C in the window.

compiler code:

gcc [ ].c -Wall -lX11 -pthread

code:

#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)
{
} 

Solution

  • Transferring my comment into an answer.

    You have:

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

    You need a null pointer to terminate the argv passed to execve(), so you should use:

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

    You could write NULL instead of the bare 0, but it makes no operational difference in this context (but there are other contexts where the difference could be significant, such as using execl() instead of execve()).