Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package jdk.internal.ffi.generated;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using jdk.internal.ffi.generated.** for jextract generated code is good. I'm not sure this is the right place for ErrnoUtils.


import jdk.internal.ffi.generated.errno.errno_h;

import java.io.IOException;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.nio.charset.StandardCharsets;

// Errno utility for macosx platform
public final class ErrnoUtils {
private ErrnoUtils() {
}

private static final long ERRNO_STRING_HOLDER_ARRAY_SIZE = 256L;

public static IOException IOExceptionWithErrnoString(int errno, String message) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming is a bit confusing here, minimally need a method description so we can quickly understand the relationship between "message" and strerror(errno).

try (Arena arena = Arena.ofConfined()) {
MemorySegment buf = arena.allocate(ERRNO_STRING_HOLDER_ARRAY_SIZE);
if (errno_h.strerror_r(errno, buf, ERRNO_STRING_HOLDER_ARRAY_SIZE) == 0) {
String errnoMsg = buf.getString(0, StandardCharsets.UTF_8);
return new IOException(message + " " + errnoMsg);
} else {
// failed to convert errno to string - output errno value
return new IOException(message + " Errno: " + errno);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

// Generated by jextract

package jdk.internal.ffi.generated.errno;

import jdk.internal.ffi.util.FFMUtils;

import java.lang.invoke.*;
import java.lang.foreign.*;

@SuppressWarnings("restricted")
public class errno_h {

errno_h() {
// Should not be called directly
}

private static final int EINTR = (int)4L;
/**
* {@snippet lang=c :
* #define EINTR 4
* }
*/
public static int EINTR() {
return EINTR;
}

private static class strerror_r {
public static final FunctionDescriptor DESC = FunctionDescriptor.of(
FFMUtils.C_INT,
FFMUtils.C_INT,
FFMUtils.C_POINTER,
FFMUtils.C_LONG
);

public static final MemorySegment ADDR = FFMUtils.findOrThrow("strerror_r");

public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC);
}

/**
* Function descriptor for:
* {@snippet lang=c :
* int strerror_r(int __errnum, char *__strerrbuf, size_t __buflen)
* }
*/
public static FunctionDescriptor strerror_r$descriptor() {
return strerror_r.DESC;
}

/**
* Downcall method handle for:
* {@snippet lang=c :
* int strerror_r(int __errnum, char *__strerrbuf, size_t __buflen)
* }
*/
public static MethodHandle strerror_r$handle() {
return strerror_r.HANDLE;
}

/**
* Address for:
* {@snippet lang=c :
* int strerror_r(int __errnum, char *__strerrbuf, size_t __buflen)
* }
*/
public static MemorySegment strerror_r$address() {
return strerror_r.ADDR;
}

/**
* {@snippet lang=c :
* int strerror_r(int __errnum, char *__strerrbuf, size_t __buflen)
* }
*/
public static int strerror_r(int __errnum, MemorySegment __strerrbuf, long __buflen) {
var mh$ = strerror_r.HANDLE;
try {
if (FFMUtils.TRACE_DOWNCALLS) {
FFMUtils.traceDowncall("strerror_r", __errnum, __strerrbuf, __buflen);
}
return (int)mh$.invokeExact(__errnum, __strerrbuf, __buflen);
} catch (Throwable ex$) {
throw new AssertionError("should not reach here", ex$);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/**
* Defines native structures for errno APIs.
* Generated with the following jextract command:
* {@snippet lang = "Shell Script":
*
* HEADER_NAME=errno.h
* echo "#include <errno.h>" > $HEADER_NAME
* echo "#include <string.h>" >> $HEADER_NAME
*
* jextract --target-package jdk.internal.ffi.generated.errno \
* --include-constant EINTR \
* --include-function strerror_r \
* $HEADER_NAME
* }
*
* After generation of native bindings, the layouts for the C builtin layouts and other
* variables/methods not specific to a component area are moved to the {@code BindingUtils} class
* for future reusability.
*
*/

package jdk.internal.ffi.generated.errno;
Loading