UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#1 2015-12-01 11:41 AM

AndrzejB
Member
Registered: 2015-12-01
Posts: 2

revc causes EINVAL error after sending

I am writing program to communicate with X11 server.
First I am sending 12 bytes: send(fd, &out, 12, 0)
next I am reading with blocking loop.
recv returns -1 and errno = 22 (EINVAL = "Invalid argument "). My fd is not in listen mode?

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>>
#include <fcntl.h>
#include <stdint.h>

/** Current protocol version */
#define X_PROTOCOL 11

/** Current minor version */
#define X_PROTOCOL_REVISION 0
/**
* @brief xcb_setup_request_t
**/
typedef struct xcb_setup_request_t {
    uint8_t  byte_order; /**<  */
    uint8_t  pad0; /**<  */
    uint16_t protocol_major_version; /**<  */
    uint16_t protocol_minor_version; /**<  */
    uint16_t authorization_protocol_name_len; /**<  */
    uint16_t authorization_protocol_data_len; /**<  */
    uint8_t  pad1[2]; /**<  */
} xcb_setup_request_t;


typedef struct {
    uint8_t  status;
    uint8_t  pad0[5];
    uint16_t length;
} xcb_setup_generic_t;



static int read_block(const int fd, void *buf, const ssize_t len)
{
    int done = 0;
    while(done < len)
    {
        int ret = recv(fd, ((char *) buf) + done, len - done, 0);
        if(ret > 0)
            done += ret;
        int err = errno;
        if(ret < 0 && errno == EAGAIN)
        {
            fd_set fds;
            FD_ZERO(&fds);
            FD_SET(fd, &fds);
            errno = 0;
            do {
                ret = select(fd + 1, &fds, 0, 0, 0);
            } while (ret == -1 && errno == EINTR);
        }
        if(ret <= 0)
            return ret;
    }
    return len;
}


int main()
{
    char* display_name  = NULL;
    display_name  = getenv("DISPLAY");
/*
   Display environment variable (command "echo $DISPLAY")
   general format this variable is: hostname:D.S
   hostname: computer where rund X server; empty hostname means localhost/unix
   host/unix: the X server for this display is listening at UNIX domain socket /tmp/.X11-unix/XD (so it's only reachable from host)
   hostname:D.S: the X server for this display is listening at TCP port 6000+D
   D: number (usually 0) of display connected to computer
   S: screen number, empty screen means 0
   (see http://askubuntu.com/questions/432255/w … -variable)
*/
#ifdef __hpux
    static const char unix_base[] = "/usr/spool/sockets/X11/";
#else
    static const char unix_base[] = "/tmp/.X11-unix/X";
#endif

    int fd;
    const char *filename = "/tmp/.X11-unix/X0";
    struct sockaddr_un addr;
    strcpy(addr.sun_path, filename);
    addr.sun_family = AF_UNIX;
#ifdef HAVE_SOCKADDR_SUN_LEN
    addr.sun_len = SUN_LEN(&addr);
#endif
    //fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0);
#ifdef SOCK_CLOEXEC
    fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
    if (fd == -1 && errno == EINVAL)
#endif
    {
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd >= 0)
            fcntl(fd, F_SETFD, FD_CLOEXEC);
    }
    //c = xcb_connect_to_fd(fd, 0);
    static const uint32_t endian = 0x01020304;
/* B = 0x42 = MSB first, l = 0x6c = LSB first */
    xcb_setup_request_t out;
    if(htonl(endian) == endian)
        out.byte_order = 0x42;
    else
        out.byte_order = 0x6c;
    out.protocol_major_version = X_PROTOCOL;
    out.protocol_minor_version = X_PROTOCOL_REVISION;
    out.authorization_protocol_name_len = 0;
    out.authorization_protocol_data_len = 0;
    send(fd, &out, 12, 0);
    xcb_setup_generic_t in;
    in.status = 5;
    size_t n = read_block(fd, &in, sizeof(in));
    close(fd);
    return 0;
}

Offline

#2 2015-12-01 12:04 PM

AndrzejB
Member
Registered: 2015-12-01
Posts: 2

Re: revc causes EINVAL error after sending

Simply I forget write connect(fd, &addr, sizeof(addr));

Offline

#3 2015-12-01 07:12 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,230

Re: revc causes EINVAL error after sending

Welcome to our forum!

Glad you solved the problem. I find it very brave of you to write an X client, but hopefully the XCB library takes most of the pain away.

Offline

Board footer

Powered by FluxBB