caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Interfacing C with OCaml and file descriptors
@ 2017-10-13 10:57 Laurent Thévenoux
  2017-10-13 11:10 ` Nicolás Ojeda Bär
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Laurent Thévenoux @ 2017-10-13 10:57 UTC (permalink / raw)
  To: caml-list

Hi,

I have a naive question about file descriptors and C interface (when interfacing C with OCaml).

For instance, a file.ml file which looks like:


external my_c_interface : out_channel -> int = c_function


where c_function writes something to a file and return the number of written char.
The c_function takes a FILE* file descriptor, as for example:


CAMLprim value c_function (value channel)
{
	CAMLparam1 (channel);
	FILE* fd = ???;
	CAMLreturn (Val_int (call_to_c_func (fd)));
}


So, if possible, how to convert the ‘value channel’ to a ‘FILE*’?

Thanks for your help,
Laurent

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Interfacing C with OCaml and file descriptors
  2017-10-13 10:57 [Caml-list] Interfacing C with OCaml and file descriptors Laurent Thévenoux
@ 2017-10-13 11:10 ` Nicolás Ojeda Bär
  2017-10-13 21:37 ` Richard W.M. Jones
  2017-10-14 15:54 ` Thierry Martinez
  2 siblings, 0 replies; 8+ messages in thread
From: Nicolás Ojeda Bär @ 2017-10-13 11:10 UTC (permalink / raw)
  To: Laurent Thévenoux; +Cc: OCaml Mailing List

[-- Attachment #1: Type: text/plain, Size: 1593 bytes --]

Dear Laurent,

Underlying OCaml I/O channels are Unix file descriptors, not FILE *'s. But
you can use the POSIX function fdopen to get a FILE* form the file
descriptor of the channel, which you can access by Channel(channel)->fd
(see <caml/io.h> for the precise definition of the channel struct).

That said, it is always tricky when different buffering mechanisms (OCaml's
and libc's) interact, so caveat emptor!

Best wishes,
Nicolás


--
Nicolás Ojeda Bär
LexiFi
892, rue Yves Kermen
F-92100 Boulogne-Billancourt
IT support: +33 1 41 10 02 67

On Fri, Oct 13, 2017 at 12:57 PM, Laurent Thévenoux <
laurent.thevenoux@inria.fr> wrote:

> Hi,
>
> I have a naive question about file descriptors and C interface (when
> interfacing C with OCaml).
>
> For instance, a file.ml file which looks like:
>
>
> external my_c_interface : out_channel -> int = c_function
>
>
> where c_function writes something to a file and return the number of
> written char.
> The c_function takes a FILE* file descriptor, as for example:
>
>
> CAMLprim value c_function (value channel)
> {
>         CAMLparam1 (channel);
>         FILE* fd = ???;
>         CAMLreturn (Val_int (call_to_c_func (fd)));
> }
>
>
> So, if possible, how to convert the ‘value channel’ to a ‘FILE*’?
>
> Thanks for your help,
> Laurent
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

[-- Attachment #2: Type: text/html, Size: 2604 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Interfacing C with OCaml and file descriptors
  2017-10-13 10:57 [Caml-list] Interfacing C with OCaml and file descriptors Laurent Thévenoux
  2017-10-13 11:10 ` Nicolás Ojeda Bär
@ 2017-10-13 21:37 ` Richard W.M. Jones
  2017-10-13 22:42   ` David Allsopp
  2017-10-14 15:18   ` Malcolm Matalka
  2017-10-14 15:54 ` Thierry Martinez
  2 siblings, 2 replies; 8+ messages in thread
From: Richard W.M. Jones @ 2017-10-13 21:37 UTC (permalink / raw)
  To: Laurent Thévenoux; +Cc: caml-list

On Fri, Oct 13, 2017 at 12:57:33PM +0200, Laurent Thévenoux wrote:
> Hi,
> 
> I have a naive question about file descriptors and C interface (when interfacing C with OCaml).

Firstly, you're confused about the difference between 'FILE *' and a
file descriptor.  They are not the same thing at all.  Read some basic
Unix texts about the difference.

Once you've sorted that out, it turns out that you can (currently)
cast a Unix.file_descr from OCaml directly into a C int file
descriptor using Int_val:

  int fd = Int_val (fdv);
  read (fd, buf, len);

It would be really nice if there was an official C function defined by
OCaml to do this in a portable and future-proof way!

Rich.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [Caml-list] Interfacing C with OCaml and file descriptors
  2017-10-13 21:37 ` Richard W.M. Jones
@ 2017-10-13 22:42   ` David Allsopp
  2017-10-14  6:10     ` Richard W.M. Jones
  2017-10-14 15:18   ` Malcolm Matalka
  1 sibling, 1 reply; 8+ messages in thread
From: David Allsopp @ 2017-10-13 22:42 UTC (permalink / raw)
  To: Richard W.M. Jones, Laurent Thévenoux; +Cc: caml-list

Richard W.M. Jones wrote:
> On Fri, Oct 13, 2017 at 12:57:33PM +0200, Laurent Thévenoux wrote:
> > Hi,
> >
> > I have a naive question about file descriptors and C interface (when
> interfacing C with OCaml).
> 
> Firstly, you're confused about the difference between 'FILE *' and a file
> descriptor.  They are not the same thing at all.  Read some basic Unix
> texts about the difference.
> 
> Once you've sorted that out, it turns out that you can (currently) cast a
> Unix.file_descr from OCaml directly into a C int file descriptor using
> Int_val:
> 
>   int fd = Int_val (fdv);
>   read (fd, buf, len);

FWIW, note that this is not portable - it won't work on Windows, since Unix.file_descr is a struct.

> It would be really nice if there was an official C function defined by
> OCaml to do this in a portable and future-proof way!

One possibility might be to include the CRT_fd_val macro already in the win32unix version of unixsupport.h and make it an "official" conversion. 


David 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Interfacing C with OCaml and file descriptors
  2017-10-13 22:42   ` David Allsopp
@ 2017-10-14  6:10     ` Richard W.M. Jones
  0 siblings, 0 replies; 8+ messages in thread
From: Richard W.M. Jones @ 2017-10-14  6:10 UTC (permalink / raw)
  To: David Allsopp; +Cc: Laurent Thévenoux, caml-list

On Fri, Oct 13, 2017 at 10:42:23PM +0000, David Allsopp wrote:
> Richard W.M. Jones wrote:
> > On Fri, Oct 13, 2017 at 12:57:33PM +0200, Laurent Thévenoux wrote:
> > > Hi,
> > >
> > > I have a naive question about file descriptors and C interface (when
> > interfacing C with OCaml).
> > 
> > Firstly, you're confused about the difference between 'FILE *' and a file
> > descriptor.  They are not the same thing at all.  Read some basic Unix
> > texts about the difference.
> > 
> > Once you've sorted that out, it turns out that you can (currently) cast a
> > Unix.file_descr from OCaml directly into a C int file descriptor using
> > Int_val:
> > 
> >   int fd = Int_val (fdv);
> >   read (fd, buf, len);
> 
> FWIW, note that this is not portable - it won't work on Windows, since Unix.file_descr is a struct.

Right, precisely my point.  However it currently works on Unix
which is what I (and the original poster) care about.

Rich.

> > It would be really nice if there was an official C function defined by
> > OCaml to do this in a portable and future-proof way!
> 
> One possibility might be to include the CRT_fd_val macro already in the win32unix version of unixsupport.h and make it an "official" conversion. 
> 
> 
> David 
> 
> 
> -- 
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

-- 
Richard Jones

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Interfacing C with OCaml and file descriptors
  2017-10-13 21:37 ` Richard W.M. Jones
  2017-10-13 22:42   ` David Allsopp
@ 2017-10-14 15:18   ` Malcolm Matalka
  1 sibling, 0 replies; 8+ messages in thread
From: Malcolm Matalka @ 2017-10-14 15:18 UTC (permalink / raw)
  To: Richard W.M. Jones; +Cc: Laurent Thévenoux, caml-list

"Richard W.M. Jones" <rich@annexia.org> writes:

> On Fri, Oct 13, 2017 at 12:57:33PM +0200, Laurent Thévenoux wrote:
>> Hi,
>> 
>> I have a naive question about file descriptors and C interface (when interfacing C with OCaml).
>
> Firstly, you're confused about the difference between 'FILE *' and a
> file descriptor.  They are not the same thing at all.  Read some basic
> Unix texts about the difference.
>
> Once you've sorted that out, it turns out that you can (currently)
> cast a Unix.file_descr from OCaml directly into a C int file
> descriptor using Int_val:
>
>   int fd = Int_val (fdv);
>   read (fd, buf, len);
>
> It would be really nice if there was an official C function defined by
> OCaml to do this in a portable and future-proof way!
>
> Rich.

I do a similar thing but I abuse "%identity" for it and do it in Ocaml.
In my case I do it for my kqueue bindings so it should be safe, assuming
Unix.file_descr is guaranteed not to change, but it does make me feel
dirty.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Interfacing C with OCaml and file descriptors
  2017-10-13 10:57 [Caml-list] Interfacing C with OCaml and file descriptors Laurent Thévenoux
  2017-10-13 11:10 ` Nicolás Ojeda Bär
  2017-10-13 21:37 ` Richard W.M. Jones
@ 2017-10-14 15:54 ` Thierry Martinez
  2017-10-16  6:46   ` Laurent Thévenoux
  2 siblings, 1 reply; 8+ messages in thread
From: Thierry Martinez @ 2017-10-14 15:54 UTC (permalink / raw)
  To: Laurent Thévenoux; +Cc: caml-list

Laurent:
> So, if possible, how to convert the ‘value channel’ to a ‘FILE*’?

As the other answers already said, there does not seem to exist a
portable way to do that.
FWIW, here is what I do for Pyml, which appears to works both on
Unix and Windows:
the function file_of_file_descr takes two arguments:
- an OCaml value which can be either in_channel or out_channel,
- and a corresponding mode ("r" or "w", typically),
and returns a FILE *.
Of course, since the API for channels is not documented, this
solution can break on future OCaml versions.

#ifdef _WIN32
#include <windows.h>

extern int win_CRT_fd_of_filedescr(value handle);

static FILE *
file_of_file_descr(value file_descr, const char *mode)
{
    CAMLparam1(file_descr);
    int fd = win_CRT_fd_of_filedescr(file_descr);
    FILE *result = _fdopen(dup(fd), mode);
    CAMLreturnT(FILE *, result);
}
#else 
static FILE *
file_of_file_descr(value file_descr, const char *mode)
{
    CAMLparam1(file_descr);
    int fd = Int_val(file_descr);
    FILE *result = fdopen(dup(fd), mode);
    CAMLreturnT(FILE *, result);
}
#endif

Cheers.
-- 
Thierry.

----- Original Message -----
> From: "Laurent Thévenoux" <laurent.thevenoux@inria.fr>
> To: caml-list@inria.fr
> Sent: Friday, October 13, 2017 12:57:33 PM
> Subject: [Caml-list] Interfacing C with OCaml and file descriptors
> 
> Hi,
> 
> I have a naive question about file descriptors and C interface (when
> interfacing C with OCaml).
> 
> For instance, a file.ml file which looks like:
> 
> 
> external my_c_interface : out_channel -> int = c_function
> 
> 
> where c_function writes something to a file and return the number of written
> char.
> The c_function takes a FILE* file descriptor, as for example:
> 
> 
> CAMLprim value c_function (value channel)
> {
> 	CAMLparam1 (channel);
> 	FILE* fd = ???;
> 	CAMLreturn (Val_int (call_to_c_func (fd)));
> }
> 
> 
> So, if possible, how to convert the ‘value channel’ to a ‘FILE*’?
> 
> Thanks for your help,
> Laurent
> 
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Interfacing C with OCaml and file descriptors
  2017-10-14 15:54 ` Thierry Martinez
@ 2017-10-16  6:46   ` Laurent Thévenoux
  0 siblings, 0 replies; 8+ messages in thread
From: Laurent Thévenoux @ 2017-10-16  6:46 UTC (permalink / raw)
  To: caml-list

Hello,

Thank you, everyone, for your very instructive answers!

Laurent

> Le 14 oct. 2017 à 17:54, Thierry Martinez <thierry.martinez@inria.fr> a écrit :
> 
> Laurent:
>> So, if possible, how to convert the ‘value channel’ to a ‘FILE*’?
> 
> As the other answers already said, there does not seem to exist a
> portable way to do that.
> FWIW, here is what I do for Pyml, which appears to works both on
> Unix and Windows:
> the function file_of_file_descr takes two arguments:
> - an OCaml value which can be either in_channel or out_channel,
> - and a corresponding mode ("r" or "w", typically),
> and returns a FILE *.
> Of course, since the API for channels is not documented, this
> solution can break on future OCaml versions.
> 
> #ifdef _WIN32
> #include <windows.h>
> 
> extern int win_CRT_fd_of_filedescr(value handle);
> 
> static FILE *
> file_of_file_descr(value file_descr, const char *mode)
> {
>    CAMLparam1(file_descr);
>    int fd = win_CRT_fd_of_filedescr(file_descr);
>    FILE *result = _fdopen(dup(fd), mode);
>    CAMLreturnT(FILE *, result);
> }
> #else 
> static FILE *
> file_of_file_descr(value file_descr, const char *mode)
> {
>    CAMLparam1(file_descr);
>    int fd = Int_val(file_descr);
>    FILE *result = fdopen(dup(fd), mode);
>    CAMLreturnT(FILE *, result);
> }
> #endif
> 
> Cheers.
> -- 
> Thierry.
> 
> ----- Original Message -----
>> From: "Laurent Thévenoux" <laurent.thevenoux@inria.fr>
>> To: caml-list@inria.fr
>> Sent: Friday, October 13, 2017 12:57:33 PM
>> Subject: [Caml-list] Interfacing C with OCaml and file descriptors
>> 
>> Hi,
>> 
>> I have a naive question about file descriptors and C interface (when
>> interfacing C with OCaml).
>> 
>> For instance, a file.ml file which looks like:
>> 
>> 
>> external my_c_interface : out_channel -> int = c_function
>> 
>> 
>> where c_function writes something to a file and return the number of written
>> char.
>> The c_function takes a FILE* file descriptor, as for example:
>> 
>> 
>> CAMLprim value c_function (value channel)
>> {
>> 	CAMLparam1 (channel);
>> 	FILE* fd = ???;
>> 	CAMLreturn (Val_int (call_to_c_func (fd)));
>> }
>> 
>> 
>> So, if possible, how to convert the ‘value channel’ to a ‘FILE*’?
>> 
>> Thanks for your help,
>> Laurent
>> 
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa.inria.fr/sympa/arc/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-10-16  6:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-13 10:57 [Caml-list] Interfacing C with OCaml and file descriptors Laurent Thévenoux
2017-10-13 11:10 ` Nicolás Ojeda Bär
2017-10-13 21:37 ` Richard W.M. Jones
2017-10-13 22:42   ` David Allsopp
2017-10-14  6:10     ` Richard W.M. Jones
2017-10-14 15:18   ` Malcolm Matalka
2017-10-14 15:54 ` Thierry Martinez
2017-10-16  6:46   ` Laurent Thévenoux

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).