libgit2 / libgit2/libgit2

Confusing "Resource temporarily unavailable" error on timeout with OpenSSL backend

Open
#7,301 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
10.6k
Forks
2.7k
PR merge metrics
No merged PRs in 30d

Description

Consider this example:

#include <git2.h>
#include <assert.h>
#include <stdio.h>

int
main ()
{
  int err;
  err = git_libgit2_init ();
  assert (err == 1);

  git_clone_options opts;
  err = git_clone_init_options (&opts, GIT_CLONE_OPTIONS_VERSION);
  assert (err == 0);

  err = git_libgit2_opts (GIT_OPT_SET_SERVER_TIMEOUT, 1);
  assert (err == 0);

  git_repository *repo;
  err = git_clone (&repo, "https://git.guix.gnu.org/guix.git", "/tmp/example",
		   &opts);
  assert (err != 0);

  const git_error *gerr;
  gerr = giterr_last ();
  fprintf (stderr, "last error: %s\n", gerr->message);

  return 0;
}

When running it (using libgit2 1.9.2 on Linux, with the OpenSSL backend), I get:

last error: SSL error: syscall failure: Resource temporarily unavailable

... which is somewhat confusing.

Here's what we see from strace:

socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_TCP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("46.224.9.33")}, 16) = 0
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
...
sendto(3, "\26\3\1\6\4\1\0\6\0\3\3m\205\362N]I5|\3452\341b\v\316`9'*/\225?"..., 1545, 0, NULL, 0) = 1545
recvfrom(3, 0x19d1853, 5, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}], 1, 1)     = 0 (Timeout)
close(3)                                = 0

This corresponds to socket_read, calling recv then poll.

The issue here is that the error reported ("Resource temporarily available") is the wrong one; it should say "Timeout" (or similar). socket_read does try to convey that error but it gets lost in the abstraction layers (BIO, streams, etc.).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the example with the one-second server timeout and tracing socket_read through the BIO and stream abstraction layers. The work is done when the timeout is preserved and reported as a timeout rather than "Resource temporarily unavailable".

Written by the indexing model from the issue text.

Assessment

Tech stack
c, git
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.