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

socket.fromfd()'s API is difficult or impossible to use correctly in general #62591

Open
cks mannequin opened this issue Jul 6, 2013 · 8 comments
Open

socket.fromfd()'s API is difficult or impossible to use correctly in general #62591

cks mannequin opened this issue Jul 6, 2013 · 8 comments
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@cks
Copy link
Mannequin

cks mannequin commented Jul 6, 2013

BPO 18391
Nosy @nascheme, @jcea, @tiran, @glyph, @aragilar

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2013-07-06.23:33:52.014>
labels = ['type-feature', 'library']
title = "socket.fromfd()'s API is difficult or impossible to use correctly in general"
updated_at = <Date 2016-06-24.17:22:46.955>
user = 'https://bugs.python.org/cks'

bugs.python.org fields:

activity = <Date 2016-06-24.17:22:46.955>
actor = 'nascheme'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2013-07-06.23:33:52.014>
creator = 'cks'
dependencies = []
files = []
hgrepos = []
issue_num = 18391
keywords = []
message_count = 8.0
messages = ['192500', '192501', '192510', '192667', '203183', '264650', '269198', '269199']
nosy_count = 6.0
nosy_names = ['nascheme', 'jcea', 'christian.heimes', 'glyph', 'cks', 'aragilar']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue18391'
versions = ['Python 3.6']

@cks
Copy link
Mannequin Author

cks mannequin commented Jul 6, 2013

socket.fromfd() requires you to supply at least the family and type of
the file descriptor that you are turning into a Python socket object.
However the socket module provides no documented way to determine what
these actually are and there are any number of situations where you may
get handed file descriptors with an indeterminate type. Nor does
providing incorrect family and type values raise an exception from
fromfd(), although if you get the wrong values you may get exceptions
from calling methods on the returned socket (you can also get garbled
and nonsensical results from some methods).

(For instance, in Python 3 calling .getsockname() may raise
UnicodeDecodeError under some circumstances.)

Suggested resolution: socket.fromfd() should always determine the
family and type itself and the arguments for them should become
optional. If they are supplied and they do not match the determined
family and type, fromfd() should probably raise an exception
(although that will break some existing code).

Less appealing resolution: the socket module should provide officially
documented and supported methods for determining the family and type
of a (socket) file descriptor. I think that a new module function to
do this would be the cleanest approach.

@cks cks mannequin added type-bug An unexpected behavior, bug, or error stdlib Python modules in the Lib dir labels Jul 6, 2013
@tiran
Copy link
Member

tiran commented Jul 7, 2013

Unfortunately it's not as easy as you may think. BSD sockets have no portable API to retrieve domain, type and protocol from a file descriptor. getsockopt() may be able to retrieve some or even all values but it's not portable. For example SO_DOMAIN and SO_PROTOCOL requires Linux 2.6.32 or newer. I'm not sure about BSD or Windows.

It's also not possible to verify the parameters until you actually do an operation like send(), recv() or accept() on a fd. Wrong parameters may not raise an error after all.

For now I suggest that you pass all information to the other process, that is fd, domain, type, proto. They are just integers.

@tiran tiran added type-feature A feature request or enhancement and removed type-bug An unexpected behavior, bug, or error labels Jul 7, 2013
@cks
Copy link
Mannequin Author

cks mannequin commented Jul 7, 2013

As far as I know, you can recover everything except the protocol
portably on Unix (and fromfd() will already handwave the protocol).
getsockopt() with SO_TYPE will give you the type. The family can be
recovered by calling getsockname() with a plain struct sockaddr and
then examining sockaddr.sa_family.

As for the other suggestion:

When Python is plugging into larger systems or APIs that pass sockets
around, it is not possible to modify those APIs to pass the additional
information that Python wants (and other environments don't need).
As far as I know, no current protocol that passes file descriptors to
newly started programs or passes file descriptors over Unix sockets
with sendmsg() and SCM_RIGHTS does this. The people responsible for
these protocols are not likely to change them to accommodate Python's
wants. A Python program (and thus Python programmers) get to deal with
the issue themselves if they want Python to participate in these
systems and protocols.

I do want to be able to write Python programs that can interact in
these environments. It is possible to deal with this in C; it is
even possible to hack around this in Python today. I believe that
it should be officially supported.

@glyph
Copy link
Mannequin

glyph mannequin commented Jul 8, 2013

It would be nice for this to be fixed in a 2.7.x release too, if possible, since the workaround involves a ton of extra system calls and there's no other way to construct a socket object directly.

@tiran
Copy link
Member

tiran commented Nov 17, 2013

Do you want to work on a patch for 3.4? You have about five days until 3.4 is going into feature freeze.

@tiran
Copy link
Member

tiran commented May 2, 2016

fromfd() can be simplified after bpo-26907 has landed.

@nascheme
Copy link
Member

I've created a patch to add fromfd2(). I think it addresses the original concern of this issue. My patch also adds the constants suggested by Issue bpo-26907.

@nascheme
Copy link
Member

Sorry, forgot to link the patch: Issue bpo-27377.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

2 participants