[swift-users] C vararg: Swift Package Manager and System Modules

Joe Groff jgroff at apple.com
Fri Dec 18 15:29:24 CST 2015


> On Dec 18, 2015, at 1:52 AM, Daniel Eggert via swift-users <swift-users at swift.org> wrote:
> 
>> On 17 Dec 2015, at 22:47, Daniel Eggert via swift-users <swift-users at 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.

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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20151218/351e876e/attachment.html>


More information about the swift-users mailing list