Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nemu3
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
nemu3
Commits
a441f5e3
Commit
a441f5e3
authored
Nov 15, 2023
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
remove c passfd
parent
ba619ec3
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
3 additions
and
412 deletions
+3
-412
setup.py
setup.py
+1
-4
src/passfd.py
src/passfd.py
+2
-32
src/passfd/__init__.py
src/passfd/__init__.py
+0
-125
src/passfd/passfd.c
src/passfd/passfd.c
+0
-251
No files found.
setup.py
View file @
a441f5e3
...
@@ -4,8 +4,6 @@
...
@@ -4,8 +4,6 @@
from
distutils.core
import
setup
,
Extension
,
Command
from
distutils.core
import
setup
,
Extension
,
Command
passfd
=
Extension
(
'_passfd'
,
sources
=
[
'src/passfd/passfd.c'
])
setup
(
setup
(
name
=
'nemu'
,
name
=
'nemu'
,
version
=
'0.3.1'
,
version
=
'0.3.1'
,
...
@@ -18,6 +16,5 @@ setup(
...
@@ -18,6 +16,5 @@ setup(
platforms
=
'Linux'
,
platforms
=
'Linux'
,
packages
=
[
'nemu'
],
packages
=
[
'nemu'
],
install_requires
=
[
'unshare'
,
'six'
],
install_requires
=
[
'unshare'
,
'six'
],
package_dir
=
{
''
:
'src'
},
package_dir
=
{
''
:
'src'
}
ext_modules
=
[
passfd
]
)
)
src/passfd.py
2
→
src/passfd.py
View file @
a441f5e3
...
@@ -26,7 +26,7 @@ def __check_socket(sock: socket.socket | IOBase):
...
@@ -26,7 +26,7 @@ def __check_socket(sock: socket.socket | IOBase):
raise
ValueError
(
"Only AF_UNIX sockets are allowed"
)
raise
ValueError
(
"Only AF_UNIX sockets are allowed"
)
if
hasattr
(
sock
,
'fileno'
):
if
hasattr
(
sock
,
'fileno'
):
sock = socket.
socket(fileno=sock.fileno()
)
sock
=
socket
.
fromfd
(
sock
.
fileno
(),
family
=
socket
.
AF_UNIX
,
type
=
socket
.
SOCK_STREAM
)
if
not
isinstance
(
sock
,
socket
.
socket
):
if
not
isinstance
(
sock
,
socket
.
socket
):
raise
TypeError
(
"An socket object or file descriptor was expected"
)
raise
TypeError
(
"An socket object or file descriptor was expected"
)
...
@@ -45,34 +45,8 @@ def __check_fd(fd):
...
@@ -45,34 +45,8 @@ def __check_fd(fd):
def
recvfd
(
sock
:
socket
.
socket
|
IOBase
,
msg_buf
:
int
=
4096
):
def
recvfd
(
sock
:
socket
.
socket
|
IOBase
,
msg_buf
:
int
=
4096
):
"""
import _passfd
(ret, msg) = _passfd.recvfd(__check_socket(sock), msg_buf)
# -1 should raise OSError
if ret == -2:
raise RuntimeError("The message received did not contain exactly one" +
" file descriptor")
if ret == -3:
raise RuntimeError("The received file descriptor is not valid")
assert ret >= 0
return (ret, msg)
"""
"""
size = struct.calcsize("@i")
+ with socket.fromfd(conn.fileno(), socket.AF_UNIX, socket.SOCK_STREAM) as s:
+ msg, ancdata, flags, addr = s.recvmsg(1, socket.CMSG_LEN(size))
+ try:
+ cmsg_level, cmsg_type, cmsg_data = ancdata[0]
+ if (cmsg_level == socket.SOL_SOCKET and
+ cmsg_type == socket.SCM_RIGHTS):
+ return struct.unpack("@i", cmsg_data[:size])[0]
+ except (ValueError, IndexError, struct.error):
+ pass
+ raise RuntimeError('Invalid data received')"""
size
=
struct
.
calcsize
(
"@i"
)
size
=
struct
.
calcsize
(
"@i"
)
msg, ancdata, flags, addr = __check_socket(sock).recvmsg(
4096, socket.CMSG_LEN
(size))
msg
,
ancdata
,
flags
,
addr
=
__check_socket
(
sock
).
recvmsg
(
msg_buf
,
socket
.
CMSG_SPACE
(
size
))
cmsg_level
,
cmsg_type
,
cmsg_data
=
ancdata
[
0
]
cmsg_level
,
cmsg_type
,
cmsg_data
=
ancdata
[
0
]
if
not
(
cmsg_level
==
socket
.
SOL_SOCKET
and
cmsg_type
==
socket
.
SCM_RIGHTS
):
if
not
(
cmsg_level
==
socket
.
SOL_SOCKET
and
cmsg_type
==
socket
.
SCM_RIGHTS
):
raise
RuntimeError
(
"The message received did not contain exactly one"
+
raise
RuntimeError
(
"The message received did not contain exactly one"
+
...
@@ -86,10 +60,6 @@ def recvfd(sock: socket.socket | IOBase, msg_buf: int = 4096):
...
@@ -86,10 +60,6 @@ def recvfd(sock: socket.socket | IOBase, msg_buf: int = 4096):
def
sendfd
(
sock
:
socket
.
socket
|
IOBase
,
fd
:
int
,
message
:
bytes
=
b"NONE"
):
def
sendfd
(
sock
:
socket
.
socket
|
IOBase
,
fd
:
int
,
message
:
bytes
=
b"NONE"
):
"""
import _passfd
return _passfd.sendfd(__check_socket(sock), __check_fd(fd), message)
"""
return
__check_socket
(
sock
).
sendmsg
(
return
__check_socket
(
sock
).
sendmsg
(
[
message
],
[
message
],
[(
socket
.
SOL_SOCKET
,
socket
.
SCM_RIGHTS
,
struct
.
pack
(
"@i"
,
fd
))])
[(
socket
.
SOL_SOCKET
,
socket
.
SCM_RIGHTS
,
struct
.
pack
(
"@i"
,
fd
))])
\ No newline at end of file
src/passfd/__init__.py
deleted
100644 → 0
View file @
ba619ec3
#!/usr/bin/env python
# vim: set fileencoding=utf-8
# vim: ts=4:sw=4:et:ai:sts=4
# passfd.py: Python library to pass file descriptors across UNIX domain sockets.
'''This simple extension provides two functions to pass and receive file
descriptors across UNIX domain sockets, using the BSD-4.3+ sendmsg() and
recvmsg() interfaces.
Direct bindings to sendmsg and recvmsg are not provided, as the API does
not map nicely into Python.
Please note that this only supports BSD-4.3+ style file descriptor
passing, and was only tested on Linux. Patches are welcomed!
For more information, see one of the R. Stevens' books:
- Richard Stevens: Unix Network Programming, Prentice Hall, 1990;
chapter 6.10
- Richard Stevens: Advanced Programming in the UNIX Environment,
Addison-Wesley, 1993; chapter 15.3
'''
#
# Please note that this only supports BSD-4.3+ style file descriptor passing,
# and was only tested on Linux. Patches are welcomed!
#
# Copyright © 2010 Martina Ferrari <tina@tina.pm>
#
# Inspired by Socket::PassAccessRights, which is:
# Copyright (c) 2000 Sampo Kellomaki <sampo@iki.fi>
#
# For more information, see one of the R. Stevens' books:
# - Richard Stevens: Unix Network Programming, Prentice Hall, 1990;
# chapter 6.10
#
# - Richard Stevens: Advanced Programming in the UNIX Environment,
# Addison-Wesley, 1993; chapter 15.3
#
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
import
socket
def
__check_socket
(
sock
):
if
hasattr
(
sock
,
'family'
)
and
sock
.
family
!=
socket
.
AF_UNIX
:
raise
ValueError
(
"Only AF_UNIX sockets are allowed"
)
if
hasattr
(
sock
,
'fileno'
):
sock
=
sock
.
fileno
()
if
not
isinstance
(
sock
,
int
):
raise
TypeError
(
"An socket object or file descriptor was expected"
)
return
sock
def
__check_fd
(
fd
):
try
:
fd
=
fd
.
fileno
()
except
AttributeError
:
pass
if
not
isinstance
(
fd
,
int
):
raise
TypeError
(
"An file object or file descriptor was expected"
)
return
fd
def
sendfd
(
sock
,
fd
,
message
=
"NONE"
):
"""Sends a message and piggybacks a file descriptor through a Unix
domain socket.
Note that the file descriptor cannot be sent by itself, at least
one byte of payload needs to be sent also.
Parameters:
sock: socket object or file descriptor for an AF_UNIX socket
fd: file object or file descriptor to pass
message: message to send
Return value:
On success, sendfd returns the number of bytes sent, not including
the file descriptor nor the control data. If there was no message
to send, 0 is returned."""
import
_passfd
return
_passfd
.
sendfd
(
__check_socket
(
sock
),
__check_fd
(
fd
),
message
)
def
recvfd
(
sock
,
msg_buf
=
4096
):
"""Receive a message and a file descriptor from a Unix domain socket.
Parameters:
sock: file descriptor or socket object for an AF_UNIX socket
buffersize: maximum message size to receive
Return value:
On success, recvfd returns a tuple containing the received
file descriptor and message. If recvmsg fails, an OSError exception
is raised. If the received data does not carry exactly one file
descriptor, or if the received file descriptor is not valid,
RuntimeError is raised."""
import
_passfd
(
ret
,
msg
)
=
_passfd
.
recvfd
(
__check_socket
(
sock
),
msg_buf
)
# -1 should raise OSError
if
ret
==
-
2
:
raise
RuntimeError
(
"The message received did not contain exactly one"
+
" file descriptor"
)
if
ret
==
-
3
:
raise
RuntimeError
(
"The received file descriptor is not valid"
)
assert
ret
>=
0
return
(
ret
,
msg
)
\ No newline at end of file
src/passfd/passfd.c
deleted
100644 → 0
View file @
ba619ec3
/* vim:ts=4:sw=4:et:ai:sts=4
*
* passfd.c: Functions to pass file descriptors across UNIX domain sockets.
*
* Please note that this only supports BSD-4.3+ style file descriptor passing,
* and was only tested on Linux. Patches are welcomed!
*
* Copyright © 2010 Martina Ferrari <tina@tina.pm>
*
* Inspired by Socket::PassAccessRights, which is:
* Copyright (c) 2000 Sampo Kellomaki <sampo@iki.fi>
*
* For more information, see one of the R. Stevens' books:
* - Richard Stevens: Unix Network Programming, Prentice Hall, 1990;
* chapter 6.10
*
* - Richard Stevens: Advanced Programming in the UNIX Environment,
* Addison-Wesley, 1993; chapter 15.3
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
int
_sendfd
(
int
sock
,
int
fd
,
size_t
len
,
const
void
*
msg
);
int
_recvfd
(
int
sock
,
size_t
*
len
,
void
*
buf
);
/* Python wrapper for _sendfd */
static
PyObject
*
sendfd
(
PyObject
*
self
,
PyObject
*
args
)
{
const
char
*
message
;
char
*
buf
;
int
ret
,
sock
,
fd
;
Py_ssize_t
message_len
;
if
(
!
PyArg_ParseTuple
(
args
,
"iis#"
,
&
sock
,
&
fd
,
&
message
,
&
message_len
))
return
NULL
;
/* I don't know if I need to make a copy of the message buffer for thread
* safety, but let's do it just in case... */
buf
=
strndup
(
message
,
(
size_t
)
message_len
);
if
(
buf
==
NULL
)
return
PyErr_SetFromErrno
(
PyExc_OSError
);
Py_BEGIN_ALLOW_THREADS
;
ret
=
_sendfd
(
sock
,
fd
,
message_len
,
message
);
Py_END_ALLOW_THREADS
;
free
(
buf
);
if
(
ret
==
-
1
)
return
PyErr_SetFromErrno
(
PyExc_OSError
);
return
Py_BuildValue
(
"i"
,
ret
);
}
/* Python wrapper for _recvfd */
static
PyObject
*
recvfd
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
buffer
;
int
ret
,
sock
;
Py_ssize_t
buffersize
=
4096
;
size_t
_buffersize
;
PyObject
*
retval
;
if
(
!
PyArg_ParseTuple
(
args
,
"i|i"
,
&
sock
,
&
buffersize
))
return
NULL
;
if
((
buffer
=
malloc
(
buffersize
))
==
NULL
)
return
PyErr_SetFromErrno
(
PyExc_OSError
);
_buffersize
=
buffersize
;
Py_BEGIN_ALLOW_THREADS
;
ret
=
_recvfd
(
sock
,
&
_buffersize
,
buffer
);
Py_END_ALLOW_THREADS
;
buffersize
=
_buffersize
;
if
(
ret
==
-
1
)
{
free
(
buffer
);
return
PyErr_SetFromErrno
(
PyExc_OSError
);
}
retval
=
Py_BuildValue
(
"is#"
,
ret
,
buffer
,
buffersize
);
free
(
buffer
);
return
retval
;
}
static
PyMethodDef
methods
[]
=
{
{
"sendfd"
,
sendfd
,
METH_VARARGS
,
"rv = sendfd(sock, fd, message)"
},
{
"recvfd"
,
recvfd
,
METH_VARARGS
,
"(fd, message) = recvfd(sock, "
"buffersize = 4096)"
},
{
NULL
,
NULL
,
0
,
NULL
}
};
static
struct
PyModuleDef
passfdmodule
=
{
PyModuleDef_HEAD_INIT
,
"_passfd"
,
/* name of module */
NULL
,
/* module documentation, may be NULL */
-
1
,
/* size of per-interpreter state of the module,
or -1 if the module keeps state in global variables. */
methods
};
PyMODINIT_FUNC
PyInit__passfd
(
void
)
{
return
PyModule_Create
(
&
passfdmodule
);
}
/* Size of the cmsg including one file descriptor */
#define CMSG_SIZE CMSG_SPACE(sizeof(int))
/*
* _sendfd(): send a message and piggyback a file descriptor.
*
* Note that the file descriptor cannot be sent by itself, at least one byte of
* payload needs to be sent.
*
* Parameters:
* sock: AF_UNIX socket
* fd: file descriptor to pass
* len: length of the message
* msg: the message itself
*
* Return value:
* On success, sendfd returns the number of characters from the message sent,
* the file descriptor information is not taken into account. If there was no
* message to send, 0 is returned. On error, -1 is returned, and errno is set
* appropriately.
*
*/
int
_sendfd
(
int
sock
,
int
fd
,
size_t
len
,
const
void
*
msg
)
{
struct
iovec
iov
[
1
];
struct
msghdr
msgh
;
char
buf
[
CMSG_SIZE
];
struct
cmsghdr
*
h
;
int
ret
;
/* At least one byte needs to be sent, for some reason (?) */
if
(
len
<
1
)
return
0
;
memset
(
&
iov
[
0
],
0
,
sizeof
(
struct
iovec
));
memset
(
&
msgh
,
0
,
sizeof
(
struct
msghdr
));
memset
(
buf
,
0
,
CMSG_SIZE
);
msgh
.
msg_name
=
NULL
;
msgh
.
msg_namelen
=
0
;
msgh
.
msg_iov
=
iov
;
msgh
.
msg_iovlen
=
1
;
msgh
.
msg_control
=
buf
;
msgh
.
msg_controllen
=
CMSG_SIZE
;
msgh
.
msg_flags
=
0
;
/* Message to be sent */
iov
[
0
].
iov_base
=
(
void
*
)
msg
;
iov
[
0
].
iov_len
=
len
;
/* Control data */
h
=
CMSG_FIRSTHDR
(
&
msgh
);
h
->
cmsg_len
=
CMSG_LEN
(
sizeof
(
int
));
h
->
cmsg_level
=
SOL_SOCKET
;
h
->
cmsg_type
=
SCM_RIGHTS
;
((
int
*
)
CMSG_DATA
(
h
))[
0
]
=
fd
;
ret
=
sendmsg
(
sock
,
&
msgh
,
0
);
return
ret
;
}
/*
* _recvfd(): receive a message and a file descriptor.
*
* Parameters:
* sock: AF_UNIX socket
* len: pointer to the length of the message buffer, modified on return
* buf: buffer to contain the received buffer
*
* If len is 0 or buf is NULL, the received message is stored in a temporary
* buffer and discarded later.
*
* Return value:
* On success, recvfd returns the received file descriptor, and len points to
* the size of the received message.
* If recvmsg fails, -1 is returned, and errno is set appropriately.
* If the received data does not carry exactly one file descriptor, -2 is
* returned. If the received file descriptor is not valid, -3 is returned.
*
*/
int
_recvfd
(
int
sock
,
size_t
*
len
,
void
*
buf
)
{
struct
iovec
iov
[
1
];
struct
msghdr
msgh
;
char
cmsgbuf
[
CMSG_SIZE
];
char
extrabuf
[
4096
];
struct
cmsghdr
*
h
;
int
st
,
fd
;
if
(
*
len
<
1
||
buf
==
NULL
)
{
/* For some reason, again, one byte needs to be received. (it would not
* block?) */
iov
[
0
].
iov_base
=
extrabuf
;
iov
[
0
].
iov_len
=
sizeof
(
extrabuf
);
}
else
{
iov
[
0
].
iov_base
=
buf
;
iov
[
0
].
iov_len
=
*
len
;
}
msgh
.
msg_name
=
NULL
;
msgh
.
msg_namelen
=
0
;
msgh
.
msg_iov
=
iov
;
msgh
.
msg_iovlen
=
1
;
msgh
.
msg_control
=
cmsgbuf
;
msgh
.
msg_controllen
=
CMSG_SIZE
;
msgh
.
msg_flags
=
0
;
st
=
recvmsg
(
sock
,
&
msgh
,
0
);
if
(
st
<
0
)
return
-
1
;
*
len
=
st
;
h
=
CMSG_FIRSTHDR
(
&
msgh
);
/* Check if we received what we expected */
if
(
h
==
NULL
||
h
->
cmsg_len
!=
CMSG_LEN
(
sizeof
(
int
))
||
h
->
cmsg_level
!=
SOL_SOCKET
||
h
->
cmsg_type
!=
SCM_RIGHTS
)
{
return
-
2
;
}
fd
=
((
int
*
)
CMSG_DATA
(
h
))[
0
];
if
(
fd
<
0
)
return
-
3
;
return
fd
;
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment