Hello everyone,

I am using ctypes in order to passing null pointers as input of Unix syscalls.
So far we used the Unix OCaml library to use syscalls (open, chdir, stat),
but it does not allow passing null pointers as input paths of the syscalls (i.e. mkdir NULL is not possible using OCaml Unix.mkdir).

The thing is I would like to avoid implementing again the logic of Unix operations after having create ctypes stubs, instead I was successful so far in using the Unix stubs as my C functions. For instance I can have:

let my_mkdir = Foreign.foreign "unix_mkdir" ~checkerrno:true (string_opt @-> returning int)

Now this does not work with the stat syscall, because it returns a data structure. The data structure returned is an OCaml type (indeed it is a Unix C stub I am using), ctypes expects a C structure, and I convert the expected C structure in a OCaml type again.

The question is: did anyone of you try to cheat too?
Is that just a completely wrong use case of ctypes (poor -lazy- me I must implement again the logic of Unix!)?
Thanks a lot,

Andrea

P.S: I attach the code I was trying to run for the stat function: it worst case it can be used as "don't do this!"
open Ctypes
open PosixTypes
open Unsigned

type stats
let stats : stats structure typ = structure "Stat"
let ( -:* ) s x = field stats s x
let st_dev = "st_dev" -:* dev_t
let st_ino = "st_ino" -:* int
let st_kind= "st_kind" -:* int
let st_perm= "st_perm" -:* int
let st_nlink = "st_nlink" -:* int
let st_uid = "st_uid" -:* int
let st_gid = "st_gid" -:* int
let st_rdev = "st_rdev" -:* int
let st_size = "st_size" -:* int64_t
let st_atime = "st_atime" -:* double
let st_mtime = "st_mtime" -:* double
let st_ctime = "st_ctime" -:* double
let () = seal stats

let st_dev_int s = UInt64.to_int (coerce dev_t uint64_t (getf s st_dev))
let st_ino_int s =  (getf s st_ino)
let st_nlink_int s = (getf s st_nlink)
let st_perm_int s = (getf s st_perm)
let st_kind_kind s = match (getf s st_kind) with | _ -> S_REG
let st_uid_int s =   (getf s st_uid)
let st_gid_int s =  (getf s st_gid)
let st_rdev_int s = (getf s st_rdev)
let st_size_int s = (getf s st_size)
let st_atime_float s = (getf s st_atime)
let st_mtime_float s = (getf s st_mtime)
let st_ctime_float s =  (getf s st_ctime)


let to_unix t = Ctypes.(Unix.LargeFile.({
                                         st_dev  = st_dev_int t;
                                         st_ino  = st_ino_int t;
                                         st_kind = st_kind_kind t;
                                         st_perm = st_perm_int t;
                                         st_nlink= st_nlink_int t;
                                         st_uid  = st_uid_int t;
                                         st_gid  = st_gid_int t;
                                         st_rdev = st_rdev_int t;
                                         st_size = st_size_int t;
                                         st_atime= st_atime_float t;
                                         st_mtime= st_mtime_float t;
                                         st_ctime= st_ctime_float t;
                                       }))
let stat = Foreign.foreign "unix_stat_64" ~check_errno:true
                           (string_opt @-> returning (ptr stats))
_______________________________________________
Ctypes mailing list
[email protected]
http://lists.ocaml.org/listinfo/ctypes

Reply via email to