Python wrapper function to establish controlling tty
This commit is contained in:
@@ -180,8 +180,27 @@ spawn(PyObject *self UNUSED, PyObject *args) {
|
|||||||
return PyLong_FromLong(pid);
|
return PyLong_FromLong(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
establish_controlling_tty(PyObject *self UNUSED, PyObject *args) {
|
||||||
|
const char *ttyname;
|
||||||
|
int stdin_fd, stdout_fd, stderr_fd;
|
||||||
|
if (!PyArg_ParseTuple(args, "siii", &ttyname, &stdin_fd, &stdout_fd, &stderr_fd)) return NULL;
|
||||||
|
int tfd = safe_open(ttyname, O_RDWR, 0);
|
||||||
|
if (tfd == -1) return PyErr_SetFromErrnoWithFilename(PyExc_OSError, ttyname);
|
||||||
|
#ifdef TIOCSCTTY
|
||||||
|
// On BSD open() does not establish the controlling terminal
|
||||||
|
if (ioctl(tfd, TIOCSCTTY, 0) == -1) return PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
#endif
|
||||||
|
if (dup2(tfd, stdin_fd) == -1) return PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
if (dup2(tfd, stdout_fd) == -1) return PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
if (dup2(tfd, stderr_fd) == -1) return PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
safe_close(tfd, __FILE__, __LINE__);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
METHODB(spawn, METH_VARARGS),
|
METHODB(spawn, METH_VARARGS),
|
||||||
|
METHODB(establish_controlling_tty, METH_VARARGS),
|
||||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1379,3 +1379,7 @@ def shm_unlink(name: str) -> None:
|
|||||||
|
|
||||||
def sigqueue(pid: int, signal: int, value: int) -> None:
|
def sigqueue(pid: int, signal: int, value: int) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def establish_controlling_tty(ttyname: str, stdin: int, stdout: int, stderr: int) -> None:
|
||||||
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user