Added the `ratequeue' program.
[ashd.git] / python3 / htp.c
1 /*
2     ashd - A Sane HTTP Daemon
3     Copyright (C) 2008  Fredrik Tolf <fredrik@dolda2000.com>
4
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <Python.h>
20 #include <errno.h>
21
22 #include <ashd/utils.h>
23 #include <ashd/proc.h>
24
25 static PyObject *p_recvfd(PyObject *self, PyObject *args)
26 {
27     int fd, ret;
28     char *data;
29     size_t dlen;
30     PyObject *ro;
31     
32     fd = 0;
33     if(!PyArg_ParseTuple(args, "|i", &fd))
34         return(NULL);
35     while(1) {
36         Py_BEGIN_ALLOW_THREADS;
37         ret = recvfd(fd, &data, &dlen);
38         Py_END_ALLOW_THREADS;
39         if(ret < 0) {
40             if(errno == 0)
41                 return(Py_BuildValue("OO", Py_None, Py_None));
42             if(errno == EINTR) {
43                 if(PyErr_CheckSignals())
44                     return(NULL);
45                 continue;
46             }
47             PyErr_SetFromErrno(PyExc_OSError);
48             return(NULL);
49         }
50         ro = Py_BuildValue("Ni", PyBytes_FromStringAndSize(data, dlen), ret);
51         free(data);
52         return(ro);
53     }
54 }
55
56 static PyObject *p_sendfd(PyObject *self, PyObject *args)
57 {
58     int sock, fd, ret;
59     Py_buffer data;
60     
61     if(!PyArg_ParseTuple(args, "iiy*", &sock, &fd, &data))
62         return(NULL);
63     while(1) {
64         Py_BEGIN_ALLOW_THREADS;
65         ret = sendfd(sock, fd, data.buf, data.len);
66         Py_END_ALLOW_THREADS;
67         PyBuffer_Release(&data);
68         if(ret < 0) {
69             if(errno == EINTR) {
70                 if(PyErr_CheckSignals())
71                     return(NULL);
72                 continue;
73             }
74             PyErr_SetFromErrno(PyExc_OSError);
75             return(NULL);
76         }
77         Py_RETURN_NONE;
78     }
79 }
80
81 static PyMethodDef methods[] = {
82     {"recvfd", p_recvfd, METH_VARARGS, "Receive a datagram and a file descriptor"},
83     {"sendfd", p_sendfd, METH_VARARGS, "Send a datagram and a file descriptor"},
84     {NULL, NULL, 0, NULL}
85 };
86
87 static struct PyModuleDef module = {
88     PyModuleDef_HEAD_INIT,
89     .m_name = "htlib",
90     .m_size = -1,
91     .m_methods = methods,
92 };
93
94 PyMODINIT_FUNC PyInit_htlib(void)
95 {
96     return(PyModule_Create(&module));
97 }