Function to create a randomly named UNIX domain socket
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
extern PyTypeObject Screen_Type;
|
extern PyTypeObject Screen_Type;
|
||||||
|
|
||||||
@@ -1756,7 +1757,6 @@ cocoa_set_menubar_title(PyObject *self UNUSED, PyObject *args UNUSED) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
|
|
||||||
send_data_to_peer(PyObject *self UNUSED, PyObject *args) {
|
send_data_to_peer(PyObject *self UNUSED, PyObject *args) {
|
||||||
char * msg; Py_ssize_t sz;
|
char * msg; Py_ssize_t sz;
|
||||||
unsigned long long peer_id;
|
unsigned long long peer_id;
|
||||||
@@ -1765,8 +1765,23 @@ send_data_to_peer(PyObject *self UNUSED, PyObject *args) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
random_unix_socket(PyObject *self UNUSED, PyObject *args UNUSED) {
|
||||||
|
int fd, optval = 1;
|
||||||
|
struct sockaddr_un bind_addr = {.sun_family=AF_UNIX};
|
||||||
|
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0) return PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof optval) != 0) goto fail;
|
||||||
|
if (bind(fd, (struct sockaddr *)&bind_addr, sizeof(sa_family_t)) != 0) goto fail;
|
||||||
|
return PyLong_FromLong((long)fd);
|
||||||
|
fail:
|
||||||
|
safe_close(fd, __FILE__, __LINE__);
|
||||||
|
return PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
}
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
METHODB(safe_pipe, METH_VARARGS),
|
METHODB(safe_pipe, METH_VARARGS),
|
||||||
|
METHODB(random_unix_socket, METH_NOARGS),
|
||||||
{"add_timer", (PyCFunction)add_python_timer, METH_VARARGS, ""},
|
{"add_timer", (PyCFunction)add_python_timer, METH_VARARGS, ""},
|
||||||
{"remove_timer", (PyCFunction)remove_python_timer, METH_VARARGS, ""},
|
{"remove_timer", (PyCFunction)remove_python_timer, METH_VARARGS, ""},
|
||||||
METHODB(monitor_pid, METH_VARARGS),
|
METHODB(monitor_pid, METH_VARARGS),
|
||||||
|
|||||||
@@ -1387,3 +1387,7 @@ def sigqueue(pid: int, signal: int, value: int) -> None:
|
|||||||
|
|
||||||
def establish_controlling_tty(ttyname: str, stdin: int, stdout: int, stderr: int) -> None:
|
def establish_controlling_tty(ttyname: str, stdin: int, stdout: int, stderr: int) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def random_unix_socket() -> int:
|
||||||
|
pass
|
||||||
|
|||||||
@@ -372,15 +372,18 @@ class startup_notification_handler:
|
|||||||
end_startup_notification(self.ctx)
|
end_startup_notification(self.ctx)
|
||||||
|
|
||||||
|
|
||||||
def remove_socket_file(s: 'Socket', path: Optional[str] = None) -> None:
|
def remove_socket_file(s: 'Socket', path: Optional[str] = None, is_dir: Optional[Callable[[str], None]] = None) -> None:
|
||||||
with suppress(OSError):
|
with suppress(OSError):
|
||||||
s.close()
|
s.close()
|
||||||
if path:
|
if path:
|
||||||
with suppress(OSError):
|
with suppress(OSError):
|
||||||
os.unlink(path)
|
if is_dir:
|
||||||
|
is_dir(path)
|
||||||
|
else:
|
||||||
|
os.unlink(path)
|
||||||
|
|
||||||
|
|
||||||
def unix_socket_paths(name: str, ext: str = '.lock') -> Generator[str, None, None]:
|
def unix_socket_directories() -> Iterator[str]:
|
||||||
import tempfile
|
import tempfile
|
||||||
home = os.path.expanduser('~')
|
home = os.path.expanduser('~')
|
||||||
candidates = [tempfile.gettempdir(), home]
|
candidates = [tempfile.gettempdir(), home]
|
||||||
@@ -389,8 +392,39 @@ def unix_socket_paths(name: str, ext: str = '.lock') -> Generator[str, None, Non
|
|||||||
candidates = [user_cache_dir(), '/Library/Caches']
|
candidates = [user_cache_dir(), '/Library/Caches']
|
||||||
for loc in candidates:
|
for loc in candidates:
|
||||||
if os.access(loc, os.W_OK | os.R_OK | os.X_OK):
|
if os.access(loc, os.W_OK | os.R_OK | os.X_OK):
|
||||||
filename = ('.' if loc == home else '') + name + ext
|
yield loc
|
||||||
yield os.path.join(loc, filename)
|
|
||||||
|
|
||||||
|
def unix_socket_paths(name: str, ext: str = '.lock') -> Generator[str, None, None]:
|
||||||
|
home = os.path.expanduser('~')
|
||||||
|
for loc in unix_socket_directories():
|
||||||
|
filename = ('.' if loc == home else '') + name + ext
|
||||||
|
yield os.path.join(loc, filename)
|
||||||
|
|
||||||
|
|
||||||
|
def random_unix_socket() -> 'Socket':
|
||||||
|
import shutil
|
||||||
|
import socket
|
||||||
|
import stat
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
from kitty.fast_data_types import random_unix_socket as rus
|
||||||
|
try:
|
||||||
|
fd = rus()
|
||||||
|
except OSError:
|
||||||
|
for path in unix_socket_directories():
|
||||||
|
ans = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0)
|
||||||
|
tdir = tempfile.mkdtemp(prefix='.kitty-', dir=path)
|
||||||
|
atexit.register(remove_socket_file, ans, tdir, shutil.rmtree)
|
||||||
|
path = os.path.join(tdir, 's')
|
||||||
|
ans.bind(path)
|
||||||
|
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
ans = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0, fileno=fd)
|
||||||
|
ans.set_inheritable(False)
|
||||||
|
ans.setblocking(False)
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def single_instance_unix(name: str) -> bool:
|
def single_instance_unix(name: str) -> bool:
|
||||||
|
|||||||
Reference in New Issue
Block a user