Call to execv: need to create an array of nullable C string pointers

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.