If I need access to the C fcntl(2):
int fcntl(int, int, ...)
can I get the swift-package-manager or swift-build-tool to compile C code that wraps this into a non-vararg version:
int SocketHelper_fcntl_setFlags(int const fildes, int const flags)
{
return fcntl(fildes, F_SETFL, flags);
}
int SocketHelper_fcntl_getFlags(int const fildes)
{
return fcntl(fildes, F_GETFL);
}
?
The “System Modules” approach from <https://github.com/apple/swift-package-manager/blob/master/Documentation/SystemModules.md> doesn’t really work. I’d have to create a .a file and put it into a /usr/lib/SocketHelper.so and /usr/include/SocketHelper.h -- which doesn’t make much sense for something this specific and trivial.
Should I look into libffi for this particular case?
/Daniel
I solved it like this:
typealias fcntlType = @convention(c) (CInt, CInt, CInt) -> (CInt)
let fcntlAddr = dlsym(UnsafeMutablePointer<Void>(bitPattern: Int(-2)), "fcntl")
let fcntlType: myFcntl = unsafeBitCast(fcntlAddr, fcntlType.self)
which admittedly is a bit tacky, but it works for now.
/Daniel
···
On 17 Dec 2015, at 22:47, Daniel Eggert via swift-users <swift-users@swift.org> wrote:
If I need access to the C fcntl(2):
int fcntl(int, int, ...)
can I get the swift-package-manager or swift-build-tool to compile C code that wraps this into a non-vararg version:
int SocketHelper_fcntl_setFlags(int const fildes, int const flags)
{
return fcntl(fildes, F_SETFL, flags);
}
int SocketHelper_fcntl_getFlags(int const fildes)
{
return fcntl(fildes, F_GETFL);
}
?
Hi Daniel,
I’m pretty sure that Swift 2.2 master supports fcntl on both linux and darwin platforms. What version are you using?
This support is done with “overlays” that you can see here:
https://github.com/apple/swift/blob/master/stdlib/public/Glibc/Glibc.swift
https://github.com/apple/swift/blob/master/stdlib/public/SDK/Darwin/Darwin.swift
-Chris
···
On Dec 17, 2015, at 1:47 PM, Daniel Eggert via swift-users <swift-users@swift.org> wrote:
If I need access to the C fcntl(2):
int fcntl(int, int, ...)
can I get the swift-package-manager or swift-build-tool to compile C code that wraps this into a non-vararg version:
Joe_Groff
(Joe Groff)
4
This is broken, since fcntl is variadic and you're calling it like a non-variadic function. C doesn't guarantee that variadic and non-variadic ABIs are compatible—this will break watchOS and ARM64 iOS/tvOS, for instance. The latest open-source builds should provide a working fcntl in the Darwin/Glibc overlays.
-Joe
···
On Dec 18, 2015, at 1:52 AM, Daniel Eggert via swift-users <swift-users@swift.org> wrote:
On 17 Dec 2015, at 22:47, Daniel Eggert via swift-users <swift-users@swift.org> wrote:
If I need access to the C fcntl(2):
int fcntl(int, int, ...)
can I get the swift-package-manager or swift-build-tool to compile C code that wraps this into a non-vararg version:
int SocketHelper_fcntl_setFlags(int const fildes, int const flags)
{
return fcntl(fildes, F_SETFL, flags);
}
int SocketHelper_fcntl_getFlags(int const fildes)
{
return fcntl(fildes, F_GETFL);
}
?
I solved it like this:
typealias fcntlType = @convention(c) (CInt, CInt, CInt) -> (CInt)
let fcntlAddr = dlsym(UnsafeMutablePointer<Void>(bitPattern: Int(-2)), "fcntl")
let fcntlType: myFcntl = unsafeBitCast(fcntlAddr, fcntlType.self)
which admittedly is a bit tacky, but it works for now.