Question

It's possible to get Openoffice to accept UNO connections over a unix domain socket with:

$soffice -headless -invisible -nocrashreport -nodefault -nologo -nofirststartwizard -norestore -conversionmode -accept='pipe,name=marcin_OOffice;urp;StarOffice.ComponentContext'

netstat shows that the domain socket is created at /tmp/OSL_PIPE_1001_marcin_OOffice. That's fine, but as I will be running this on a shared host, I'd like to have the socket somewhere else, e.g. in my home drive. However, passing a full file path (either relative or absolute) as the name parameter results in no socket being created.

Is there a way I can influence where the socket is created, e.g. with an environment variable?

EDIT: Setting TMP and TMPDIR environment variables does not affect this behaviour. I'm running this on linux.

Was it helpful?

Solution

Since there doesn't seem to be an "official" way of controlling where the socket gets created you can go down the "sledgehammer to crack a nutshell" road by writing your own shared object that interposes on connect() and rewrites any AF_FILE addresses in /tmp:

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
#include <assert.h>
#include <linux/un.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>

int connect(int sockfd, const struct sockaddr *addr,
            socklen_t addrlen) 
{
  static int (*real_connect)(int, const struct sockaddr *, socklen_t) = NULL;
  if (!real_connect)
    real_connect = dlsym(RTLD_NEXT, "connect");

  if (addr->sa_family == AF_FILE) {
    // mutate sockaddr
    assert(addrlen >= sizeof(struct sockaddr_un));
    const struct sockaddr_un u = { AF_UNIX, "/foo/bar/path" };
    // but only if it is in /tmp
    if (!strncmp(((const struct sockaddr_un*)addr)->sun_path, "/tmp", 4)) {
      return real_connect(sockfd, (const struct sockaddr*)&u, sizeof u);
    }
  }
  return real_connect(sockfd, addr, addrlen);
}

Compile with:

gcc -Wall -Wextra test.c -ldl -shared -o interpose.so -fPIC

And then run as:

LD_PRELOAD=./interpose.so soffice -headless -invisible -nocrashreport -nodefault -nologo -nofirststartwizard -norestore -conversionmode -accept='pipe,name=marcin_OOffice;urp;StarOffice.ComponentContext'

which seems to work from reading the strace output (but I have no idea how to actually exercise the socket to prove that it really works).

OTHER TIPS

You should interpose between bind() (same signature as connect) as this is where the socket is created, then for the clients interpose between connect().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top