Skip to content

Conversation

@MisterDA
Copy link
Contributor

I did a review of ocamlmerlin.c. I found two issues:

  1. Erroneous size computation of the struct sockaddr_un. On some BSD systems the struct sockaddr family of types have a leading sxx_len field. It was not taken into account. Use offsetof, as described by POSIX, to compute the socklen.
    https://man.freebsd.org/cgi/man.cgi?unix(4)
    https://man7.org/linux/man-pages/man7/unix.7.html
    https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_un.h.html
  2. Functions from WinAPI don't set errno, and their failure code can be retrieved with GetLastError and the error string with FormatMessage. Functions from the CRT do set errno, and perror can be used to display the error string.

There's also a few patches that improve the code quality, in my opinion. It now assumes a C99 compiler with (optionally) C2y extensions. For reference, the OCaml runtime requires at least C11.

@xvw
Copy link
Collaborator

xvw commented Nov 19, 2025

Oh wow! I think it deserve a Changelog entry !

@voodoos
Copy link
Collaborator

voodoos commented Nov 19, 2025

Thanks a lot @MisterDA ! Do you know if this could be linked to #1993 ? Or if it's another set of (your?) patches we didn't backport to 413 ?

@MisterDA
Copy link
Contributor Author

MisterDA commented Nov 19, 2025

Thanks a lot @MisterDA ! Do you know if this could be linked to #1993 ? Or if it's another set of (your?) patches we didn't backport to 413 ?

Ah yes, I think this patch will fix the warning encountered by the user; but the build failure is unrelated. This patch series doesn't apply cleanly to v4.7-413, unfortunately. The opam files for these old merlin version are missing constraints on menhir.

# syntax=docker/dockerfile:1
FROM ocaml/opam:ubuntu-25.04-ocaml-4.13
RUN sudo ln -sf /usr/bin/opam-2.4 /usr/bin/opam && opam init --reinit -ni
ADD --keep-git-dir --link --chown=1000:1000 https://github.com/ocaml/merlin.git#v4.7-413 /home/opam/merlin
RUN git config --global --add safe.directory ~/merlin
WORKDIR /home/opam/merlin
RUN --mount=type=cache,target=/home/opam/.opam/download-cache,sharing=locked,uid=1000,gid=1000 \
    opam install -y --deps-only --with-dev --formula='"menhir" {<= "20220210"}' merlin.4.7-413
RUN patch -p1 <<'EOF'
diff --git a/src/frontend/ocamlmerlin/dune b/src/frontend/ocamlmerlin/dune
index faa01b93..cc549032 100644
--- a/src/frontend/ocamlmerlin/dune
+++ b/src/frontend/ocamlmerlin/dune
@@ -14,7 +14,7 @@
  (modules (:standard \ gen_ccflags))
  (libraries config yojson merlin_analysis merlin_kernel
             merlin_utils os_ipc ocaml_parsing query_protocol query_commands
-            ocaml_typing ocaml_utils seq))
+            ocaml_typing ocaml_utils))

 (executable
  (name      gen_ccflags)
EOF
ADD --chown=1000 --link https://github.com/ocaml/merlin/pull/1998.diff 1998.diff
RUN patch -p1 < 1998.diff
RUN opam exec -- make -j1

@MisterDA
Copy link
Contributor Author

Oh wow! I think it deserve a Changelog entry !

Could you do that for me? 🙏

@MisterDA MisterDA marked this pull request as draft November 25, 2025 11:05
@MisterDA
Copy link
Contributor Author

Marking as draft because the CI hasn't run, and there are errors with my patches on Windows. I'll circle back to this.

On Windows, use [GetTempPath2][] if available or [GetTempPath][] to
retrieve the temporary directory path.

On other systems, follow the [XDG Base Directory Specification][XDG]
and put the socket file in the XDG runtime directory. It is indicated
by the `XDG_RUNTIME_DIR` environment variable, that is always set on
platforms implementing the spec. Otherwise, fallback to `TMPDIR` or
`/tmp`.

[GetTempPath2]: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
[GetTempPath2]: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
[XDG]: https://specifications.freedesktop.org/basedir/latest/
In C, arrays passed as arguments to functions decay into pointers, and
the size information is lost. One way to partially retain this
information is to use `static n` with `n` being the array size: the
compiler now knows that the first `n` elements after the pointed
address can be accessed. This C99 feature is unfortunately not
supported by MSVC (but supported by clang-cl).
- make the function static;
- don't use K&R-style declaration, compilers now reject it before
  C23. After C23 `f(void)` is similar to `f()`.
Quoting POSIX 2024:

> The size of sun_path is required to be constant, but intentionally
> does not have a specified name for that constant. Historically,
> different implementations used different sizes. For example, 4.3 BSD
> used a size of 108, and 4.4 BSD used a size of 104. Since most
> implementations originate from BSD versions, the size is typically
> in the range 92 to 108. An application can deduce the size by using
> `sizeof(((struct sockaddr_un *)0)->sun_path)`.
It works with mingw-w64 too.

    warning: '__p__environ' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]

https://gcc.gnu.org/onlinedocs/gcc/Microsoft-Windows-Variable-Attributes.html#index-dllimport-variable-attribute
to count the number of elements in an array.
`perror` can be used with functions from the CRT that set `errno`,
otherwise `GetLastError` and `FormatMessage` have to be used instead.
_snprintf doesn't null-terminate strings.
MSVCRT doens't provide snprintf, but if __USE_MINGW_ANSI_STDIO is
defined, then mingw-w64 will provide this function.
There are environments where mingw-w64 is configured with MSVCRT, and
others where it is configured with UCRT. It seems safer to use the
compatibility shims.
UCRT provides snprintf, and MSVC defaults to UCRT.
@MisterDA MisterDA force-pushed the ocamlmerlin.c branch 2 times, most recently from 765c5f4 to 73c3461 Compare November 25, 2025 18:08
@MisterDA MisterDA force-pushed the ocamlmerlin.c branch 2 times, most recently from e1e64bc to 18a16e8 Compare November 25, 2025 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants