guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: wayland client in Guile without libwayland-client


From: Matt Wette
Subject: Re: wayland client in Guile without libwayland-client
Date: Fri, 18 Nov 2022 14:58:02 -0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2

On 11/18/22 2:34 PM, Maxime Devos wrote:



On 18-11-2022 17:54, Matt Wette wrote:
cm-buf is a bytevector of control messages (`man cmsg`).  To deal
with control messages I have generated these procedures:

   (cmsg-list->bytevector cmsg-list) => bytevector
   (bytevector->cmsg-list bytevector) => cmsg-list

I have previously written an implementation for encoding/decoding cmsg at <https://git.gnunet.org/gnunet-scheme.git/tree/gnu/gnunet/util/cmsg.scm>, with a bunch of tests at <https://git.gnunet.org/gnunet-scheme.git/tree/tests/cmsg.scm> (no bindings for sendmsg, recvmsg!, though).

To compare, could you share your implementation of cmsg-list->bytevector and bytevector->cmsg-list?.

Greetings,
Maxime.
OK.  I have not used yet.

And I want to mention, because my sendmsg() recvmsg() explanation was not clear,
those routines will accept a bytevector or vector of bytevectors for iobuf.

Here is the cmsg code.  I have not used it yet, so not really tested.
I will check your stuff out.
#define CMSG_SZ(cmsg) ((cmsg->cmsg_len) - sizeof(struct cmsghdr))

size_t
scm_c_cmsg_len (SCM cmsg)
{
  SCM bv;
  size_t ln;

  // SCM_ASSERT (scm_is_vector (cmsg), cmsg, 0, scm_c_cmsg_len);
  bv = scm_c_vector_ref (cmsg, 2);
  // SCM_ASSERT (scm_is_bytevector (bv), cmsg, 0, scm_c_cmsg_len);
  ln = CMSG_LEN (scm_c_bytevector_length (bv));
  return ln;
}

SCM_DEFINE(scm_cmsg_list_to_bytevector, "cmsg-list->bytevector", 1, 0, 0,
       (SCM cmsgl),
       "control message list to bytevector")
#define FUNC_NAME s_scm_cmsg_list_to_bytevector
{
  SCM ml, cm, bv, cb;
  size_t ln;
  struct cmsghdr *cmsg;

  for (ml = cmsgl, ln = 0; ml != SCM_EOL; ml = SCM_CDR (ml)) {
    cm = SCM_CAR (ml);
    ln += CMSG_ALIGN (scm_c_cmsg_len (cm));
  }

  bv = scm_c_make_bytevector (ln);

  cmsg = (struct cmsghdr *) SCM_BYTEVECTOR_CONTENTS (bv);
  memset(cmsg, 0, ln);
  for (ml = cmsgl, ln = 0; ml != SCM_EOL; ml = SCM_CDR (ml)) {
    cm = SCM_CAR (ml);
    cmsg->cmsg_len = scm_c_cmsg_len (cm);
    cmsg->cmsg_level = scm_to_int (scm_c_vector_ref (cm, 0));
    cmsg->cmsg_type = scm_to_int (scm_c_vector_ref (cm, 1));
    cb = scm_c_vector_ref (cm, 2);
    memcpy (CMSG_DATA(cmsg), SCM_BYTEVECTOR_CONTENTS (cb),
        scm_c_bytevector_length (cb));
    cmsg = (struct cmsghdr *)((unsigned char *) cmsg
                  + CMSG_ALIGN (cmsg->cmsg_len));
  }

  return bv;
}
#undef FUNC_NAME

SCM_DEFINE(scm_bytevector_to_cmsg_list, "bytevector->cmsg-list", 1, 0, 0,
       (SCM bv),
       "extract cmsg-list from bytevector")
#define FUNC_NAME s_scm_bytevector_to_cmsg_list
{
  SCM res, bv1, ctl;
  struct msghdr *mhp;
  struct cmsghdr *cmsg;
  union { struct msghdr mh; double d; } x;

  mhp = &x.mh;

  SCM_VALIDATE_BYTEVECTOR (1, bv);
  mhp->msg_control = (struct cmsghdr *) SCM_BYTEVECTOR_CONTENTS (bv);
  mhp->msg_controllen = SCM_BYTEVECTOR_LENGTH (bv);

  res = SCM_EOL;
  for (cmsg = CMSG_FIRSTHDR (mhp); cmsg != NULL;
       cmsg = CMSG_NXTHDR (mhp, cmsg)) {
    ctl = scm_c_make_vector (3, SCM_BOOL_F);
    scm_c_vector_set_x (ctl, 0, scm_from_int (cmsg->cmsg_level));
    scm_c_vector_set_x (ctl, 1, scm_from_int (cmsg->cmsg_type));
    bv1 = scm_c_make_bytevector (CMSG_SZ (cmsg));
    memcpy(SCM_BYTEVECTOR_CONTENTS (bv1), CMSG_DATA (cmsg), CMSG_SZ (cmsg));
    scm_c_vector_set_x (ctl, 2, bv1);
    res = scm_cons(ctl, res);
  }
  res = scm_reverse_x (res, SCM_UNDEFINED);
  return res;
}
#undef FUNC_NAME



reply via email to

[Prev in Thread] Current Thread [Next in Thread]