Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impossible to Unix.dup2 to a specific number or to inherit Unix_file_descr by number on startup #6948

Closed
vicuna opened this issue Jul 31, 2015 · 2 comments

Comments

@vicuna
Copy link

vicuna commented Jul 31, 2015

Original bug ID: 6948
Reporter: goswin
Status: closed (set by @xavierleroy on 2017-02-16T14:16:45Z)
Resolution: won't fix
Priority: normal
Severity: minor
Platform: Unix
Version: 4.01.0
Category: otherlibs
Monitored by: @gasche @diml

Bug description

I have a framework that uses a socket to communicate between modules it starts as seperate processes. The processes expect the control socket to be left open as FD 3 when it gets started.

Writing my own module in ocaml I'm left with the problem of how to access that socket. The Unix module has no function to return an already open FD. Currently I do

let fd = Obj.magic 3

but I don't want to rely on the fact that Unix.file_descr is just an int. Which probably isn't true on Windows already.

Similary, for unit testing, I need to start module processes and feed them test data. But there is no way to create a socket that will use FD 3 before calling Unix.exec. There is 'Unix.dup2 : file_descr -> file_descr -> unit' but that assumes I already have a valid file_descr that I want to replace, like stdin. So I'm left with using:

Unix.dup2 sock_other (Obj.magic 3)

Last I would prefer not to have to fork, dup2 and exec at all but use a high level interface. Unix.create_process comes to mind. But that only supports redirecting stdint, stdout and stderr. A more general 'create_process2 : string -> string array -> file_descr list -> int' would be usefull there.

Steps to reproduce

% ocaml 3>&1
OCaml version 4.01.0

Findlib has been successfully loaded. Additional directives:
#require "package";; to load a package
#list;; to list the available packages
#camlp4o;; to load camlp4 (standard syntax)
#camlp4r;; to load camlp4 (revised syntax)
#predicates "p,q,...";; to set these predicates
Topfind.reset();; to force that packages will be reloaded
#thread;; to enable threads

#require "unix";;

/usr/lib/ocaml/unix.cma: loaded

let fd = Obj.magic 3;;

val fd : 'a =

Unix.write fd "Hello World\n" 0 12;;

Hello World

  • : int = 12
@vicuna
Copy link
Author

vicuna commented Aug 4, 2015

Comment author: goswin

I came across another problem related to Unix.dup2. What I want to do is move the FD from whatever number it is to number 3. Problem is that the original FD could already be 3. In that case Unix.dup2 does nothing and I must not close the original FD.

Just another reason to have a create_process2 that handles the specifics internally.

@vicuna
Copy link
Author

vicuna commented Nov 20, 2015

Comment author: @xavierleroy

It has been a conscious decision in the design of the Unix interface that file descriptors are an abstract type, not integers, and that there is no such thing as "file descriptor number 3". The latter makes no sense under Windows, in particular.

If you're only interested in Unix, you might just as well keep using the Obj.magic trick. as it is likely to keep working in the foreseeable future. It would be prudent to check Sys.os_type in an assertion, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant