3 * System-specific functionality
5 * (c) 2019 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the Python interface to mLib.
12 * mLib/Python is free software: you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
17 * mLib/Python is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with mLib/Python. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 /*----- Header files ------------------------------------------------------*/
30 #include "mLib-python.h"
32 /*----- Main code ---------------------------------------------------------*/
34 static int getint(PyObject
*obj
, int *i_out
)
40 t
= PyNumber_Index(obj
); if (!t
) goto end
;
41 i
= PyInt_AsLong(t
); if (i
== -1 && PyErr_Occurred()) goto end
;
42 if (INT_MIN
> i
|| i
> INT_MAX
) OVFERR("out of range");
50 static int convfd(PyObject
*obj
, void *p
)
56 if (getint(obj
, fd_out
)) {
58 t
= PyObject_CallMethod(obj
, "fileno", 0); if (!t
) goto end
;
59 if (getint(t
, fd_out
)) goto end
;
67 static PyObject
*meth_detachtty(PyObject
*me
)
68 { detachtty(); RETURN_NONE
; }
70 static PyObject
*meth_daemonize(PyObject
*me
)
72 if (daemonize()) OSERR(0);
78 static PyObject
*meth_fdflags(PyObject
*me
, PyObject
*arg
, PyObject
*kw
)
81 unsigned fbic
= 0, fxor
= 0, fdbic
= 0, fdxor
= 0;
82 static const char *const kwlist
[] =
83 { "file", "fbic", "fxor", "fdbic", "fdxor", 0 };
85 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O&|O&O&O&O&:fdflags", KWLIST
,
87 convuint
, &fbic
, convuint
, &fxor
,
88 convuint
, &fdbic
, convuint
, &fdxor
))
90 if (fdflags(fd
, fbic
, fxor
, fdbic
, fdxor
)) OSERR(0);
96 static PyObject
*meth_fdsend(PyObject
*me
, PyObject
*arg
, PyObject
*kw
)
102 static const char *const kwlist
[] = { "sock", "file", "buffer", 0 };
104 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O&O&O&:fdsend", KWLIST
,
105 convfd
, &sock
, convfd
, &fd
,
108 n
= fdpass_send(sock
, fd
, buf
.p
, buf
.sz
); if (n
< 0) OSERR(0);
109 rc
= PyInt_FromLong(n
);
114 static PyObject
*meth_fdrecv(PyObject
*me
, PyObject
*arg
, PyObject
*kw
)
120 PyObject
*buf
= 0, *rc
= 0;
121 static const char *const kwlist
[] = { "sock", "size", 0 };
123 if (!PyArg_ParseTupleAndKeywords(arg
, kw
, "O&O&:fdrecv", KWLIST
,
124 convfd
, &sock
, convszt
, &sz
))
126 BIN_PREPAREWRITE(buf
, p
, sz
);
127 n
= fdpass_recv(sock
, &fd
, p
, sz
); if (n
< 0) OSERR(0);
128 BIN_DONEWRITE(buf
, n
);
129 rc
= Py_BuildValue("(iN)", fd
, buf
); buf
= 0;
135 static PyObject
*meth_mdup(PyObject
*me
, PyObject
*arg
)
138 PyObject
*t
= 0, *u
= 0, *rc
= 0;
144 if (!PyArg_ParseTuple(arg
, "O:mdup", &v
)) goto end
;
145 n
= PySequence_Size(v
); if (n
< 0) goto end
;
146 vv
= xmalloc(n
*sizeof(*vv
));
147 for (i
= 0; i
< n
; i
++) {
148 t
= PySequence_GetItem(v
, i
); if (!t
) goto end
;
149 m
= PySequence_Size(t
); if (m
< 0) goto end
;
150 if (m
!= 2) VALERR("expected a list of pairs");
152 u
= PySequence_GetItem(t
, 0);
153 if (getint(u
, &vv
[i
].cur
)) goto end
;
156 u
= PySequence_GetItem(t
, 1);
157 if (getint(u
, &vv
[i
].want
)) goto end
;
165 for (i
= 0; i
< n
; i
++) {
166 t
= Py_BuildValue("(ii)", vv
[i
].cur
, vv
[i
].want
);
167 if (PySequence_SetItem(v
, i
, t
)) goto end
;
172 rc
= v
; Py_INCREF(rc
);
175 Py_XDECREF(t
); Py_XDECREF(u
);
179 static const PyMethodDef methods
[] = {
180 #define METHNAME(name) meth_##name
181 NAMETH(detachtty
, "detachtty(): fork, detatch controlling terminal")
182 NAMETH(daemonize
, "daemonize(): fork and become a daemon")
183 KWMETH(fdflags
, "fdflags(FILE, [fbic = 0], [fxor = 0], "
184 "[fdbic = 0], [fdxor = 0])")
185 KWMETH(fdsend
, "fdsend(FILE, FD, BUFFER) -> N")
186 KWMETH(fdrecv
, "fdrecv(FILE, SIZE) -> FD, BUFFER")
187 METH (mdup
, "mdup(LIST) -> LIST:\n"
188 " LIST is a list (mutable sequence) of pairs (CUR, WANT). Duplicate\n"
189 " each CUR file descriptor as WANT (may be -1 to mean `don't care'),\n"
190 " closing original CUR. Works even if there are cycles. LIST is\n"
191 " updated in place with CUR reflecting the new file descriptors even\n"
192 " on error. Returns the same LIST on success.")
197 void sys_pyinit(void)
202 void sys_pyinsert(PyObject
*mod
)
206 /*----- That's all, folks -------------------------------------------------*/