Hello,
I am totally new to Kotlin and I am trying to call the standard posix function execv. The “__argv” argument accepted by this function is an array of C string pointers, with the last element of the array being null.
I can’t find a find to call the function, which is defined as:
platform.posix 11_posix.knm @CCall
public external fun execv(
@CCall.CString
__path: String?,
__argv: CValuesRef<CPointerVar<ByteVar /* = ByteVarOf<Byte> */> /* = CPointerVarOf<CPointer<ByteVarOf<Byte>>> */>?
): Int
I have:
val args: Sequence<String> = ...
val command: String = ...
val argsPlusNull: Sequence<String?> = args.plus(null)
memScoped {
val a = argsPlusNull.toList().toCStringArray(memScope)
if (execv(command, a) ...
}
Here, the toCStringArray call is invalid because the list element type is String? rather than String.
How can I then call execv with the proper “__argv” argument?
Many thanks !
Hi there,
This is either an oversight or the kotlin wrapper adds the null element on its own under the hood (but I doubt it). I would force the compiler to compile by casting my List<String?> into the non nullable type. The compiler will complain, but you can use @Supress to silence it.
Hello and thank you for reaching out.
Casting does not seem to work, as least not how I did it.
memScoped {
println("Hi from the child 1")
val a0 = args.plus(null).toList()
val a = (a0 as List<String>).toCStringArray(memScope)
println("Hi from the child 2")
println("Will exec $pgm with ${a0.implodeWithCommas()}")
if (execv(pgm, a) == -1)
sysfail("can't execv program '$pgm'")
}
This piece of code is executed as part of the child after a fork(). The message “Hi from the child 1” prints but the second one “Hi from the child 2” does not, as if the cast from List<String?> to List made the program crash. Strangely, I do not get output on stderr.