shkhln / linuxulator-steam-utils

Steam launcher for FreeBSD
MIT License
128 stars 12 forks source link

Update for Wiki: "Half Life 2: Update" (id: 290930) works #10

Closed netchild closed 4 years ago

netchild commented 4 years ago

Hi,

for the compatibility page in thw wiki: ID 290930 (Half Life 2: Update") is playable. Hangs on exit.

Bye, Alexander.

shkhln commented 4 years ago

Ok, thanks.

shkhln commented 4 years ago

Hangs on exit.

Apparently, these games bundle some ancient CEF version (what for? I don't think it's even used anywhere in the game UI), which deadlocks on initialization after being unable to create a PF_NETLINK / NETLINK_ROUTE socket. The easiest way to work around the issue would be this preloadable snippet:

// disable CEF entirely
int cef_initialize() {
  return -1;
}

Alternatively, something like that also works:

static int fake_netlink_fd = -1;

__attribute__((constructor))
static void init_netlink_fd() {

  int inout[2];
  {
    int err = pipe(inout);
    assert(err == 0);
  }

  fake_netlink_fd = inout[1];
}

static int (*libc_socket)(int, int, int) = NULL;

int socket(int domain, int type, int protocol) {

  if (!libc_socket) {
    libc_socket = dlsym(RTLD_NEXT, "socket");
  }

  if (domain == PF_NETLINK) {
    return fake_netlink_fd;
  } else {
    return libc_socket(domain, type, protocol);
  }
}

static int (*libc_bind)(int, const struct sockaddr*, socklen_t) = NULL;

int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen) {

  if (!libc_bind) {
    libc_bind = dlsym(RTLD_NEXT, "bind");
  }

  if (sockfd == fake_netlink_fd) {
    return fake_netlink_fd;
  } else {
    return libc_bind(sockfd, addr, addrlen);
  }
}
shkhln commented 6 months ago

I haven't seen this issue for a while, so I'm going to assume it was fixed by https://www.freebsd.org/status/report-2022-10-2022-12/netlink/.