1 #include "uwsgi_python.h"
2 
3 extern struct uwsgi_server uwsgi;
4 extern struct uwsgi_python up;
5 extern struct uwsgi_plugin python_plugin;
6 
py_uwsgi_add_var(PyObject * self,PyObject * args)7 static PyObject *py_uwsgi_add_var(PyObject * self, PyObject * args) {
8 	 char *key = NULL;
9         Py_ssize_t keylen = 0;
10         char *val = NULL;
11         Py_ssize_t vallen = 0;
12 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
13 
14 	if (!PyArg_ParseTuple(args, "s#s#", &key, &keylen, &val, &vallen)) {
15         	return NULL;
16         }
17 
18 	if (!uwsgi_req_append(wsgi_req, key, keylen, val, vallen)) {
19 		return PyErr_Format(PyExc_ValueError, "unable to add request var, check your buffer size");
20 	}
21 
22 	Py_INCREF(Py_True);
23 	return Py_True;
24 }
25 
py_uwsgi_micros(PyObject * self,PyObject * args)26 static PyObject *py_uwsgi_micros(PyObject * self, PyObject * args) {
27         return PyLong_FromUnsignedLongLong(uwsgi_micros());
28 }
29 
py_uwsgi_signal_wait(PyObject * self,PyObject * args)30 static PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
31 
32         struct wsgi_request *wsgi_req = py_current_wsgi_req();
33 	int wait_for_specific_signal = 0;
34 	uint8_t uwsgi_signal = 0;
35 	int received_signal;
36 
37 	wsgi_req->signal_received = -1;
38 
39 	if (PyTuple_Size(args) > 0) {
40 		if (!PyArg_ParseTuple(args, "|B:", &uwsgi_signal)) {
41                 	return NULL;
42         	}
43 		wait_for_specific_signal = 1;
44 	}
45 
46 	UWSGI_RELEASE_GIL;
47 
48 	if (wait_for_specific_signal) {
49 		received_signal = uwsgi_signal_wait(uwsgi_signal);
50 	}
51 	else {
52 		received_signal = uwsgi_signal_wait(-1);
53 	}
54 
55 	if (received_signal < 0) {
56 		UWSGI_GET_GIL;
57 		return PyErr_Format(PyExc_SystemError, "error waiting for signal");
58 	}
59 
60         wsgi_req->signal_received = received_signal;
61 
62 	UWSGI_GET_GIL;
63 
64         return PyString_FromString("");
65 }
66 
py_uwsgi_signal_received(PyObject * self,PyObject * args)67 static PyObject *py_uwsgi_signal_received(PyObject * self, PyObject * args) {
68 
69         struct wsgi_request *wsgi_req = py_current_wsgi_req();
70 
71         return PyInt_FromLong(wsgi_req->signal_received);
72 }
73 
74 
uwsgi_encode_pydict(PyObject * pydict,uint16_t * size)75 char *uwsgi_encode_pydict(PyObject * pydict, uint16_t * size) {
76 
77 	int i;
78 	PyObject *zero, *key, *val;
79 	uint16_t keysize, valsize;
80 
81 
82 	char *buf, *bufptr;
83 
84 	PyObject *vars = PyDict_Items(pydict);
85 
86 	if (!vars) {
87 		PyErr_Print();
88 		return NULL;
89 	}
90 
91 	*size = 0;
92 
93 	// calc the packet size
94 	// try to fallback whenever possible
95 	for (i = 0; i < PyList_Size(vars); i++) {
96 		zero = PyList_GetItem(vars, i);
97 		if (!zero) {
98 			PyErr_Print();
99 			continue;
100 		}
101 
102 		if (!PyTuple_Check(zero)) {
103 			uwsgi_log("invalid python dictionary item\n");
104 			continue;
105 		}
106 
107 		if (PyTuple_Size(zero) < 2) {
108 			uwsgi_log("invalid python dictionary item\n");
109 			continue;
110 		}
111 		key = PyTuple_GetItem(zero, 0);
112 		val = PyTuple_GetItem(zero, 1);
113 
114 		if (!PyString_Check(key) || !PyString_Check(val)) {
115 			continue;
116 		}
117 
118 
119 		keysize = PyString_Size(key);
120 		valsize = PyString_Size(val);
121 
122 		*size += (keysize + 2 + valsize + 2);
123 
124 		// do not DECREF here !!!
125 		//Py_DECREF(zero);
126 	}
127 
128 	if (*size <= 4) {
129 		uwsgi_log("empty python dictionary\n");
130 		return NULL;
131 	}
132 
133 	// remember to free this memory !!!
134 	buf = malloc(*size);
135 	if (!buf) {
136 		uwsgi_error("malloc()");
137 		return NULL;
138 	}
139 
140 	bufptr = buf;
141 
142 	for (i = 0; i < PyList_Size(vars); i++) {
143 		zero = PyList_GetItem(vars, i);
144 		if (!zero) {
145 			PyErr_Print();
146 			continue;
147 		}
148 
149 		if (!PyTuple_Check(zero)) {
150 			uwsgi_log("invalid python dictionary item\n");
151 			continue;
152 		}
153 
154 		if (PyTuple_Size(zero) < 2) {
155 			uwsgi_log("invalid python dictionary item\n");
156 			continue;
157 		}
158 		key = PyTuple_GetItem(zero, 0);
159 		val = PyTuple_GetItem(zero, 1);
160 
161 
162 		if (!key || !val) {
163 			PyErr_Print();
164 			continue;
165 		}
166 
167 		if (!PyString_Check(key) || !PyString_Check(val)) {
168 			continue;
169 		}
170 
171 
172 		keysize = PyString_Size(key);
173 		valsize = PyString_Size(val);
174 		if (bufptr + keysize + 2 + valsize + 2 <= buf + *size) {
175 
176 			*bufptr++ = (uint8_t) (keysize & 0xff);
177         		*bufptr++ = (uint8_t) ((keysize >> 8) & 0xff);
178 			memcpy(bufptr, PyString_AsString(key), keysize);
179 			bufptr += keysize;
180 
181 			*bufptr++ = (uint8_t) (valsize & 0xff);
182         		*bufptr++ = (uint8_t) ((valsize >> 8) & 0xff);
183 			memcpy(bufptr, PyString_AsString(val), valsize);
184 			bufptr += valsize;
185 		}
186 
187 	}
188 
189 	return buf;
190 
191 }
192 
py_uwsgi_listen_queue(PyObject * self,PyObject * args)193 static PyObject *py_uwsgi_listen_queue(PyObject * self, PyObject * args) {
194 
195 	int id = 0;
196 
197 	if (!PyArg_ParseTuple(args, "|i:listen_queue", &id)) {
198                 return NULL;
199         }
200 
201 	struct uwsgi_socket *uwsgi_sock = uwsgi_get_socket_by_num(id);
202 	if (!uwsgi_sock) {
203 		return PyErr_Format(PyExc_ValueError, "unable to find socket %d", id);
204 	}
205 
206 	return PyInt_FromLong(uwsgi_sock->queue);
207 }
208 
py_uwsgi_close(PyObject * self,PyObject * args)209 static PyObject *py_uwsgi_close(PyObject * self, PyObject * args) {
210 
211 	int fd;
212 
213 	if (!PyArg_ParseTuple(args, "i:close", &fd)) {
214 		return NULL;
215 	}
216 
217 	close(fd);
218 
219 	Py_INCREF(Py_None);
220 	return Py_None;
221 
222 }
223 
py_uwsgi_add_cron(PyObject * self,PyObject * args)224 static PyObject *py_uwsgi_add_cron(PyObject * self, PyObject * args) {
225 
226 	uint8_t uwsgi_signal;
227 	int minute, hour, day, month, week;
228 
229 	if (!PyArg_ParseTuple(args, "Biiiii:add_cron", &uwsgi_signal, &minute, &hour, &day, &month, &week)) {
230                 return NULL;
231         }
232 
233 	if (uwsgi_signal_add_cron(uwsgi_signal, minute, hour, day, month, week)) {
234 		return PyErr_Format(PyExc_ValueError, "unable to add cron");
235 	}
236 
237 	Py_INCREF(Py_True);
238 	return Py_True;
239 }
240 
241 
py_uwsgi_add_timer(PyObject * self,PyObject * args)242 static PyObject *py_uwsgi_add_timer(PyObject * self, PyObject * args) {
243 
244 	uint8_t uwsgi_signal;
245 	int secs;
246 
247 	if (!PyArg_ParseTuple(args, "Bi:add_timer", &uwsgi_signal, &secs)) {
248 		return NULL;
249 	}
250 
251 	if (uwsgi_add_timer(uwsgi_signal, secs))
252 		return PyErr_Format(PyExc_ValueError, "unable to add timer");
253 
254 	Py_INCREF(Py_None);
255 	return Py_None;
256 }
257 
py_uwsgi_add_rb_timer(PyObject * self,PyObject * args)258 PyObject *py_uwsgi_add_rb_timer(PyObject * self, PyObject * args) {
259 
260         uint8_t uwsgi_signal;
261         int secs;
262 	int iterations = 0;
263 
264         if (!PyArg_ParseTuple(args, "Bi|i:add_rb_timer", &uwsgi_signal, &secs, &iterations)) {
265                 return NULL;
266         }
267 
268         if (uwsgi_signal_add_rb_timer(uwsgi_signal, secs, iterations))
269                 return PyErr_Format(PyExc_ValueError, "unable to add rb_timer");
270 
271         Py_INCREF(Py_None);
272         return Py_None;
273 }
274 
275 
276 
py_uwsgi_add_file_monitor(PyObject * self,PyObject * args)277 PyObject *py_uwsgi_add_file_monitor(PyObject * self, PyObject * args) {
278 
279 	uint8_t uwsgi_signal;
280 	char *filename;
281 
282 	if (!PyArg_ParseTuple(args, "Bs:add_file_monitor", &uwsgi_signal, &filename)) {
283 		return NULL;
284 	}
285 
286 	if (uwsgi_add_file_monitor(uwsgi_signal, filename))
287 		return PyErr_Format(PyExc_ValueError, "unable to add file monitor");
288 
289 	Py_INCREF(Py_None);
290 	return Py_None;
291 }
292 
py_uwsgi_call(PyObject * self,PyObject * args)293 PyObject *py_uwsgi_call(PyObject * self, PyObject * args) {
294 
295 	char *func;
296 	uint64_t size = 0;
297 	PyObject *py_func;
298 	int argc = PyTuple_Size(args);
299 	int i;
300 	char *argv[256];
301 	uint16_t argvs[256];
302 
303 	// TODO better error reporting
304 	if (argc < 1)
305 		goto clear;
306 
307 	py_func = PyTuple_GetItem(args, 0);
308 
309 	if (!PyString_Check(py_func))
310 		goto clear;
311 
312 	func = PyString_AsString(py_func);
313 
314 	for (i = 0; i < (argc - 1); i++) {
315 		PyObject *py_str = PyTuple_GetItem(args, i + 1);
316 		if (!PyString_Check(py_str)) {
317 			goto clear;
318 		}
319 		argv[i] = PyString_AsString(py_str);
320 		argvs[i] = PyString_Size(py_str);
321 	}
322 
323 	UWSGI_RELEASE_GIL;
324 	// response must always be freed
325 	char *response = uwsgi_do_rpc(NULL, func, argc - 1, argv, argvs, &size);
326 	UWSGI_GET_GIL;
327 
328 	if (response) {
329 		PyObject *ret = PyString_FromStringAndSize(response, size);
330 		free(response);
331 		return ret;
332 	}
333 
334 	Py_INCREF(Py_None);
335 	return Py_None;
336 
337       clear:
338 
339 	return PyErr_Format(PyExc_ValueError, "unable to call rpc function");
340 
341 }
342 
py_uwsgi_rpc_list(PyObject * self,PyObject * args)343 PyObject *py_uwsgi_rpc_list(PyObject * self, PyObject * args) {
344 
345 	uint64_t i;
346 	PyObject *rpc_list = PyTuple_New(uwsgi.shared->rpc_count[uwsgi.mywid]);
347 
348 	int pos = (uwsgi.mywid * uwsgi.rpc_max);
349 	for (i = 0; i < uwsgi.shared->rpc_count[uwsgi.mywid]; i++) {
350 		if (uwsgi.rpc_table[pos + i].name[0] != 0) {
351 			PyTuple_SetItem(rpc_list, i, PyString_FromString(uwsgi.rpc_table[pos + i].name));
352 		}
353 	}
354 
355 	return rpc_list;
356 
357 }
358 
py_uwsgi_rpc(PyObject * self,PyObject * args)359 PyObject *py_uwsgi_rpc(PyObject * self, PyObject * args) {
360 
361 	char *node = NULL, *func;
362 	uint64_t size = 0;
363 	PyObject *py_node, *py_func;
364 
365 	int argc = PyTuple_Size(args);
366 	char *argv[256];
367 	uint16_t argvs[256];
368 
369 	int i;
370 
371 	// TODO better error reporting
372 	if (argc < 2)
373 		goto clear;
374 
375 	py_node = PyTuple_GetItem(args, 0);
376 
377 	if (PyString_Check(py_node)) {
378 		node = PyString_AsString(py_node);
379 	}
380 #ifdef PYTHREE
381         else if (PyUnicode_Check(py_node)) {
382                 node = PyBytes_AsString(PyUnicode_AsLatin1String(py_node));
383 	}
384 #endif
385 
386 	py_func = PyTuple_GetItem(args, 1);
387 
388 	if (!PyString_Check(py_func))
389 		goto clear;
390 
391 	func = PyString_AsString(py_func);
392 
393 	for (i = 0; i < (argc - 2); i++) {
394 		PyObject *py_str = PyTuple_GetItem(args, i + 2);
395 		if (!PyString_Check(py_str))
396 			goto clear;
397 		argv[i] = PyString_AsString(py_str);
398 		argvs[i] = PyString_Size(py_str);
399 	}
400 
401 	UWSGI_RELEASE_GIL;
402 	char *response = uwsgi_do_rpc(node, func, argc - 2, argv, argvs, &size);
403 	UWSGI_GET_GIL;
404 
405 	if (response) {
406                 PyObject *ret = PyString_FromStringAndSize(response, size);
407                 free(response);
408                 return ret;
409         }
410 
411 	Py_INCREF(Py_None);
412         return Py_None;
413 
414       clear:
415 
416         return PyErr_Format(PyExc_ValueError, "unable to call rpc function");
417 
418 }
419 
py_uwsgi_register_rpc(PyObject * self,PyObject * args)420 PyObject *py_uwsgi_register_rpc(PyObject * self, PyObject * args) {
421 
422 	uint8_t argc = 0;
423 	char *name;
424 	PyObject *func;
425 
426 	if (!PyArg_ParseTuple(args, "sO|B:register_rpc", &name, &func, &argc)) {
427 		return NULL;
428 	}
429 
430 	Py_INCREF(func);
431 
432 	if (uwsgi_register_rpc(name, &python_plugin, argc, func)) {
433 		return PyErr_Format(PyExc_ValueError, "unable to register rpc function");
434 	}
435 
436 	Py_INCREF(Py_True);
437 	return Py_True;
438 }
439 
py_uwsgi_signal_registered(PyObject * self,PyObject * args)440 PyObject *py_uwsgi_signal_registered(PyObject * self, PyObject * args) {
441 	uint8_t uwsgi_signal;
442 
443 	if (!PyArg_ParseTuple(args, "B:signal_registered", &uwsgi_signal)) {
444                 return NULL;
445         }
446 
447 	if (uwsgi_signal_registered(uwsgi_signal)) {
448 		Py_INCREF(Py_True);
449 		return Py_True;
450 	}
451 
452 	Py_INCREF(Py_None);
453 	return Py_None;
454 }
455 
456 #ifdef UWSGI_SSL
py_uwsgi_i_am_the_lord(PyObject * self,PyObject * args)457 PyObject *py_uwsgi_i_am_the_lord(PyObject * self, PyObject * args) {
458 	char *legion_name = NULL;
459 
460         if (!PyArg_ParseTuple(args, "s:i_am_the_lord", &legion_name)) {
461                 return NULL;
462         }
463 
464         if (uwsgi_legion_i_am_the_lord(legion_name)) {
465                 Py_INCREF(Py_True);
466                 return Py_True;
467         }
468 
469         Py_INCREF(Py_False);
470         return Py_False;
471 }
472 
py_uwsgi_lord_scroll(PyObject * self,PyObject * args)473 PyObject *py_uwsgi_lord_scroll(PyObject * self, PyObject * args) {
474         char *legion_name = NULL;
475 
476         if (!PyArg_ParseTuple(args, "s:lord_scroll", &legion_name)) {
477                 return NULL;
478         }
479 
480 	uint16_t rlen = 0;
481 	char *buf = uwsgi_legion_lord_scroll(legion_name, &rlen);
482 	if (!buf) {
483         	Py_INCREF(Py_None);
484         	return Py_None;
485 	}
486 
487 	PyObject *ret = PyString_FromStringAndSize(buf, rlen);
488 	free(buf);
489         return ret;
490 }
491 
scrolls_items(uint16_t pos,char * key,uint16_t keylen,void * data)492 static void scrolls_items(uint16_t pos, char *key, uint16_t keylen, void *data) {
493 	PyObject *list = (PyObject *) data;
494 	PyObject *zero = PyString_FromStringAndSize(key, keylen);
495 	PyList_Append(list, zero);
496 	Py_DECREF(zero);
497 }
498 
py_uwsgi_scrolls(PyObject * self,PyObject * args)499 PyObject *py_uwsgi_scrolls(PyObject * self, PyObject * args) {
500         char *legion_name = NULL;
501 
502         if (!PyArg_ParseTuple(args, "s:scrolls", &legion_name)) {
503                 return NULL;
504         }
505 
506 	uint64_t rlen = 0;
507         char *buf = uwsgi_legion_scrolls(legion_name, &rlen);
508 	if (!buf) goto end;
509 	PyObject *list = PyList_New(0);
510 	if (uwsgi_hooked_parse_array(buf, rlen, scrolls_items, list)) {
511 		goto error;
512 	}
513 	free(buf);
514 	return list;
515 error:
516 	free(buf);
517 end:
518 	Py_INCREF(Py_None);
519 	return Py_None;
520 }
521 
522 
523 #endif
524 
py_uwsgi_register_signal(PyObject * self,PyObject * args)525 PyObject *py_uwsgi_register_signal(PyObject * self, PyObject * args) {
526 
527 	uint8_t uwsgi_signal;
528 	char *signal_kind;
529 	PyObject *handler;
530 
531 	if (!PyArg_ParseTuple(args, "BsO:register_signal", &uwsgi_signal, &signal_kind, &handler)) {
532 		return NULL;
533 	}
534 
535 	Py_INCREF(handler);
536 
537 	if (uwsgi_register_signal(uwsgi_signal, signal_kind, handler, 0)) {
538 		return PyErr_Format(PyExc_ValueError, "unable to register signal");
539 	}
540 
541 	Py_INCREF(Py_None);
542 	return Py_None;
543 }
544 
py_uwsgi_signal(PyObject * self,PyObject * args)545 PyObject *py_uwsgi_signal(PyObject * self, PyObject * args) {
546 
547 	uint8_t uwsgi_signal;
548 	char *remote = NULL;
549 
550 	if (!PyArg_ParseTuple(args, "B|s:signal", &uwsgi_signal, &remote)) {
551 		return NULL;
552 	}
553 
554 	if (remote) {
555 #ifdef UWSGI_DEBUG
556 		uwsgi_log("sending signal %d to node %s\n", uwsgi_signal, remote);
557 #endif
558 		int ret = uwsgi_remote_signal_send(remote, uwsgi_signal);
559 		if (ret == 1) goto clear;
560 		if (ret == -1)
561 			return PyErr_Format(PyExc_IOError, "unable to deliver signal %d to node %s", uwsgi_signal, remote);
562 		if (ret == 0)
563 			return PyErr_Format(PyExc_ValueError, "node %s rejected signal %d", remote, uwsgi_signal);
564 	}
565 	else {
566 #ifdef UWSGI_DEBUG
567 		uwsgi_log("sending signal %d to master\n", uwsgi_signal);
568 #endif
569 		uwsgi_signal_send(uwsgi.signal_socket, uwsgi_signal);
570 	}
571 
572 clear:
573 	Py_INCREF(Py_None);
574 	return Py_None;
575 
576 }
577 
py_uwsgi_log_this(PyObject * self,PyObject * args)578 PyObject *py_uwsgi_log_this(PyObject * self, PyObject * args) {
579 
580 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
581 
582 	wsgi_req->log_this = 1;
583 
584 	Py_INCREF(Py_None);
585 	return Py_None;
586 }
587 
py_uwsgi_alarm(PyObject * self,PyObject * args)588 PyObject *py_uwsgi_alarm(PyObject * self, PyObject * args) {
589 	char *alarm = NULL;
590 	char *msg = NULL;
591 	Py_ssize_t msg_len = 0;
592 	if (!PyArg_ParseTuple(args, "ss#:alarm", &alarm, &msg, &msg_len)) {
593                 return NULL;
594         }
595 
596 	uwsgi_alarm_trigger(alarm, msg, msg_len);
597 
598 	Py_INCREF(Py_None);
599 	return Py_None;
600 }
601 
py_uwsgi_get_logvar(PyObject * self,PyObject * args)602 PyObject *py_uwsgi_get_logvar(PyObject * self, PyObject * args) {
603 
604 	char *key = NULL;
605         Py_ssize_t keylen = 0;
606         struct wsgi_request *wsgi_req = py_current_wsgi_req();
607 
608 	if (!PyArg_ParseTuple(args, "s#:get_logvar", &key, &keylen)) {
609                 return NULL;
610         }
611 
612 	struct uwsgi_logvar *lv = uwsgi_logvar_get(wsgi_req, key, keylen);
613 
614 	if (lv) {
615 		return PyString_FromStringAndSize(lv->val, lv->vallen);
616 	}
617 
618         Py_INCREF(Py_None);
619         return Py_None;
620 }
621 
py_uwsgi_set_logvar(PyObject * self,PyObject * args)622 PyObject *py_uwsgi_set_logvar(PyObject * self, PyObject * args) {
623 
624         char *key = NULL;
625         Py_ssize_t keylen = 0;
626         char *val = NULL;
627         Py_ssize_t vallen = 0;
628         struct wsgi_request *wsgi_req = py_current_wsgi_req();
629 
630         if (!PyArg_ParseTuple(args, "s#s#:set_logvar", &key, &keylen, &val, &vallen)) {
631                 return NULL;
632         }
633 
634         uwsgi_logvar_add(wsgi_req, key, keylen, val, vallen);
635 
636         Py_INCREF(Py_None);
637         return Py_None;
638 }
639 
py_uwsgi_recv(PyObject * self,PyObject * args)640 PyObject *py_uwsgi_recv(PyObject * self, PyObject * args) {
641 
642 	int fd, max_size = 4096;
643 	char buf[4096];
644 	ssize_t rlen;
645 
646 
647 	if (!PyArg_ParseTuple(args, "i|i:recv", &fd, &max_size)) {
648 		return NULL;
649 	}
650 
651 	UWSGI_RELEASE_GIL
652 		// security check
653 		if (max_size > 4096)
654 		max_size = 4096;
655 
656 	rlen = read(fd, buf, max_size);
657 
658 	UWSGI_GET_GIL if (rlen > 0) {
659 		return PyString_FromStringAndSize(buf, rlen);
660 	}
661 
662 	Py_INCREF(Py_None);
663 	return Py_None;
664 }
665 
py_uwsgi_is_connected(PyObject * self,PyObject * args)666 PyObject *py_uwsgi_is_connected(PyObject * self, PyObject * args) {
667 
668 	int fd = -1;
669 
670 	if (!PyArg_ParseTuple(args, "i:is_connected", &fd)) {
671 		return NULL;
672 	}
673 
674 	if (uwsgi_is_connected(fd)) {
675 		Py_INCREF(Py_True);
676 		return Py_True;
677 	}
678 
679 	Py_INCREF(Py_False);
680 	return Py_False;
681 }
682 
683 
py_uwsgi_send(PyObject * self,PyObject * args)684 PyObject *py_uwsgi_send(PyObject * self, PyObject * args) {
685 
686 	PyObject *data;
687 	PyObject *arg1, *arg2;
688 
689 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
690 
691 	int uwsgi_fd = wsgi_req->fd;
692 
693 	if (!PyArg_ParseTuple(args, "O|O:send", &arg1, &arg2)) {
694 		return NULL;
695 	}
696 
697 	if (PyTuple_Size(args) > 1) {
698 		uwsgi_fd = PyInt_AsLong(arg1);
699 		data = arg2;
700 	}
701 	else {
702 		data = arg1;
703 	}
704 
705 	UWSGI_RELEASE_GIL if (write(uwsgi_fd, PyString_AsString(data), PyString_Size(data)) < 0) {
706 		uwsgi_error("write()");
707 		UWSGI_GET_GIL Py_INCREF(Py_None);
708 		return Py_None;
709 	}
710 
711 	UWSGI_GET_GIL Py_INCREF(Py_True);
712 	return Py_True;
713 
714 }
715 
716 #ifdef UWSGI_ROUTING
py_uwsgi_route(PyObject * self,PyObject * args)717 static PyObject *py_uwsgi_route(PyObject * self, PyObject * args) {
718 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
719 	char *router_name = NULL;
720 	char *router_args = NULL;
721 
722 	if (!PyArg_ParseTuple(args, "ss:route", &router_name, &router_args)) {
723                 return NULL;
724         }
725 
726 	int ret = uwsgi_route_api_func(wsgi_req, router_name, uwsgi_str(router_args));
727 	return PyInt_FromLong(ret);
728 }
729 #endif
730 
py_uwsgi_offload(PyObject * self,PyObject * args)731 PyObject *py_uwsgi_offload(PyObject * self, PyObject * args) {
732 /*
733 	size_t len = 0;
734 	char *filename = NULL;
735 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
736 
737 	if (!PyArg_ParseTuple(args, "s|i:offload_transfer", &filename, &len)) {
738                 return NULL;
739         }
740 
741 	if (!wsgi_req->socket->can_offload) {
742 		return PyErr_Format(PyExc_ValueError, "The current socket does not support offloading");
743 	}
744 
745 	if (!wsgi_req->headers_sent) {
746 		UWSGI_RELEASE_GIL
747         	if (uwsgi_response_write_headers_do(wsgi_req)) {
748 			UWSGI_GET_GIL
749 			return PyErr_Format(PyExc_ValueError, "unable to send headers before offload transfer");
750 		}
751 		UWSGI_GET_GIL
752 	}
753 
754 
755 	UWSGI_RELEASE_GIL
756         if (uwsgi_offload_request_sendfile_do(wsgi_req, filename, -1, len)) {
757 		UWSGI_GET_GIL
758 		return PyErr_Format(PyExc_ValueError, "unable to offload the request");
759 	}
760 	UWSGI_GET_GIL
761 
762 */
763 
764 	return PyString_FromString("");
765 }
766 
py_uwsgi_advanced_sendfile(PyObject * self,PyObject * args)767 PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
768 
769 	PyObject *what;
770 	char *filename;
771 	size_t chunk = 0;
772 	off_t pos = 0;
773 	size_t filesize = 0;
774 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
775 
776 	int fd = -1;
777 
778 	if (!PyArg_ParseTuple(args, "O|iii:sendfile", &what, &chunk, &pos, &filesize)) {
779 		return NULL;
780 	}
781 
782 
783 	if (PyString_Check(what)) {
784 
785 		filename = PyString_AsString(what);
786 
787 		fd = open(filename, O_RDONLY);
788 		if (fd < 0) {
789 			uwsgi_error_open(filename);
790 			goto clear;
791 		}
792 
793 	}
794 #ifdef PYTHREE
795 	else if (PyUnicode_Check(what)) {
796 		filename = PyBytes_AsString(PyUnicode_AsLatin1String(what));
797 
798 		fd = open(filename, O_RDONLY);
799 		if (fd < 0) {
800 			uwsgi_error_open(filename);
801 			goto clear;
802 		}
803 	}
804 #endif
805 	else {
806 		fd = PyObject_AsFileDescriptor(what);
807 		if (fd < 0)
808 			goto clear;
809 
810 		// check for mixing file_wrapper and sendfile
811 		if (fd == wsgi_req->sendfile_fd) {
812 			Py_INCREF(what);
813 		}
814 	}
815 
816 	UWSGI_RELEASE_GIL
817 	// fd is closed by the following function
818 	uwsgi_response_sendfile_do(wsgi_req, fd, pos, filesize);
819 	UWSGI_GET_GIL
820 	// revert to old values
821 	uwsgi_py_check_write_errors {
822         	uwsgi_py_write_exception(wsgi_req);
823 		return NULL;
824         }
825 
826 	Py_INCREF(Py_True);
827 	return Py_True;
828 
829       clear:
830 	Py_INCREF(Py_None);
831 	return Py_None;
832 
833 }
834 
835 
py_uwsgi_async_sleep(PyObject * self,PyObject * args)836 PyObject *py_uwsgi_async_sleep(PyObject * self, PyObject * args) {
837 
838 	float timeout;
839 	int sec_timeout;
840 
841 	if (!PyArg_ParseTuple(args, "f:async_sleep", &timeout)) {
842 		return NULL;
843 	}
844 
845 	sec_timeout = (int) timeout;
846 
847 	if (sec_timeout > 0) {
848 		async_add_timeout(uwsgi.wsgi_req, sec_timeout);
849 	}
850 
851 	return PyString_FromString("");
852 }
853 
py_uwsgi_warning(PyObject * self,PyObject * args)854 PyObject *py_uwsgi_warning(PyObject * self, PyObject * args) {
855 	char *message;
856 	int len;
857 
858 	if (!PyArg_ParseTuple(args, "s:set_warning_message", &message)) {
859 		return NULL;
860 	}
861 
862 	len = strlen(message);
863 	if (len > 80) {
864 		uwsgi_log("- warning message must be max 80 chars, it will be truncated -");
865 		memcpy(uwsgi.shared->warning_message, message, 80);
866 		uwsgi.shared->warning_message[80] = 0;
867 	}
868 	else {
869 		memcpy(uwsgi.shared->warning_message, message, len);
870 		uwsgi.shared->warning_message[len] = 0;
871 	}
872 
873 	Py_INCREF(Py_True);
874 	return Py_True;
875 }
876 
py_uwsgi_log(PyObject * self,PyObject * args)877 PyObject *py_uwsgi_log(PyObject * self, PyObject * args) {
878 	char *logline;
879 
880 	if (!PyArg_ParseTuple(args, "s:log", &logline)) {
881 		return NULL;
882 	}
883 
884 	uwsgi_log("%s\n", logline);
885 
886 	Py_INCREF(Py_True);
887 	return Py_True;
888 }
889 
py_uwsgi_set_user_harakiri(PyObject * self,PyObject * args)890 PyObject *py_uwsgi_set_user_harakiri(PyObject * self, PyObject * args) {
891 	int sec = 0;
892 	if (!PyArg_ParseTuple(args, "i:set_user_harakiri", &sec)) {
893                 return NULL;
894         }
895 
896 	set_user_harakiri(sec);
897 
898         Py_INCREF(Py_None);
899         return Py_None;
900 }
901 
py_uwsgi_i_am_the_spooler(PyObject * self,PyObject * args)902 PyObject *py_uwsgi_i_am_the_spooler(PyObject * self, PyObject * args) {
903 	if (uwsgi.i_am_a_spooler) {
904 		Py_INCREF(Py_True);
905 		return Py_True;
906 	}
907 	Py_INCREF(Py_None);
908 	return Py_None;
909 }
910 
py_uwsgi_is_locked(PyObject * self,PyObject * args)911 PyObject *py_uwsgi_is_locked(PyObject * self, PyObject * args) {
912 
913         int lock_num = 0;
914 
915         // the spooler cannot lock resources
916         if (uwsgi.i_am_a_spooler) {
917                 return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
918         }
919 
920         if (!PyArg_ParseTuple(args, "|i:is_locked", &lock_num)) {
921                 return NULL;
922         }
923 
924         if (lock_num < 0 || lock_num > uwsgi.locks) {
925                 return PyErr_Format(PyExc_ValueError, "Invalid lock number");
926         }
927 
928 	UWSGI_RELEASE_GIL
929 
930         if (uwsgi_lock_check(uwsgi.user_lock[lock_num]) == 0) {
931 		UWSGI_GET_GIL
932 		Py_INCREF(Py_False);
933 		return Py_False;
934 	}
935 
936 	UWSGI_GET_GIL
937 
938         Py_INCREF(Py_True);
939         return Py_True;
940 }
941 
942 
py_uwsgi_lock(PyObject * self,PyObject * args)943 PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
944 
945 	int lock_num = 0;
946 
947 	// the spooler cannot lock resources
948 	if (uwsgi.i_am_a_spooler) {
949 		return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
950 	}
951 
952 	if (!PyArg_ParseTuple(args, "|i:lock", &lock_num)) {
953                 return NULL;
954         }
955 
956 	if (lock_num < 0 || lock_num > uwsgi.locks) {
957 		return PyErr_Format(PyExc_ValueError, "Invalid lock number");
958 	}
959 
960 	UWSGI_RELEASE_GIL
961 	uwsgi_lock(uwsgi.user_lock[lock_num]);
962 	UWSGI_GET_GIL
963 
964 	Py_INCREF(Py_None);
965 	return Py_None;
966 }
967 
py_uwsgi_unlock(PyObject * self,PyObject * args)968 PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) {
969 
970 	int lock_num = 0;
971 
972 	if (uwsgi.i_am_a_spooler) {
973 		return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
974 	}
975 
976 	if (!PyArg_ParseTuple(args, "|i:unlock", &lock_num)) {
977                 return NULL;
978         }
979 
980         if (lock_num < 0 || lock_num > uwsgi.locks) {
981                 return PyErr_Format(PyExc_ValueError, "Invalid lock number");
982         }
983 
984 	uwsgi_unlock(uwsgi.user_lock[lock_num]);
985 
986 	Py_INCREF(Py_None);
987 	return Py_None;
988 }
989 
py_uwsgi_connection_fd(PyObject * self,PyObject * args)990 PyObject *py_uwsgi_connection_fd(PyObject * self, PyObject * args) {
991 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
992 	return PyInt_FromLong(wsgi_req->fd);
993 }
994 
py_uwsgi_websocket_handshake(PyObject * self,PyObject * args)995 PyObject *py_uwsgi_websocket_handshake(PyObject * self, PyObject * args) {
996         char *key = NULL;
997         Py_ssize_t key_len = 0;
998 
999         char *origin = NULL;
1000         Py_ssize_t origin_len = 0;
1001 
1002         char *proto = NULL;
1003         Py_ssize_t proto_len = 0;
1004 
1005         if (!PyArg_ParseTuple(args, "|s#s#s#:websocket_handshake", &key, &key_len, &origin, &origin_len, &proto, &proto_len)) {
1006                 return NULL;
1007         }
1008 
1009 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
1010 
1011 	UWSGI_RELEASE_GIL
1012 	int ret = uwsgi_websocket_handshake(wsgi_req, key, key_len, origin, origin_len, proto, proto_len);
1013 	UWSGI_GET_GIL
1014 
1015 	if (ret) {
1016 		return PyErr_Format(PyExc_IOError, "unable to complete websocket handshake");
1017 	}
1018 
1019 	Py_INCREF(Py_None);
1020         return Py_None;
1021 }
1022 
py_uwsgi_websocket_send(PyObject * self,PyObject * args)1023 PyObject *py_uwsgi_websocket_send(PyObject * self, PyObject * args) {
1024 	char *message = NULL;
1025         Py_ssize_t message_len = 0;
1026 
1027         if (!PyArg_ParseTuple(args, "s#:websocket_send", &message, &message_len)) {
1028                 return NULL;
1029         }
1030 
1031 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
1032 
1033 	UWSGI_RELEASE_GIL
1034 	int ret  = uwsgi_websocket_send(wsgi_req, message, message_len);
1035 	UWSGI_GET_GIL
1036 	if (ret < 0) {
1037 		return PyErr_Format(PyExc_IOError, "unable to send websocket message");
1038 	}
1039 	Py_INCREF(Py_None);
1040         return Py_None;
1041 }
1042 
py_uwsgi_websocket_send_binary(PyObject * self,PyObject * args)1043 PyObject *py_uwsgi_websocket_send_binary(PyObject * self, PyObject * args) {
1044         char *message = NULL;
1045         Py_ssize_t message_len = 0;
1046 
1047         if (!PyArg_ParseTuple(args, "s#:websocket_send_binary", &message, &message_len)) {
1048                 return NULL;
1049         }
1050 
1051         struct wsgi_request *wsgi_req = py_current_wsgi_req();
1052 
1053         UWSGI_RELEASE_GIL
1054         int ret  = uwsgi_websocket_send_binary(wsgi_req, message, message_len);
1055         UWSGI_GET_GIL
1056         if (ret < 0) {
1057                 return PyErr_Format(PyExc_IOError, "unable to send websocket binary message");
1058         }
1059         Py_INCREF(Py_None);
1060         return Py_None;
1061 }
1062 
1063 
py_uwsgi_chunked_read(PyObject * self,PyObject * args)1064 PyObject *py_uwsgi_chunked_read(PyObject * self, PyObject * args) {
1065 	int timeout = 0;
1066 	if (!PyArg_ParseTuple(args, "|i:chunked_read", &timeout)) {
1067                 return NULL;
1068         }
1069 	size_t len = 0;
1070         struct wsgi_request *wsgi_req = py_current_wsgi_req();
1071         UWSGI_RELEASE_GIL
1072         char *chunk = uwsgi_chunked_read(wsgi_req, &len, timeout, 0);
1073         UWSGI_GET_GIL
1074         if (!chunk) {
1075                 return PyErr_Format(PyExc_IOError, "unable to receive chunked part");
1076         }
1077 
1078         return PyString_FromStringAndSize(chunk, len);
1079 }
1080 
py_uwsgi_chunked_read_nb(PyObject * self,PyObject * args)1081 PyObject *py_uwsgi_chunked_read_nb(PyObject * self, PyObject * args) {
1082         size_t len = 0;
1083         struct wsgi_request *wsgi_req = py_current_wsgi_req();
1084         UWSGI_RELEASE_GIL
1085         char *chunk = uwsgi_chunked_read(wsgi_req, &len, 0, 1);
1086         UWSGI_GET_GIL
1087         if (!chunk) {
1088 		if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
1089 			Py_INCREF(Py_None);
1090 			return Py_None;
1091 		}
1092                 return PyErr_Format(PyExc_IOError, "unable to receive chunked part");
1093         }
1094 
1095         return PyString_FromStringAndSize(chunk, len);
1096 }
1097 
1098 
1099 
py_uwsgi_websocket_recv(PyObject * self,PyObject * args)1100 PyObject *py_uwsgi_websocket_recv(PyObject * self, PyObject * args) {
1101 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
1102 	UWSGI_RELEASE_GIL
1103 	struct uwsgi_buffer *ub = uwsgi_websocket_recv(wsgi_req);
1104 	UWSGI_GET_GIL
1105 	if (!ub) {
1106 		return PyErr_Format(PyExc_IOError, "unable to receive websocket message");
1107 	}
1108 
1109 	PyObject *ret = PyString_FromStringAndSize(ub->buf, ub->pos);
1110 	uwsgi_buffer_destroy(ub);
1111 	return ret;
1112 }
1113 
py_uwsgi_websocket_recv_nb(PyObject * self,PyObject * args)1114 PyObject *py_uwsgi_websocket_recv_nb(PyObject * self, PyObject * args) {
1115         struct wsgi_request *wsgi_req = py_current_wsgi_req();
1116         UWSGI_RELEASE_GIL
1117         struct uwsgi_buffer *ub = uwsgi_websocket_recv_nb(wsgi_req);
1118         UWSGI_GET_GIL
1119         if (!ub) {
1120                 return PyErr_Format(PyExc_IOError, "unable to receive websocket message");
1121         }
1122 
1123         PyObject *ret = PyString_FromStringAndSize(ub->buf, ub->pos);
1124         uwsgi_buffer_destroy(ub);
1125         return ret;
1126 }
1127 
1128 
py_uwsgi_embedded_data(PyObject * self,PyObject * args)1129 PyObject *py_uwsgi_embedded_data(PyObject * self, PyObject * args) {
1130 
1131 	char *name;
1132 	char *symbol;
1133 	void *sym_ptr_start = NULL;
1134 	void *sym_ptr_end = NULL;
1135 
1136 	if (!PyArg_ParseTuple(args, "s:embedded_data", &name)) {
1137 		return NULL;
1138 	}
1139 
1140 	symbol = uwsgi_concat3("_binary_", name, "_start");
1141 	sym_ptr_start = dlsym(RTLD_DEFAULT, symbol);
1142 	free(symbol);
1143 	if (!sym_ptr_start)
1144 		return PyErr_Format(PyExc_ValueError, "unable to find symbol %s", name);
1145 
1146 
1147 
1148 	symbol = uwsgi_concat3("_binary_", name, "_end");
1149 	sym_ptr_end = dlsym(RTLD_DEFAULT, symbol);
1150 	free(symbol);
1151 	if (!sym_ptr_end)
1152 		return PyErr_Format(PyExc_ValueError, "unable to find symbol %s", name);
1153 
1154 	return PyString_FromStringAndSize(sym_ptr_start, sym_ptr_end - sym_ptr_start);
1155 
1156 }
1157 
py_uwsgi_setprocname(PyObject * self,PyObject * args)1158 PyObject *py_uwsgi_setprocname(PyObject * self, PyObject * args) {
1159 	char *name = NULL;
1160 
1161 	if (!PyArg_ParseTuple(args, "s:setprocname", &name)) {
1162                 return NULL;
1163         }
1164 
1165 	uwsgi_set_processname(name);
1166 
1167 	Py_INCREF(Py_None);
1168 	return Py_None;
1169 }
1170 
py_uwsgi_ready(PyObject * self,PyObject * args)1171 PyObject *py_uwsgi_ready(PyObject * self, PyObject * args) {
1172 
1173 	if (ushared->ready) {
1174 		Py_INCREF(Py_True);
1175 		return Py_True;
1176 	}
1177 
1178 	Py_INCREF(Py_None);
1179 	return Py_None;
1180 }
1181 
py_uwsgi_in_farm(PyObject * self,PyObject * args)1182 PyObject *py_uwsgi_in_farm(PyObject * self, PyObject * args) {
1183 
1184 	char *farm_name = NULL;
1185 	int i;
1186 
1187 	if (!PyArg_ParseTuple(args, "|s:in_farm", &farm_name)) {
1188                 return NULL;
1189         }
1190 
1191 	if (uwsgi.muleid == 0) goto none;
1192 
1193 	for(i=0;i<uwsgi.farms_cnt;i++) {
1194 		if (!farm_name) {
1195 			if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
1196 				Py_INCREF(Py_True);
1197 				return Py_True;
1198 			}
1199 		}
1200 		else {
1201 			if (!strcmp(farm_name, uwsgi.farms[i].name)) {
1202 				if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
1203 					Py_INCREF(Py_True);
1204 					return Py_True;
1205 				}
1206 			}
1207 		}
1208 	}
1209 none:
1210 
1211 	Py_INCREF(Py_None);
1212 	return Py_None;
1213 
1214 }
1215 
py_uwsgi_farm_msg(PyObject * self,PyObject * args)1216 PyObject *py_uwsgi_farm_msg(PyObject * self, PyObject * args) {
1217 
1218         char *message = NULL;
1219         Py_ssize_t message_len = 0;
1220 	char *farm_name = NULL;
1221         ssize_t len;
1222 	int i;
1223 
1224         if (!PyArg_ParseTuple(args, "ss#:farm_msg", &farm_name, &message, &message_len)) {
1225                 return NULL;
1226         }
1227 
1228 	for(i=0;i<uwsgi.farms_cnt;i++) {
1229 
1230 		if (!strcmp(farm_name, uwsgi.farms[i].name)) {
1231 			UWSGI_RELEASE_GIL
1232                 	len = write(uwsgi.farms[i].queue_pipe[0], message, message_len);
1233 			UWSGI_GET_GIL
1234                 	if (len <= 0) {
1235                         	uwsgi_error("write()");
1236                 	}
1237 			break;
1238 		}
1239 
1240         }
1241 
1242         Py_INCREF(Py_None);
1243         return Py_None;
1244 
1245 }
1246 
1247 
py_uwsgi_mule_msg(PyObject * self,PyObject * args)1248 PyObject *py_uwsgi_mule_msg(PyObject * self, PyObject * args) {
1249 
1250 	char *message = NULL;
1251 	Py_ssize_t message_len = 0;
1252 	PyObject *mule_obj = NULL;
1253 	int fd = -1;
1254 	int mule_id = -1;
1255 	int resp = -1;
1256 
1257 	if (!PyArg_ParseTuple(args, "s#|O:mule_msg", &message, &message_len, &mule_obj)) {
1258                 return NULL;
1259         }
1260 
1261 	if (uwsgi.mules_cnt < 1)
1262 		return PyErr_Format(PyExc_ValueError, "no mule configured");
1263 
1264 	if (mule_obj == NULL) {
1265 		UWSGI_RELEASE_GIL
1266 		resp = mule_send_msg(uwsgi.shared->mule_queue_pipe[0], message, message_len);
1267 		UWSGI_GET_GIL
1268 	}
1269 	else {
1270 		if (PyString_Check(mule_obj)) {
1271 			struct uwsgi_farm *uf = get_farm_by_name(PyString_AsString(mule_obj));
1272 			if (uf == NULL) {
1273 				return PyErr_Format(PyExc_ValueError, "unknown farm");
1274 			}
1275 			fd = uf->queue_pipe[0];
1276 		}
1277 		else if (PyInt_Check(mule_obj)) {
1278 			mule_id = PyInt_AsLong(mule_obj);
1279 			if (mule_id < 0 && mule_id > uwsgi.mules_cnt) {
1280 				return PyErr_Format(PyExc_ValueError, "invalid mule number");
1281 			}
1282 			if (mule_id == 0) {
1283 				fd = uwsgi.shared->mule_queue_pipe[0];
1284 			}
1285 			else {
1286 				fd = uwsgi.mules[mule_id-1].queue_pipe[0];
1287 			}
1288 		}
1289 		else {
1290 			return PyErr_Format(PyExc_ValueError, "invalid mule");
1291 		}
1292 
1293 		if (fd > -1) {
1294 			UWSGI_RELEASE_GIL
1295 			resp = mule_send_msg(fd, message, message_len);
1296 			UWSGI_GET_GIL
1297 		}
1298 	}
1299 
1300 	if(!resp) {
1301 		Py_INCREF(Py_True);
1302 		return Py_True;
1303 	}
1304 
1305 	Py_INCREF(Py_False);
1306 	return Py_False;
1307 
1308 }
1309 
py_uwsgi_mule_get_msg(PyObject * self,PyObject * args,PyObject * kwargs)1310 PyObject *py_uwsgi_mule_get_msg(PyObject * self, PyObject * args, PyObject *kwargs) {
1311 
1312 	ssize_t len = 0;
1313 	// this buffer is configurable (default 64k)
1314 	char *message;
1315 	PyObject *py_manage_signals = NULL;
1316 	PyObject *py_manage_farms = NULL;
1317 	size_t buffer_size = 65536;
1318 	int timeout = -1;
1319 	int manage_signals = 1, manage_farms = 1;
1320 
1321 	static char *kwlist[] = {"signals", "farms", "buffer_size", "timeout", NULL};
1322 
1323 	if (uwsgi.muleid == 0) {
1324 		return PyErr_Format(PyExc_ValueError, "you can receive mule messages only in a mule !!!");
1325 	}
1326 
1327 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii:mule_get_msg", kwlist, &py_manage_signals, &py_manage_farms, &buffer_size, &timeout)) {
1328 		return NULL;
1329 	}
1330 
1331 	// signals and farms are managed by default
1332 	if (py_manage_signals == Py_None || py_manage_signals == Py_False) {
1333 		manage_signals = 0;
1334 	}
1335 
1336 	if (py_manage_farms == Py_None || py_manage_farms == Py_False) {
1337 		manage_farms = 0;
1338 	}
1339 
1340 	message = uwsgi_malloc(buffer_size);
1341 
1342 	UWSGI_RELEASE_GIL;
1343 	len = uwsgi_mule_get_msg(manage_signals, manage_farms, message, buffer_size, timeout) ;
1344 	UWSGI_GET_GIL;
1345 
1346 	if (len < 0) {
1347 		free(message);
1348 		Py_INCREF(Py_None);
1349         	return Py_None;
1350 	}
1351 
1352 	PyObject *msg = PyString_FromStringAndSize(message, len);
1353 	free(message);
1354 	return msg;
1355 }
1356 
py_uwsgi_farm_get_msg(PyObject * self,PyObject * args)1357 PyObject *py_uwsgi_farm_get_msg(PyObject * self, PyObject * args) {
1358 
1359         ssize_t len = 0;
1360         // this buffer will be configurable
1361         char message[65536];
1362 	int i, count = 0, pos = 0, ret;
1363 	struct pollfd *farmpoll;
1364 
1365         if (uwsgi.muleid == 0) {
1366                 return PyErr_Format(PyExc_ValueError, "you can receive farm messages only in a mule !!!");
1367         }
1368         UWSGI_RELEASE_GIL;
1369 	for(i=0;i<uwsgi.farms_cnt;i++) {
1370 		if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) count++;
1371 	}
1372 	farmpoll = uwsgi_malloc( sizeof(struct pollfd) * count);
1373 	for(i=0;i<uwsgi.farms_cnt;i++) {
1374 		if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) {
1375 			farmpoll[pos].fd = uwsgi.farms[i].queue_pipe[1];
1376 			farmpoll[pos].events = POLLIN;
1377 			pos++;
1378 		}
1379 	}
1380 
1381 	ret = poll(farmpoll, count, -1);
1382 	if (ret <= 0) {
1383         	UWSGI_GET_GIL;
1384 		uwsgi_error("poll()");
1385 		free(farmpoll);
1386 		Py_INCREF(Py_None);
1387 		return Py_None;
1388 	}
1389 
1390 	for(i=0;i<count;i++) {
1391 		if (farmpoll[i].revents & POLLIN) {
1392         		len = read(farmpoll[i].fd, message, 65536);
1393 			break;
1394 		}
1395 	}
1396         UWSGI_GET_GIL;
1397         if (len <= 0) {
1398                 uwsgi_error("read()");
1399 		free(farmpoll);
1400                 Py_INCREF(Py_None);
1401                 return Py_None;
1402         }
1403 
1404 	free(farmpoll);
1405         return PyString_FromStringAndSize(message, len);
1406 }
1407 
1408 
py_uwsgi_extract(PyObject * self,PyObject * args)1409 PyObject *py_uwsgi_extract(PyObject * self, PyObject * args) {
1410 
1411         char *name;
1412 	size_t len;
1413 	char *buf;
1414 
1415         if (!PyArg_ParseTuple(args, "s:extract", &name)) {
1416                 return NULL;
1417         }
1418 
1419 	buf = uwsgi_open_and_read(name, &len, 0, NULL);
1420 	if (buf && len > 0) {
1421         	return PyString_FromStringAndSize(buf, len);
1422 	}
1423 	if (buf)
1424 		free(buf);
1425 	Py_INCREF(Py_None);
1426 	return Py_None;
1427 
1428 }
1429 
1430 
py_uwsgi_sharedarea_inc64(PyObject * self,PyObject * args)1431 PyObject *py_uwsgi_sharedarea_inc64(PyObject * self, PyObject * args) {
1432 	int id;
1433 	uint64_t pos = 0;
1434 	int64_t value = 1;
1435 
1436 	if (!PyArg_ParseTuple(args, "iL|l:sharedarea_inc64", &id, &pos, &value)) {
1437 		return NULL;
1438 	}
1439 
1440 	UWSGI_RELEASE_GIL
1441 	int ret = uwsgi_sharedarea_inc64(id, pos, value);
1442 	UWSGI_GET_GIL
1443 
1444 	if (ret) {
1445 		return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_inc64()");
1446 	}
1447 
1448 	Py_INCREF(Py_None);
1449         return Py_None;
1450 
1451 }
1452 
py_uwsgi_sharedarea_inc32(PyObject * self,PyObject * args)1453 PyObject *py_uwsgi_sharedarea_inc32(PyObject * self, PyObject * args) {
1454         int id;
1455         uint64_t pos = 0;
1456         int32_t value = 1;
1457 
1458         if (!PyArg_ParseTuple(args, "iL|i:sharedarea_inc32", &id, &pos, &value)) {
1459                 return NULL;
1460         }
1461 
1462         UWSGI_RELEASE_GIL
1463         int ret = uwsgi_sharedarea_inc32(id, pos, value);
1464         UWSGI_GET_GIL
1465 
1466         if (ret) {
1467                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_inc32()");
1468         }
1469 
1470         Py_INCREF(Py_None);
1471         return Py_None;
1472 
1473 }
1474 
py_uwsgi_sharedarea_dec64(PyObject * self,PyObject * args)1475 PyObject *py_uwsgi_sharedarea_dec64(PyObject * self, PyObject * args) {
1476         int id;
1477         uint64_t pos = 0;
1478         int64_t value = 1;
1479 
1480         if (!PyArg_ParseTuple(args, "iL|l:sharedarea_dec64", &id, &pos, &value)) {
1481                 return NULL;
1482         }
1483 
1484         UWSGI_RELEASE_GIL
1485         int ret = uwsgi_sharedarea_dec64(id, pos, value);
1486         UWSGI_GET_GIL
1487 
1488         if (ret) {
1489                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_dec64()");
1490         }
1491 
1492         Py_INCREF(Py_None);
1493         return Py_None;
1494 
1495 }
1496 
py_uwsgi_sharedarea_dec32(PyObject * self,PyObject * args)1497 PyObject *py_uwsgi_sharedarea_dec32(PyObject * self, PyObject * args) {
1498         int id;
1499         uint64_t pos = 0;
1500         int32_t value = 1;
1501 
1502         if (!PyArg_ParseTuple(args, "iL|i:sharedarea_dec32", &id, &pos, &value)) {
1503                 return NULL;
1504         }
1505 
1506         UWSGI_RELEASE_GIL
1507         int ret = uwsgi_sharedarea_dec32(id, pos, value);
1508         UWSGI_GET_GIL
1509 
1510         if (ret) {
1511                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_dec32()");
1512         }
1513 
1514         Py_INCREF(Py_None);
1515         return Py_None;
1516 
1517 }
1518 
py_uwsgi_sharedarea_write32(PyObject * self,PyObject * args)1519 PyObject *py_uwsgi_sharedarea_write32(PyObject * self, PyObject * args) {
1520         int id;
1521         uint64_t pos = 0;
1522         int32_t value = 0;
1523 
1524         if (!PyArg_ParseTuple(args, "iLI:sharedarea_write32", &id, &pos, &value)) {
1525                 return NULL;
1526         }
1527 
1528         UWSGI_RELEASE_GIL
1529         int ret = uwsgi_sharedarea_write32(id, pos, &value);
1530         UWSGI_GET_GIL
1531 
1532         if (ret) {
1533                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write32()");
1534         }
1535 
1536         Py_INCREF(Py_None);
1537         return Py_None;
1538 }
1539 
py_uwsgi_sharedarea_write16(PyObject * self,PyObject * args)1540 PyObject *py_uwsgi_sharedarea_write16(PyObject * self, PyObject * args) {
1541         int id;
1542         uint64_t pos = 0;
1543         int16_t value = 0;
1544 
1545         if (!PyArg_ParseTuple(args, "iLI:sharedarea_write16", &id, &pos, &value)) {
1546                 return NULL;
1547         }
1548 
1549         UWSGI_RELEASE_GIL
1550         int ret = uwsgi_sharedarea_write16(id, pos, &value);
1551         UWSGI_GET_GIL
1552 
1553         if (ret) {
1554                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write16()");
1555         }
1556 
1557         Py_INCREF(Py_None);
1558         return Py_None;
1559 }
1560 
1561 
1562 
py_uwsgi_sharedarea_write64(PyObject * self,PyObject * args)1563 PyObject *py_uwsgi_sharedarea_write64(PyObject * self, PyObject * args) {
1564 	int id;
1565 	uint64_t pos = 0;
1566 	int64_t value = 0;
1567 
1568 	if (!PyArg_ParseTuple(args, "iLL:sharedarea_write64", &id, &pos, &value)) {
1569 		return NULL;
1570 	}
1571 
1572 	UWSGI_RELEASE_GIL
1573         int ret = uwsgi_sharedarea_write64(id, pos, &value);
1574         UWSGI_GET_GIL
1575 
1576         if (ret) {
1577                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write64()");
1578         }
1579 
1580 	Py_INCREF(Py_None);
1581         return Py_None;
1582 }
1583 
py_uwsgi_sharedarea_write(PyObject * self,PyObject * args)1584 PyObject *py_uwsgi_sharedarea_write(PyObject * self, PyObject * args) {
1585 	int id;
1586 	uint64_t pos = 0;
1587 	char *value;
1588 	Py_ssize_t value_len = 0;
1589 
1590 	if (!PyArg_ParseTuple(args, "iLs#:sharedarea_write", &id, &pos, &value, &value_len)) {
1591 		return NULL;
1592 	}
1593 
1594 	UWSGI_RELEASE_GIL
1595         int ret = uwsgi_sharedarea_write(id, pos, value, value_len);
1596         UWSGI_GET_GIL
1597 
1598         if (ret) {
1599                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write()");
1600         }
1601 
1602         Py_INCREF(Py_None);
1603         return Py_None;
1604 }
1605 
py_uwsgi_sharedarea_update(PyObject * self,PyObject * args)1606 PyObject *py_uwsgi_sharedarea_update(PyObject * self, PyObject * args) {
1607         int id;
1608 
1609         if (!PyArg_ParseTuple(args, "i:sharedarea_update", &id)) {
1610                 return NULL;
1611         }
1612 
1613         if (uwsgi_sharedarea_update(id)) {
1614                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_update()");
1615         }
1616 
1617         Py_INCREF(Py_None);
1618         return Py_None;
1619 
1620 }
1621 
py_uwsgi_sharedarea_rlock(PyObject * self,PyObject * args)1622 PyObject *py_uwsgi_sharedarea_rlock(PyObject * self, PyObject * args) {
1623         int id;
1624 
1625         if (!PyArg_ParseTuple(args, "i:sharedarea_rlock", &id)) {
1626                 return NULL;
1627         }
1628 
1629         UWSGI_RELEASE_GIL
1630         int ret = uwsgi_sharedarea_rlock(id);
1631         UWSGI_GET_GIL
1632 
1633         if (ret) {
1634                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_rlock()");
1635         }
1636 
1637         Py_INCREF(Py_None);
1638         return Py_None;
1639 
1640 }
1641 
py_uwsgi_sharedarea_wlock(PyObject * self,PyObject * args)1642 PyObject *py_uwsgi_sharedarea_wlock(PyObject * self, PyObject * args) {
1643         int id;
1644 
1645         if (!PyArg_ParseTuple(args, "i:sharedarea_wlock", &id)) {
1646                 return NULL;
1647         }
1648 
1649         UWSGI_RELEASE_GIL
1650         int ret = uwsgi_sharedarea_wlock(id);
1651         UWSGI_GET_GIL
1652 
1653         if (ret) {
1654                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_wlock()");
1655         }
1656 
1657         Py_INCREF(Py_None);
1658         return Py_None;
1659 
1660 }
1661 
py_uwsgi_sharedarea_unlock(PyObject * self,PyObject * args)1662 PyObject *py_uwsgi_sharedarea_unlock(PyObject * self, PyObject * args) {
1663         int id;
1664 
1665         if (!PyArg_ParseTuple(args, "i:sharedarea_unlock", &id)) {
1666                 return NULL;
1667         }
1668 
1669         UWSGI_RELEASE_GIL
1670         int ret = uwsgi_sharedarea_unlock(id);
1671         UWSGI_GET_GIL
1672 
1673         if (ret) {
1674                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_unlock()");
1675         }
1676 
1677         Py_INCREF(Py_None);
1678         return Py_None;
1679 
1680 }
1681 
1682 
1683 
1684 
py_uwsgi_sharedarea_write8(PyObject * self,PyObject * args)1685 PyObject *py_uwsgi_sharedarea_write8(PyObject * self, PyObject * args) {
1686 	int id;
1687 	uint64_t pos = 0;
1688 	int8_t value;
1689 
1690 	if (!PyArg_ParseTuple(args, "iLb:sharedarea_write8", &id, &pos, &value)) {
1691 		return NULL;
1692 	}
1693 
1694 	UWSGI_RELEASE_GIL
1695         int ret = uwsgi_sharedarea_write8(id, pos, &value);
1696         UWSGI_GET_GIL
1697 
1698         if (ret) {
1699                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_write8()");
1700         }
1701 
1702         Py_INCREF(Py_None);
1703         return Py_None;
1704 
1705 }
1706 
py_uwsgi_sharedarea_read64(PyObject * self,PyObject * args)1707 PyObject *py_uwsgi_sharedarea_read64(PyObject * self, PyObject * args) {
1708 	int id;
1709 	uint64_t pos = 0;
1710 	int64_t value;
1711 
1712 	if (!PyArg_ParseTuple(args, "iL:sharedarea_read64", &id, &pos)) {
1713 		return NULL;
1714 	}
1715 
1716 	UWSGI_RELEASE_GIL
1717         int ret = uwsgi_sharedarea_read64(id, pos, &value);
1718         UWSGI_GET_GIL
1719 
1720         if (ret) {
1721                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read64()");
1722         }
1723 
1724 	return PyLong_FromLongLong(value);
1725 
1726 }
1727 
py_uwsgi_sharedarea_read32(PyObject * self,PyObject * args)1728 PyObject *py_uwsgi_sharedarea_read32(PyObject * self, PyObject * args) {
1729         int id;
1730         uint64_t pos = 0;
1731         int32_t value;
1732 
1733         if (!PyArg_ParseTuple(args, "iL:sharedarea_read32", &id, &pos)) {
1734                 return NULL;
1735         }
1736 
1737         UWSGI_RELEASE_GIL
1738         int ret = uwsgi_sharedarea_read32(id, pos, &value);
1739         UWSGI_GET_GIL
1740 
1741         if (ret) {
1742                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read32()");
1743         }
1744 
1745         return PyInt_FromLong(value);
1746 
1747 }
1748 
py_uwsgi_sharedarea_read16(PyObject * self,PyObject * args)1749 PyObject *py_uwsgi_sharedarea_read16(PyObject * self, PyObject * args) {
1750         int id;
1751         uint64_t pos = 0;
1752         int16_t value;
1753 
1754         if (!PyArg_ParseTuple(args, "iL:sharedarea_read16", &id, &pos)) {
1755                 return NULL;
1756         }
1757 
1758         UWSGI_RELEASE_GIL
1759         int ret = uwsgi_sharedarea_read16(id, pos, &value);
1760         UWSGI_GET_GIL
1761 
1762         if (ret) {
1763                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read16()");
1764         }
1765 
1766         return PyInt_FromLong(value);
1767 
1768 }
1769 
1770 
py_uwsgi_sharedarea_read8(PyObject * self,PyObject * args)1771 PyObject *py_uwsgi_sharedarea_read8(PyObject * self, PyObject * args) {
1772 	int id;
1773 	uint64_t pos = 0;
1774 	int8_t byte;
1775 
1776 	if (!PyArg_ParseTuple(args, "iL:sharedarea_read8", &id, &pos)) {
1777 		return NULL;
1778 	}
1779 
1780 	UWSGI_RELEASE_GIL
1781         int ret = uwsgi_sharedarea_read8(id, pos, &byte);
1782         UWSGI_GET_GIL
1783 
1784         if (ret) {
1785                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read8()");
1786         }
1787 
1788 	return PyInt_FromLong(byte);
1789 }
1790 
py_uwsgi_sharedarea_read(PyObject * self,PyObject * args)1791 PyObject *py_uwsgi_sharedarea_read(PyObject * self, PyObject * args) {
1792 	int id;
1793 	uint64_t pos = 0;
1794 	uint64_t len = 0;
1795 
1796 	if (!PyArg_ParseTuple(args, "iL|L:sharedarea_read", &id, &pos, &len)) {
1797 		return NULL;
1798 	}
1799 
1800 	if (!len) {
1801 		struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, pos);
1802                 if (!sa) {
1803 			return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read()");
1804                 }
1805                 len = (sa->max_pos+1)-pos;
1806 	}
1807 
1808 	PyObject *ret = PyString_FromStringAndSize(NULL, len);
1809 #ifdef PYTHREE
1810 	char *storage = PyBytes_AsString(ret);
1811 #else
1812 	char *storage = PyString_AS_STRING(ret);
1813 #endif
1814 
1815 	UWSGI_RELEASE_GIL
1816         int64_t rlen = uwsgi_sharedarea_read(id, pos, storage, len);
1817         UWSGI_GET_GIL
1818 
1819         if (rlen < 0) {
1820 		Py_DECREF(ret);
1821                 return PyErr_Format(PyExc_ValueError, "error calling uwsgi_sharedarea_read()");
1822         }
1823 
1824 	// HACK: we are safe as rlen can only be lower or equal to len
1825 	Py_SET_SIZE((PyVarObject *) ret, rlen);
1826 
1827 	return ret;
1828 }
1829 
1830 #if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
1831 #ifndef HAS_NOT_PyMemoryView_FromBuffer
py_uwsgi_sharedarea_memoryview(PyObject * self,PyObject * args)1832 PyObject *py_uwsgi_sharedarea_memoryview(PyObject * self, PyObject * args) {
1833         int id;
1834 	if (!PyArg_ParseTuple(args, "i:sharedarea_memoryview", &id)) {
1835                 return NULL;
1836         }
1837 	struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
1838 	if (!sa) {
1839         	return PyErr_Format(PyExc_ValueError, "cannot get a memoryview object from sharedarea %d", id);
1840         }
1841 	Py_buffer info;
1842 	if (PyBuffer_FillInfo(&info, NULL, sa->area, sa->max_pos+1, 0, PyBUF_CONTIG) < 0)
1843         	return PyErr_Format(PyExc_ValueError, "cannot get a memoryview object from sharedarea %d", id);
1844 	return PyMemoryView_FromBuffer(&info);
1845 }
1846 #endif
1847 
py_uwsgi_sharedarea_object(PyObject * self,PyObject * args)1848 PyObject *py_uwsgi_sharedarea_object(PyObject * self, PyObject * args) {
1849 	int id;
1850         if (!PyArg_ParseTuple(args, "i:sharedarea_object", &id)) {
1851                 return NULL;
1852         }
1853         struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
1854         if (!sa) {
1855                 return PyErr_Format(PyExc_ValueError, "cannot get an object from sharedarea %d", id);
1856         }
1857 	return (PyObject *) sa->obj;
1858 }
1859 #endif
1860 
py_uwsgi_spooler_freq(PyObject * self,PyObject * args)1861 PyObject *py_uwsgi_spooler_freq(PyObject * self, PyObject * args) {
1862 
1863 	if (!PyArg_ParseTuple(args, "i", &uwsgi.shared->spooler_frequency)) {
1864 		return NULL;
1865 	}
1866 
1867 	Py_INCREF(Py_True);
1868 	return Py_True;
1869 
1870 }
1871 
py_uwsgi_spooler_jobs(PyObject * self,PyObject * args)1872 PyObject *py_uwsgi_spooler_jobs(PyObject * self, PyObject * args) {
1873 
1874 	DIR *sdir;
1875 	struct dirent *dp;
1876 	char *abs_path;
1877 	struct stat sf_lstat;
1878 
1879 	PyObject *jobslist = PyList_New(0);
1880 
1881 	struct uwsgi_spooler *uspool = uwsgi.spoolers;
1882 
1883 	sdir = opendir(uspool->dir);
1884 
1885 	if (sdir) {
1886 		while ((dp = readdir(sdir)) != NULL) {
1887 			if (!strncmp("uwsgi_spoolfile_on_", dp->d_name, 19)) {
1888 				abs_path = malloc(strlen(uspool->dir) + 1 + strlen(dp->d_name) + 1);
1889 				if (!abs_path) {
1890 					uwsgi_error("malloc()");
1891 					closedir(sdir);
1892 					goto clear;
1893 				}
1894 
1895 				memset(abs_path, 0, strlen(uspool->dir) + 1 + strlen(dp->d_name) + 1);
1896 
1897 				memcpy(abs_path, uspool->dir, strlen(uspool->dir));
1898 				memcpy(abs_path + strlen(uspool->dir), "/", 1);
1899 				memcpy(abs_path + strlen(uspool->dir) + 1, dp->d_name, strlen(dp->d_name));
1900 
1901 
1902 				if (lstat(abs_path, &sf_lstat)) {
1903 					free(abs_path);
1904 					continue;
1905 				}
1906 				if (!S_ISREG(sf_lstat.st_mode)) {
1907 					free(abs_path);
1908 					continue;
1909 				}
1910 				if (!access(abs_path, R_OK | W_OK)) {
1911 					if (PyList_Append(jobslist, PyString_FromString(abs_path))) {
1912 						PyErr_Print();
1913 					}
1914 				}
1915 				free(abs_path);
1916 			}
1917 		}
1918 		closedir(sdir);
1919 	}
1920 
1921       clear:
1922 	return jobslist;
1923 
1924 }
1925 
1926 
py_uwsgi_send_spool(PyObject * self,PyObject * args,PyObject * kw)1927 PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) {
1928 	PyObject *spool_dict, *spool_vars;
1929 	PyObject *zero, *key, *val;
1930 	uint16_t keysize, valsize;
1931 	char *body = NULL;
1932 	size_t body_len= 0;
1933 
1934 	spool_dict = PyTuple_GetItem(args, 0);
1935 
1936 	if (spool_dict) {
1937 		if (!PyDict_Check(spool_dict)) {
1938 			return PyErr_Format(PyExc_ValueError, "The argument of spooler callable must be a dictionary");
1939 		}
1940 	}
1941 	else {
1942 		// clear the error
1943 		PyErr_Clear();
1944 		spool_dict = kw;
1945 	}
1946 
1947 	if (!spool_dict) {
1948 		return PyErr_Format(PyExc_ValueError, "The argument of spooler callable must be a dictionary");
1949 	}
1950 
1951 	PyObject *pybody = uwsgi_py_dict_get(spool_dict, "body");
1952 	if (pybody) {
1953 		if (PyString_Check(pybody)) {
1954 			body = PyString_AsString(pybody);
1955 			body_len = PyString_Size(pybody);
1956 			Py_INCREF(pybody);
1957 			uwsgi_py_dict_del(spool_dict, "body");
1958 		}
1959 	}
1960 
1961 	spool_vars = PyDict_Items(spool_dict);
1962 	if (!spool_vars) {
1963 		Py_INCREF(Py_None);
1964 		return Py_None;
1965 	}
1966 
1967 	int i;
1968 	struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
1969 
1970 	for (i = 0; i < PyList_Size(spool_vars); i++) {
1971 		zero = PyList_GetItem(spool_vars, i);
1972 		if (zero) {
1973 			if (PyTuple_Check(zero)) {
1974 				key = PyTuple_GetItem(zero, 0);
1975 				val = PyTuple_GetItem(zero, 1);
1976 
1977 				if (PyString_Check(key)) {
1978 
1979 					keysize = PyString_Size(key);
1980 
1981 					if (PyString_Check(val)) {
1982 						valsize = PyString_Size(val);
1983 						if (uwsgi_buffer_append_keyval(ub, PyString_AsString(key), keysize, PyString_AsString(val), valsize)) {
1984 							uwsgi_buffer_destroy(ub);
1985 							goto error;
1986 						}
1987 					}
1988 					else {
1989 #ifdef PYTHREE
1990 						PyObject *str = PyObject_Bytes(val);
1991 #else
1992 						PyObject *str = PyObject_Str(val);
1993 #endif
1994 						if (!str) {
1995 							uwsgi_buffer_destroy(ub);
1996 							goto error;
1997 						}
1998 						if (uwsgi_buffer_append_keyval(ub, PyString_AsString(key), keysize, PyString_AsString(str), PyString_Size(str))) {
1999 							Py_DECREF(str);
2000 							uwsgi_buffer_destroy(ub);
2001 							goto error;
2002 						}
2003 						Py_DECREF(str);
2004 					}
2005 				}
2006 				else {
2007 					uwsgi_buffer_destroy(ub);
2008                                         goto error;
2009 				}
2010 			}
2011 			else {
2012 				uwsgi_buffer_destroy(ub);
2013                                 goto error;
2014 			}
2015 		}
2016 		else {
2017 			uwsgi_buffer_destroy(ub);
2018                         goto error;
2019 		}
2020 	}
2021 
2022 
2023 	UWSGI_RELEASE_GIL
2024 
2025 	// current_wsgi_req can be NULL, in such a case a non-thread-safe counter will be used
2026 	char *filename = uwsgi_spool_request(NULL, ub->buf, ub->pos, body, body_len);
2027 	uwsgi_buffer_destroy(ub);
2028 
2029 	UWSGI_GET_GIL
2030 
2031 
2032 	if (pybody) {
2033 		if (PyString_Check(pybody)) {
2034 			Py_DECREF(pybody);
2035 		}
2036 	}
2037 
2038 	Py_DECREF(spool_vars);
2039 
2040 	if (filename) {
2041 		PyObject *ret = PyString_FromString(filename);
2042 		free(filename);
2043 		return ret;
2044 	}
2045 	return PyErr_Format(PyExc_ValueError, "unable to spool job");
2046 error:
2047 #ifdef PYTHREE
2048 	return PyErr_Format(PyExc_ValueError, "spooler callable dictionary must contains only bytes");
2049 #else
2050 	return PyErr_Format(PyExc_ValueError, "spooler callable dictionary must contains only strings");
2051 #endif
2052 }
2053 
py_uwsgi_spooler_pid(PyObject * self,PyObject * args)2054 PyObject *py_uwsgi_spooler_pid(PyObject * self, PyObject * args) {
2055 	struct uwsgi_spooler *uspool = uwsgi.spoolers;
2056 	if (!uwsgi.spoolers) return PyInt_FromLong(0);
2057 	return PyInt_FromLong(uspool->pid);
2058 }
2059 
py_uwsgi_spooler_pids(PyObject * self,PyObject * args)2060 PyObject *py_uwsgi_spooler_pids(PyObject * self, PyObject * args) {
2061     PyObject *ret = PyList_New(0);
2062     struct uwsgi_spooler *uspool = uwsgi.spoolers;
2063     while (uspool) {
2064         PyList_Append(ret, PyInt_FromLong(uspool->pid));
2065         uspool = uspool->next;
2066     }
2067     return ret;
2068 }
2069 
py_uwsgi_spooler_get_task(PyObject * self,PyObject * args)2070 PyObject *py_uwsgi_spooler_get_task(PyObject * self, PyObject * args) {
2071 
2072 	char spool_buf[0xffff];
2073 	struct uwsgi_header uh;
2074 	char *body = NULL;
2075 	size_t body_len = 0;
2076 
2077 	int spool_fd;
2078 
2079 	char *task_path = NULL;
2080 
2081 	struct stat task_stat;
2082 
2083 	if (!PyArg_ParseTuple(args, "s:spooler_get_task", &task_path)) {
2084 		return NULL;
2085 	}
2086 
2087 	if (lstat(task_path, &task_stat)) {
2088 		Py_INCREF(Py_None);
2089 		return Py_None;
2090 	}
2091 
2092 	if (access(task_path, R_OK | W_OK)) {
2093 		Py_INCREF(Py_None);
2094 		return Py_None;
2095 	}
2096 
2097 	spool_fd = open(task_path, O_RDWR);
2098 
2099 	if (spool_fd < 0) {
2100 		Py_INCREF(Py_None);
2101 		return Py_None;
2102 	}
2103 
2104 	if (uwsgi_spooler_read_header(task_path, spool_fd, &uh) ||
2105 		uwsgi_spooler_read_content(spool_fd, spool_buf, &body, &body_len, &uh, &task_stat)) {
2106 		Py_INCREF(Py_None);
2107 		return Py_None;
2108 	}
2109 
2110 	uwsgi_protected_close(spool_fd);
2111 
2112 	PyObject *spool_dict = uwsgi_python_dict_from_spooler_content(task_path, spool_buf, uh.pktsize, body, body_len);
2113 
2114 	if (!spool_dict) {
2115 		Py_INCREF(Py_None);
2116 		return Py_None;
2117 	}
2118 
2119 	return spool_dict;
2120 }
2121 
2122 
py_uwsgi_connect(PyObject * self,PyObject * args)2123 PyObject *py_uwsgi_connect(PyObject * self, PyObject * args) {
2124 
2125 	char *socket_name = NULL;
2126 	int timeout = 0;
2127 	if (!PyArg_ParseTuple(args, "s|i:connect", &socket_name, &timeout)) {
2128 		return NULL;
2129 	}
2130 
2131 	return PyInt_FromLong(uwsgi_connect(socket_name, timeout, 0));
2132 }
2133 
py_uwsgi_async_connect(PyObject * self,PyObject * args)2134 PyObject *py_uwsgi_async_connect(PyObject * self, PyObject * args) {
2135 
2136 	char *socket_name = NULL;
2137 	if (!PyArg_ParseTuple(args, "s:async_connect", &socket_name)) {
2138 		return NULL;
2139 	}
2140 
2141 	return PyInt_FromLong(uwsgi_connect(socket_name, 0, 1));
2142 }
2143 
2144 /* uWSGI masterpid */
py_uwsgi_masterpid(PyObject * self,PyObject * args)2145 PyObject *py_uwsgi_masterpid(PyObject * self, PyObject * args) {
2146 	if (uwsgi.master_process) {
2147 		return PyInt_FromLong(uwsgi.workers[0].pid);
2148 	}
2149 	return PyInt_FromLong(0);
2150 }
2151 
2152 	/* uWSGI total_requests */
py_uwsgi_total_requests(PyObject * self,PyObject * args)2153 PyObject *py_uwsgi_total_requests(PyObject * self, PyObject * args) {
2154 	return PyLong_FromUnsignedLongLong(uwsgi.workers[0].requests);
2155 }
2156 
2157 	/* uWSGI workers */
py_uwsgi_workers(PyObject * self,PyObject * args)2158 PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) {
2159 
2160 	PyObject *worker_dict, *apps_dict, *apps_tuple, *zero;
2161 	int i, j;
2162 	struct uwsgi_app *ua;
2163 
2164 	for (i = 0; i < uwsgi.numproc; i++) {
2165 		worker_dict = PyTuple_GetItem(up.workers_tuple, i);
2166 		if (!worker_dict) {
2167 			goto clear;
2168 		}
2169 
2170 		PyDict_Clear(worker_dict);
2171 
2172 		zero = PyInt_FromLong(uwsgi.workers[i + 1].id);
2173 		if (PyDict_SetItemString(worker_dict, "id", zero)) {
2174 			goto clear;
2175 		}
2176 		Py_DECREF(zero);
2177 
2178 
2179 		zero = PyInt_FromLong(uwsgi.workers[i + 1].pid);
2180 		if (PyDict_SetItemString(worker_dict, "pid", zero)) {
2181 			goto clear;
2182 		}
2183 		Py_DECREF(zero);
2184 
2185 		zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].requests);
2186 		if (PyDict_SetItemString(worker_dict, "requests", zero)) {
2187 			goto clear;
2188 		}
2189 		Py_DECREF(zero);
2190 
2191 		zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].delta_requests);
2192 		if (PyDict_SetItemString(worker_dict, "delta_requests", zero)) {
2193 			goto clear;
2194 		}
2195 		Py_DECREF(zero);
2196 
2197 		zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].signals);
2198 		if (PyDict_SetItemString(worker_dict, "signals", zero)) {
2199 			goto clear;
2200 		}
2201 		Py_DECREF(zero);
2202 
2203 		zero = PyLong_FromUnsignedLongLong(uwsgi_worker_exceptions(i+1));
2204 		if (PyDict_SetItemString(worker_dict, "exceptions", zero)) {
2205 			goto clear;
2206 		}
2207 		Py_DECREF(zero);
2208 
2209 		if (uwsgi.workers[i + 1].cheaped) {
2210 			zero = PyString_FromString("cheap");
2211 		}
2212 		else if (uwsgi.workers[i + 1].suspended && !uwsgi_worker_is_busy(i+1)) {
2213 			zero = PyString_FromString("pause");
2214 		}
2215 		else {
2216 			if (uwsgi.workers[i + 1].sig) {
2217 				zero = PyString_FromFormat("sig%d",uwsgi.workers[i + 1].signum);
2218 			}
2219 			else if (uwsgi_worker_is_busy(i+1)) {
2220 				zero = PyString_FromString("busy");
2221 			}
2222 			else {
2223 				zero = PyString_FromString("idle");
2224 			}
2225 		}
2226 		if (PyDict_SetItemString(worker_dict, "status", zero)) {
2227                         goto clear;
2228                 }
2229 
2230 		Py_DECREF(zero);
2231 
2232 		zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].rss_size);
2233 		if (PyDict_SetItemString(worker_dict, "rss", zero)) {
2234 			goto clear;
2235 		}
2236 		Py_DECREF(zero);
2237 
2238 		zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].vsz_size);
2239 		if (PyDict_SetItemString(worker_dict, "vsz", zero)) {
2240 			goto clear;
2241 		}
2242 		Py_DECREF(zero);
2243 
2244 		zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].running_time);
2245 		if (PyDict_SetItemString(worker_dict, "running_time", zero)) {
2246 			goto clear;
2247 		}
2248 		Py_DECREF(zero);
2249 
2250 		zero = PyLong_FromLong(uwsgi.workers[i + 1].last_spawn);
2251 		if (PyDict_SetItemString(worker_dict, "last_spawn", zero)) {
2252 			goto clear;
2253 		}
2254 		Py_DECREF(zero);
2255 
2256 		zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].respawn_count-1);
2257 		if (PyDict_SetItemString(worker_dict, "respawn_count", zero)) {
2258 			goto clear;
2259 		}
2260 		Py_DECREF(zero);
2261 
2262 		zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].tx);
2263 		if (PyDict_SetItemString(worker_dict, "tx", zero)) {
2264 			goto clear;
2265 		}
2266 		Py_DECREF(zero);
2267 
2268 		zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].avg_response_time);
2269 		if (PyDict_SetItemString(worker_dict, "avg_rt", zero)) {
2270 			goto clear;
2271 		}
2272 		Py_DECREF(zero);
2273 
2274 		apps_tuple = PyTuple_New(uwsgi.workers[i+1].apps_cnt);
2275 
2276 		for(j=0;j<uwsgi.workers[i+1].apps_cnt;j++) {
2277 			apps_dict = PyDict_New();
2278 			ua = &uwsgi.workers[i+1].apps[j];
2279 
2280 			zero = PyInt_FromLong(j);
2281 			PyDict_SetItemString(apps_dict, "id", zero);
2282 			Py_DECREF(zero);
2283 
2284 			zero = PyInt_FromLong(ua->modifier1);
2285 			PyDict_SetItemString(apps_dict, "modifier1", zero);
2286 			Py_DECREF(zero);
2287 
2288 			zero = PyString_FromStringAndSize(ua->mountpoint, ua->mountpoint_len);
2289 			PyDict_SetItemString(apps_dict, "mountpoint", zero);
2290 			Py_DECREF(zero);
2291 
2292 			zero = PyInt_FromLong((long) ua->startup_time);
2293 			PyDict_SetItemString(apps_dict, "startup_time", zero);
2294 			Py_DECREF(zero);
2295 
2296 			zero = PyInt_FromLong((long)ua->interpreter);
2297 			PyDict_SetItemString(apps_dict, "interpreter", zero);
2298 			Py_DECREF(zero);
2299 
2300 			zero = PyInt_FromLong((long)ua->callable);
2301 			PyDict_SetItemString(apps_dict, "callable", zero);
2302 			Py_DECREF(zero);
2303 
2304 			zero = PyLong_FromUnsignedLongLong(ua->requests);
2305 			PyDict_SetItemString(apps_dict, "requests", zero);
2306 			Py_DECREF(zero);
2307 
2308 			zero = PyLong_FromUnsignedLongLong(ua->exceptions);
2309 			PyDict_SetItemString(apps_dict, "exceptions", zero);
2310 			Py_DECREF(zero);
2311 
2312 			if (*ua->chdir) {
2313 				zero = PyString_FromString(ua->chdir);
2314 			}
2315 			else {
2316 				zero = PyString_FromString("");
2317 			}
2318 			PyDict_SetItemString(apps_dict, "chdir", zero);
2319 			Py_DECREF(zero);
2320 
2321 			PyTuple_SetItem(apps_tuple, j, apps_dict);
2322 		}
2323 
2324 
2325 		PyDict_SetItemString(worker_dict, "apps", apps_tuple);
2326 		Py_DECREF(apps_tuple);
2327 
2328 	}
2329 
2330 
2331 	Py_INCREF(up.workers_tuple);
2332 	return up.workers_tuple;
2333 
2334       clear:
2335 	PyErr_Print();
2336 	PyErr_Clear();
2337 	Py_INCREF(Py_None);
2338 	return Py_None;
2339 
2340 }
2341 
2342 
2343 	/* uWSGI reload */
py_uwsgi_reload(PyObject * self,PyObject * args)2344 PyObject *py_uwsgi_reload(PyObject * self, PyObject * args) {
2345 
2346 	if (kill(uwsgi.workers[0].pid, SIGHUP)) {
2347 		uwsgi_error("kill()");
2348 		Py_INCREF(Py_None);
2349 		return Py_None;
2350 	}
2351 
2352 	Py_INCREF(Py_True);
2353 	return Py_True;
2354 }
2355 
2356 /* uWSGI stop */
py_uwsgi_stop(PyObject * self,PyObject * args)2357 PyObject *py_uwsgi_stop(PyObject * self, PyObject * args) {
2358 
2359         if (kill(uwsgi.workers[0].pid, SIGQUIT)) {
2360                 uwsgi_error("kill()");
2361                 Py_INCREF(Py_None);
2362                 return Py_None;
2363         }
2364 
2365         Py_INCREF(Py_True);
2366         return Py_True;
2367 }
2368 
py_uwsgi_request_id(PyObject * self,PyObject * args)2369 PyObject *py_uwsgi_request_id(PyObject * self, PyObject * args) {
2370 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
2371 	return PyLong_FromUnsignedLongLong(uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].requests);
2372 }
2373 
py_uwsgi_worker_id(PyObject * self,PyObject * args)2374 PyObject *py_uwsgi_worker_id(PyObject * self, PyObject * args) {
2375 	return PyInt_FromLong(uwsgi.mywid);
2376 }
2377 
py_uwsgi_mule_id(PyObject * self,PyObject * args)2378 PyObject *py_uwsgi_mule_id(PyObject * self, PyObject * args) {
2379 	return PyInt_FromLong(uwsgi.muleid);
2380 }
2381 
py_uwsgi_logsize(PyObject * self,PyObject * args)2382 PyObject *py_uwsgi_logsize(PyObject * self, PyObject * args) {
2383 	return PyLong_FromUnsignedLongLong(uwsgi.shared->logsize);
2384 }
2385 
py_uwsgi_mem(PyObject * self,PyObject * args)2386 PyObject *py_uwsgi_mem(PyObject * self, PyObject * args) {
2387 
2388 	uint64_t rss=0, vsz = 0;
2389 	PyObject *ml = PyTuple_New(2);
2390 
2391 	get_memusage(&rss, &vsz);
2392 
2393 	PyTuple_SetItem(ml, 0, PyLong_FromUnsignedLongLong(rss));
2394 	PyTuple_SetItem(ml, 1, PyLong_FromUnsignedLongLong(vsz));
2395 
2396 	return ml;
2397 
2398 }
2399 
py_uwsgi_cl(PyObject * self,PyObject * args)2400 PyObject *py_uwsgi_cl(PyObject * self, PyObject * args) {
2401 
2402 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
2403 
2404 	return PyLong_FromUnsignedLongLong(wsgi_req->post_cl);
2405 
2406 }
2407 
py_uwsgi_disconnect(PyObject * self,PyObject * args)2408 PyObject *py_uwsgi_disconnect(PyObject * self, PyObject * args) {
2409 
2410 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
2411 
2412 	uwsgi_disconnect(wsgi_req);
2413 
2414 	Py_INCREF(Py_None);
2415 	return Py_None;
2416 }
2417 
py_uwsgi_ready_fd(PyObject * self,PyObject * args)2418 PyObject *py_uwsgi_ready_fd(PyObject * self, PyObject * args) {
2419 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
2420 	return PyInt_FromLong(uwsgi_ready_fd(wsgi_req));
2421 }
2422 
py_uwsgi_accepting(PyObject * self,PyObject * args)2423 PyObject *py_uwsgi_accepting(PyObject * self, PyObject * args) {
2424 	int accepting = 1;
2425 	if (!PyArg_ParseTuple(args, "|i", &accepting)) {
2426 		return NULL;
2427 	}
2428 	uwsgi.workers[uwsgi.mywid].accepting = !!accepting;
2429 	return Py_None;
2430 }
2431 
py_uwsgi_parse_file(PyObject * self,PyObject * args)2432 PyObject *py_uwsgi_parse_file(PyObject * self, PyObject * args) {
2433 
2434 	char *filename;
2435 	int fd;
2436 	ssize_t len;
2437 	char *buffer, *ptrbuf, *bufferend, *keybuf;
2438 	uint16_t strsize = 0, keysize = 0;
2439 
2440 	struct uwsgi_header uh;
2441 	PyObject *zero;
2442 
2443 	if (!PyArg_ParseTuple(args, "s:parsefile", &filename)) {
2444 		return NULL;
2445 	}
2446 
2447 	UWSGI_RELEASE_GIL
2448 
2449 	fd = open(filename, O_RDONLY);
2450 	if (fd < 0) {
2451 		uwsgi_error_open(filename);
2452 		UWSGI_GET_GIL
2453 		goto clear;
2454 	}
2455 
2456 	len = read(fd, &uh, 4);
2457 	if (len != 4) {
2458 		uwsgi_error("read()");
2459 		UWSGI_GET_GIL
2460 		goto clear2;
2461 	}
2462 
2463 	buffer = malloc(uh.pktsize);
2464 	if (!buffer) {
2465 		uwsgi_error("malloc()");
2466 		UWSGI_GET_GIL
2467 		goto clear2;
2468 	}
2469 	len = read(fd, buffer, uh.pktsize);
2470 	if (len != uh.pktsize) {
2471 		uwsgi_error("read()");
2472 		free(buffer);
2473 		UWSGI_GET_GIL
2474 		goto clear2;
2475 	}
2476 
2477 	UWSGI_GET_GIL
2478 
2479 	ptrbuf = buffer;
2480 	bufferend = ptrbuf + uh.pktsize;
2481 
2482 	if (!uh.modifier1 || uh.modifier1 == UWSGI_MODIFIER_SPOOL_REQUEST) {
2483 		zero = PyDict_New();
2484 
2485 		while (ptrbuf < bufferend) {
2486 			if (ptrbuf + 2 < bufferend) {
2487 				memcpy(&strsize, ptrbuf, 2);
2488 #ifdef __BIG_ENDIAN__
2489 				strsize = uwsgi_swap16(strsize);
2490 #endif
2491 				/* key cannot be null */
2492 				if (!strsize) {
2493 					uwsgi_log("uwsgi key cannot be null.\n");
2494 					goto clear3;
2495 				}
2496 
2497 				ptrbuf += 2;
2498 				if (ptrbuf + strsize < bufferend) {
2499 					// var key
2500 					keybuf = ptrbuf;
2501 					keysize = strsize;
2502 					ptrbuf += strsize;
2503 					// value can be null (even at the end) so use <=
2504 					if (ptrbuf + 2 <= bufferend) {
2505 						memcpy(&strsize, ptrbuf, 2);
2506 #ifdef __BIG_ENDIAN__
2507 						strsize = uwsgi_swap16(strsize);
2508 #endif
2509 						ptrbuf += 2;
2510 						if (ptrbuf + strsize <= bufferend) {
2511 							PyDict_SetItem(zero, PyString_FromStringAndSize(keybuf, keysize), PyString_FromStringAndSize(ptrbuf, strsize));
2512 							ptrbuf += strsize;
2513 						}
2514 						else {
2515 							goto clear3;
2516 						}
2517 					}
2518 					else {
2519 						goto clear3;
2520 					}
2521 				}
2522 			}
2523 			else {
2524 				goto clear3;
2525 			}
2526 		}
2527 
2528 		close(fd);
2529 		free(buffer);
2530 		return zero;
2531 
2532 	}
2533 
2534 	free(buffer);
2535 	goto clear2;
2536 
2537       clear3:
2538 	Py_DECREF(zero);
2539 	free(buffer);
2540       clear2:
2541 	close(fd);
2542       clear:
2543 	Py_INCREF(Py_None);
2544 	return Py_None;
2545 
2546 }
2547 
2548 static PyMethodDef uwsgi_spooler_methods[] = {
2549 #ifdef PYTHREE
2550 	{"send_to_spooler", (PyCFunction)(void *)py_uwsgi_send_spool, METH_VARARGS|METH_KEYWORDS, ""},
2551 	{"spool", (PyCFunction)(void *)py_uwsgi_send_spool, METH_VARARGS|METH_KEYWORDS, ""},
2552 #else
2553 	{"send_to_spooler", (PyCFunction)(void *)py_uwsgi_send_spool, METH_KEYWORDS, ""},
2554 	{"spool", (PyCFunction)(void *)py_uwsgi_send_spool, METH_KEYWORDS, ""},
2555 #endif
2556 	{"set_spooler_frequency", py_uwsgi_spooler_freq, METH_VARARGS, ""},
2557 	{"spooler_jobs", py_uwsgi_spooler_jobs, METH_VARARGS, ""},
2558 	{"spooler_pid", py_uwsgi_spooler_pid, METH_VARARGS, ""},
2559 	{"spooler_pids", py_uwsgi_spooler_pids, METH_VARARGS, ""},
2560 
2561 	{"spooler_get_task", py_uwsgi_spooler_get_task, METH_VARARGS, ""},
2562 	{NULL, NULL},
2563 };
2564 
2565 
py_uwsgi_suspend(PyObject * self,PyObject * args)2566 PyObject *py_uwsgi_suspend(PyObject * self, PyObject * args) {
2567 
2568 	struct wsgi_request *wsgi_req = py_current_wsgi_req();
2569 
2570 	if (uwsgi.schedule_to_main) uwsgi.schedule_to_main(wsgi_req);
2571 
2572 	Py_INCREF(Py_True);
2573 	return Py_True;
2574 
2575 }
2576 
2577 static PyMethodDef uwsgi_advanced_methods[] = {
2578 	{"reload", py_uwsgi_reload, METH_VARARGS, ""},
2579 	{"stop", py_uwsgi_stop, METH_VARARGS, ""},
2580 	{"workers", py_uwsgi_workers, METH_VARARGS, ""},
2581 	{"masterpid", py_uwsgi_masterpid, METH_VARARGS, ""},
2582 	{"total_requests", py_uwsgi_total_requests, METH_VARARGS, ""},
2583 	{"request_id", py_uwsgi_request_id, METH_VARARGS, ""},
2584 	{"worker_id", py_uwsgi_worker_id, METH_VARARGS, ""},
2585 	{"mule_id", py_uwsgi_mule_id, METH_VARARGS, ""},
2586 	{"log", py_uwsgi_log, METH_VARARGS, ""},
2587 	{"log_this_request", py_uwsgi_log_this, METH_VARARGS, ""},
2588 	{"set_logvar", py_uwsgi_set_logvar, METH_VARARGS, ""},
2589 	{"get_logvar", py_uwsgi_get_logvar, METH_VARARGS, ""},
2590 	{"alarm", py_uwsgi_alarm, METH_VARARGS, ""},
2591 	{"disconnect", py_uwsgi_disconnect, METH_VARARGS, ""},
2592 	{"lock", py_uwsgi_lock, METH_VARARGS, ""},
2593 	{"is_locked", py_uwsgi_is_locked, METH_VARARGS, ""},
2594 	{"unlock", py_uwsgi_unlock, METH_VARARGS, ""},
2595 	{"cl", py_uwsgi_cl, METH_VARARGS, ""},
2596 	{"accepting", py_uwsgi_accepting, METH_VARARGS, ""},
2597 
2598 	{"setprocname", py_uwsgi_setprocname, METH_VARARGS, ""},
2599 
2600 	{"listen_queue", py_uwsgi_listen_queue, METH_VARARGS, ""},
2601 
2602 	{"register_signal", py_uwsgi_register_signal, METH_VARARGS, ""},
2603 	{"signal", py_uwsgi_signal, METH_VARARGS, ""},
2604 	{"signal_wait", py_uwsgi_signal_wait, METH_VARARGS, ""},
2605 	{"signal_registered", py_uwsgi_signal_registered, METH_VARARGS, ""},
2606 	{"signal_received", py_uwsgi_signal_received, METH_VARARGS, ""},
2607 	{"add_file_monitor", py_uwsgi_add_file_monitor, METH_VARARGS, ""},
2608 	{"add_timer", py_uwsgi_add_timer, METH_VARARGS, ""},
2609 	{"add_rb_timer", py_uwsgi_add_rb_timer, METH_VARARGS, ""},
2610 	{"add_cron", py_uwsgi_add_cron, METH_VARARGS, ""},
2611 
2612 #ifdef UWSGI_ROUTING
2613 	{"route", py_uwsgi_route, METH_VARARGS, ""},
2614 #endif
2615 
2616 	{"register_rpc", py_uwsgi_register_rpc, METH_VARARGS, ""},
2617 	{"rpc", py_uwsgi_rpc, METH_VARARGS, ""},
2618 	{"rpc_list", py_uwsgi_rpc_list, METH_VARARGS, ""},
2619 	{"call", py_uwsgi_call, METH_VARARGS, ""},
2620 	{"sendfile", py_uwsgi_advanced_sendfile, METH_VARARGS, ""},
2621 	{"offload", py_uwsgi_offload, METH_VARARGS, ""},
2622 	{"set_warning_message", py_uwsgi_warning, METH_VARARGS, ""},
2623 	{"mem", py_uwsgi_mem, METH_VARARGS, ""},
2624 	{"logsize", py_uwsgi_logsize, METH_VARARGS, ""},
2625 #ifdef UWSGI_SSL
2626 	{"i_am_the_lord", py_uwsgi_i_am_the_lord, METH_VARARGS, ""},
2627 	{"lord_scroll", py_uwsgi_lord_scroll, METH_VARARGS, ""},
2628 	{"scrolls", py_uwsgi_scrolls, METH_VARARGS, ""},
2629 #endif
2630 	{"async_sleep", py_uwsgi_async_sleep, METH_VARARGS, ""},
2631 	{"async_connect", py_uwsgi_async_connect, METH_VARARGS, ""},
2632 
2633 	{"green_schedule", py_uwsgi_suspend, METH_VARARGS, ""},
2634 	{"suspend", py_uwsgi_suspend, METH_VARARGS, ""},
2635 	{"wait_fd_read", py_eventfd_read, METH_VARARGS, ""},
2636 	{"wait_fd_write", py_eventfd_write, METH_VARARGS, ""},
2637 
2638 	{"connect", py_uwsgi_connect, METH_VARARGS, ""},
2639 	{"connection_fd", py_uwsgi_connection_fd, METH_VARARGS, ""},
2640 	{"is_connected", py_uwsgi_is_connected, METH_VARARGS, ""},
2641 	{"send", py_uwsgi_send, METH_VARARGS, ""},
2642 	{"recv", py_uwsgi_recv, METH_VARARGS, ""},
2643 	{"close", py_uwsgi_close, METH_VARARGS, ""},
2644 	{"i_am_the_spooler", py_uwsgi_i_am_the_spooler, METH_VARARGS, ""},
2645 
2646 	{"parsefile", py_uwsgi_parse_file, METH_VARARGS, ""},
2647 	{"embedded_data", py_uwsgi_embedded_data, METH_VARARGS, ""},
2648 	{"extract", py_uwsgi_extract, METH_VARARGS, ""},
2649 
2650 	{"mule_msg", py_uwsgi_mule_msg, METH_VARARGS, ""},
2651 	{"farm_msg", py_uwsgi_farm_msg, METH_VARARGS, ""},
2652 	{"mule_get_msg", (PyCFunction)(void *)py_uwsgi_mule_get_msg, METH_VARARGS|METH_KEYWORDS, ""},
2653 	{"farm_get_msg", py_uwsgi_farm_get_msg, METH_VARARGS, ""},
2654 	{"in_farm", py_uwsgi_in_farm, METH_VARARGS, ""},
2655 
2656 	{"ready", py_uwsgi_ready, METH_VARARGS, ""},
2657 
2658 	{"set_user_harakiri", py_uwsgi_set_user_harakiri, METH_VARARGS, ""},
2659 
2660 	{"websocket_recv", py_uwsgi_websocket_recv, METH_VARARGS, ""},
2661 	{"websocket_recv_nb", py_uwsgi_websocket_recv_nb, METH_VARARGS, ""},
2662 	{"websocket_send", py_uwsgi_websocket_send, METH_VARARGS, ""},
2663 	{"websocket_send_binary", py_uwsgi_websocket_send_binary, METH_VARARGS, ""},
2664 	{"websocket_handshake", py_uwsgi_websocket_handshake, METH_VARARGS, ""},
2665 
2666 	{"chunked_read", py_uwsgi_chunked_read, METH_VARARGS, ""},
2667 	{"chunked_read_nb", py_uwsgi_chunked_read_nb, METH_VARARGS, ""},
2668 
2669 	{"ready_fd", py_uwsgi_ready_fd, METH_VARARGS, ""},
2670 
2671 	{"add_var", py_uwsgi_add_var, METH_VARARGS, ""},
2672 
2673 	{"micros", py_uwsgi_micros, METH_VARARGS, ""},
2674 
2675 	{NULL, NULL},
2676 };
2677 
2678 
2679 static PyMethodDef uwsgi_sa_methods[] = {
2680 	{"sharedarea_read", py_uwsgi_sharedarea_read, METH_VARARGS, ""},
2681 	{"sharedarea_write", py_uwsgi_sharedarea_write, METH_VARARGS, ""},
2682 	{"sharedarea_readbyte", py_uwsgi_sharedarea_read8, METH_VARARGS, ""},
2683 	{"sharedarea_writebyte", py_uwsgi_sharedarea_write8, METH_VARARGS, ""},
2684 	{"sharedarea_read8", py_uwsgi_sharedarea_read8, METH_VARARGS, ""},
2685 	{"sharedarea_write8", py_uwsgi_sharedarea_write8, METH_VARARGS, ""},
2686 	{"sharedarea_readlong", py_uwsgi_sharedarea_read64, METH_VARARGS, ""},
2687 	{"sharedarea_writelong", py_uwsgi_sharedarea_write64, METH_VARARGS, ""},
2688 	{"sharedarea_read64", py_uwsgi_sharedarea_read64, METH_VARARGS, ""},
2689 	{"sharedarea_write64", py_uwsgi_sharedarea_write64, METH_VARARGS, ""},
2690 	{"sharedarea_read32", py_uwsgi_sharedarea_read32, METH_VARARGS, ""},
2691 	{"sharedarea_write32", py_uwsgi_sharedarea_write32, METH_VARARGS, ""},
2692 	{"sharedarea_read16", py_uwsgi_sharedarea_read16, METH_VARARGS, ""},
2693 	{"sharedarea_write16", py_uwsgi_sharedarea_write16, METH_VARARGS, ""},
2694 	{"sharedarea_inclong", py_uwsgi_sharedarea_inc64, METH_VARARGS, ""},
2695 	{"sharedarea_inc64", py_uwsgi_sharedarea_inc64, METH_VARARGS, ""},
2696 	{"sharedarea_inc32", py_uwsgi_sharedarea_inc32, METH_VARARGS, ""},
2697 	{"sharedarea_dec64", py_uwsgi_sharedarea_dec64, METH_VARARGS, ""},
2698 	{"sharedarea_dec32", py_uwsgi_sharedarea_dec32, METH_VARARGS, ""},
2699 	{"sharedarea_rlock", py_uwsgi_sharedarea_rlock, METH_VARARGS, ""},
2700 	{"sharedarea_wlock", py_uwsgi_sharedarea_wlock, METH_VARARGS, ""},
2701 	{"sharedarea_unlock", py_uwsgi_sharedarea_unlock, METH_VARARGS, ""},
2702 #if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
2703 #ifndef HAS_NOT_PyMemoryView_FromBuffer
2704 	{"sharedarea_memoryview", py_uwsgi_sharedarea_memoryview, METH_VARARGS, ""},
2705 #endif
2706 	{"sharedarea_object", py_uwsgi_sharedarea_object, METH_VARARGS, ""},
2707 #endif
2708 	{NULL, NULL},
2709 };
2710 
py_uwsgi_cache_clear(PyObject * self,PyObject * args)2711 PyObject *py_uwsgi_cache_clear(PyObject * self, PyObject * args) {
2712 
2713         char *cache = NULL;
2714 
2715         if (!PyArg_ParseTuple(args, "|s:cache_clear", &cache)) {
2716                 return NULL;
2717         }
2718 
2719         UWSGI_RELEASE_GIL
2720         if (!uwsgi_cache_magic_clear(cache)) {
2721                 UWSGI_GET_GIL
2722                 Py_INCREF(Py_True);
2723                 return Py_True;
2724         }
2725         UWSGI_GET_GIL
2726 
2727         Py_INCREF(Py_None);
2728         return Py_None;
2729 }
2730 
2731 
py_uwsgi_cache_del(PyObject * self,PyObject * args)2732 PyObject *py_uwsgi_cache_del(PyObject * self, PyObject * args) {
2733 
2734 	char *key;
2735         Py_ssize_t keylen = 0;
2736         char *cache = NULL;
2737 
2738         if (!PyArg_ParseTuple(args, "s#|s:cache_del", &key, &keylen, &cache)) {
2739                 return NULL;
2740         }
2741 
2742         UWSGI_RELEASE_GIL
2743         if (!uwsgi_cache_magic_del(key, keylen, cache)) {
2744                 UWSGI_GET_GIL
2745                 Py_INCREF(Py_True);
2746                 return Py_True;
2747         }
2748         UWSGI_GET_GIL
2749 
2750         Py_INCREF(Py_None);
2751         return Py_None;
2752 
2753 
2754 }
2755 
2756 
py_uwsgi_cache_set(PyObject * self,PyObject * args)2757 PyObject *py_uwsgi_cache_set(PyObject * self, PyObject * args) {
2758 
2759 	char *key;
2760 	char *value;
2761 	Py_ssize_t vallen = 0;
2762 	Py_ssize_t keylen = 0;
2763 	char *remote = NULL;
2764 
2765 	uint64_t expires = 0;
2766 
2767 	if (!PyArg_ParseTuple(args, "s#s#|ls:cache_set", &key, &keylen, &value, &vallen, &expires, &remote)) {
2768 		return NULL;
2769 	}
2770 
2771 	UWSGI_RELEASE_GIL
2772 	if (uwsgi_cache_magic_set(key, keylen, value, vallen, expires, 0, remote)) {
2773 		UWSGI_GET_GIL
2774 		Py_INCREF(Py_None);
2775 		return Py_None;
2776 	}
2777 	UWSGI_GET_GIL
2778 
2779 	Py_INCREF(Py_True);
2780 	return Py_True;
2781 
2782 }
2783 
py_uwsgi_cache_update(PyObject * self,PyObject * args)2784 PyObject *py_uwsgi_cache_update(PyObject * self, PyObject * args) {
2785 
2786 	char *key;
2787         char *value;
2788         Py_ssize_t vallen = 0;
2789         Py_ssize_t keylen = 0;
2790         char *remote = NULL;
2791 
2792         uint64_t expires = 0;
2793 
2794         if (!PyArg_ParseTuple(args, "s#s#|ls:cache_update", &key, &keylen, &value, &vallen, &expires, &remote)) {
2795                 return NULL;
2796         }
2797 
2798         UWSGI_RELEASE_GIL
2799         if (uwsgi_cache_magic_set(key, keylen, value, vallen, expires, UWSGI_CACHE_FLAG_UPDATE, remote)) {
2800                 UWSGI_GET_GIL
2801                 Py_INCREF(Py_None);
2802                 return Py_None;
2803         }
2804         UWSGI_GET_GIL
2805 
2806         Py_INCREF(Py_True);
2807         return Py_True;
2808 
2809 }
2810 
py_uwsgi_cache_inc(PyObject * self,PyObject * args)2811 PyObject *py_uwsgi_cache_inc(PyObject * self, PyObject * args) {
2812 
2813         char *key;
2814         Py_ssize_t keylen = 0;
2815         char *remote = NULL;
2816 	int64_t value = 1;
2817         uint64_t expires = 0;
2818 
2819         if (!PyArg_ParseTuple(args, "s#|lls:cache_inc", &key, &keylen, &value, &expires, &remote)) {
2820                 return NULL;
2821         }
2822 
2823         UWSGI_RELEASE_GIL
2824         if (uwsgi_cache_magic_set(key, keylen, (char *) &value, 8, expires, UWSGI_CACHE_FLAG_UPDATE|UWSGI_CACHE_FLAG_MATH|UWSGI_CACHE_FLAG_FIXEXPIRE|UWSGI_CACHE_FLAG_INC, remote)) {
2825                 UWSGI_GET_GIL
2826                 Py_INCREF(Py_None);
2827                 return Py_None;
2828         }
2829         UWSGI_GET_GIL
2830 
2831         Py_INCREF(Py_True);
2832         return Py_True;
2833 
2834 }
2835 
py_uwsgi_cache_dec(PyObject * self,PyObject * args)2836 PyObject *py_uwsgi_cache_dec(PyObject * self, PyObject * args) {
2837 
2838         char *key;
2839         Py_ssize_t keylen = 0;
2840         char *remote = NULL;
2841         int64_t value = 1;
2842         uint64_t expires = 0;
2843 
2844         if (!PyArg_ParseTuple(args, "s#|lls:cache_dec", &key, &keylen, &value, &expires, &remote)) {
2845                 return NULL;
2846         }
2847 
2848         UWSGI_RELEASE_GIL
2849         if (uwsgi_cache_magic_set(key, keylen, (char *) &value, 8, expires, UWSGI_CACHE_FLAG_UPDATE|UWSGI_CACHE_FLAG_MATH|UWSGI_CACHE_FLAG_FIXEXPIRE|UWSGI_CACHE_FLAG_DEC, remote)) {
2850                 UWSGI_GET_GIL
2851                 Py_INCREF(Py_None);
2852                 return Py_None;
2853         }
2854         UWSGI_GET_GIL
2855 
2856         Py_INCREF(Py_True);
2857         return Py_True;
2858 
2859 }
2860 
py_uwsgi_cache_mul(PyObject * self,PyObject * args)2861 PyObject *py_uwsgi_cache_mul(PyObject * self, PyObject * args) {
2862 
2863         char *key;
2864         Py_ssize_t keylen = 0;
2865         char *remote = NULL;
2866         int64_t value = 2;
2867         uint64_t expires = 0;
2868 
2869         if (!PyArg_ParseTuple(args, "s#|lls:cache_mul", &key, &keylen, &value, &expires, &remote)) {
2870                 return NULL;
2871         }
2872 
2873         UWSGI_RELEASE_GIL
2874         if (uwsgi_cache_magic_set(key, keylen, (char *) &value, 8, expires, UWSGI_CACHE_FLAG_UPDATE|UWSGI_CACHE_FLAG_MATH|UWSGI_CACHE_FLAG_FIXEXPIRE|UWSGI_CACHE_FLAG_MUL, remote)) {
2875                 UWSGI_GET_GIL
2876                 Py_INCREF(Py_None);
2877                 return Py_None;
2878         }
2879         UWSGI_GET_GIL
2880 
2881         Py_INCREF(Py_True);
2882         return Py_True;
2883 
2884 }
2885 
py_uwsgi_cache_div(PyObject * self,PyObject * args)2886 PyObject *py_uwsgi_cache_div(PyObject * self, PyObject * args) {
2887 
2888         char *key;
2889         Py_ssize_t keylen = 0;
2890         char *remote = NULL;
2891         int64_t value = 2;
2892         uint64_t expires = 0;
2893 
2894         if (!PyArg_ParseTuple(args, "s#|lls:cache_div", &key, &keylen, &value, &expires, &remote)) {
2895                 return NULL;
2896         }
2897 
2898         UWSGI_RELEASE_GIL
2899         if (uwsgi_cache_magic_set(key, keylen, (char *) &value, 8, expires, UWSGI_CACHE_FLAG_UPDATE|UWSGI_CACHE_FLAG_MATH|UWSGI_CACHE_FLAG_FIXEXPIRE|UWSGI_CACHE_FLAG_DIV, remote)) {
2900                 UWSGI_GET_GIL
2901                 Py_INCREF(Py_None);
2902                 return Py_None;
2903         }
2904         UWSGI_GET_GIL
2905 
2906         Py_INCREF(Py_True);
2907         return Py_True;
2908 
2909 }
2910 
2911 
2912 
py_uwsgi_cache_exists(PyObject * self,PyObject * args)2913 PyObject *py_uwsgi_cache_exists(PyObject * self, PyObject * args) {
2914 
2915 	char *key;
2916         Py_ssize_t keylen = 0;
2917         char *cache = NULL;
2918 
2919         if (!PyArg_ParseTuple(args, "s#|s:cache_exists", &key, &keylen, &cache)) {
2920                 return NULL;
2921         }
2922 
2923         UWSGI_RELEASE_GIL
2924         if (uwsgi_cache_magic_exists(key, keylen, cache)) {
2925 		UWSGI_GET_GIL
2926 		Py_INCREF(Py_True);
2927 		return Py_True;
2928 	}
2929         UWSGI_GET_GIL
2930 
2931         Py_INCREF(Py_None);
2932         return Py_None;
2933 }
2934 
py_uwsgi_queue_push(PyObject * self,PyObject * args)2935 PyObject *py_uwsgi_queue_push(PyObject * self, PyObject * args) {
2936 
2937 	Py_ssize_t msglen = 0;
2938 	char *message ;
2939 	PyObject *res;
2940 
2941 	if (!PyArg_ParseTuple(args, "s#:queue_push", &message, &msglen)) {
2942                 return NULL;
2943         }
2944 
2945 	if (uwsgi.queue_size) {
2946 		UWSGI_RELEASE_GIL
2947                 uwsgi_wlock(uwsgi.queue_lock);
2948                 if (uwsgi_queue_push(message, msglen)) {
2949                 	uwsgi_rwunlock(uwsgi.queue_lock);
2950 			UWSGI_GET_GIL
2951 			Py_INCREF(Py_True);
2952                         res = Py_True;
2953                 }
2954                 else {
2955                 	uwsgi_rwunlock(uwsgi.queue_lock);
2956 			UWSGI_GET_GIL
2957                         Py_INCREF(Py_None);
2958                         res = Py_None;
2959                 }
2960                 return res;
2961         }
2962 
2963         Py_INCREF(Py_None);
2964         return Py_None;
2965 
2966 }
2967 
py_uwsgi_queue_set(PyObject * self,PyObject * args)2968 PyObject *py_uwsgi_queue_set(PyObject * self, PyObject * args) {
2969 
2970         Py_ssize_t msglen = 0;
2971 	uint64_t pos = 0;
2972         char *message ;
2973         PyObject *res;
2974 
2975         if (!PyArg_ParseTuple(args, "ls#:queue_set", &pos, &message, &msglen)) {
2976                 return NULL;
2977         }
2978 
2979         if (uwsgi.queue_size) {
2980 		UWSGI_RELEASE_GIL
2981                 uwsgi_wlock(uwsgi.queue_lock);
2982                 if (uwsgi_queue_set(pos, message, msglen)) {
2983                 	uwsgi_rwunlock(uwsgi.queue_lock);
2984 			UWSGI_GET_GIL
2985                         Py_INCREF(Py_True);
2986                         res = Py_True;
2987                 }
2988                 else {
2989                 	uwsgi_rwunlock(uwsgi.queue_lock);
2990 			UWSGI_GET_GIL
2991                         Py_INCREF(Py_None);
2992                         res = Py_None;
2993                 }
2994                 return res;
2995         }
2996 
2997         Py_INCREF(Py_None);
2998         return Py_None;
2999 
3000 }
3001 
3002 
py_uwsgi_queue_slot(PyObject * self,PyObject * args)3003 PyObject *py_uwsgi_queue_slot(PyObject * self, PyObject * args) {
3004 
3005 	return PyLong_FromUnsignedLongLong(uwsgi.queue_header->pos);
3006 }
3007 
py_uwsgi_queue_pull_slot(PyObject * self,PyObject * args)3008 PyObject *py_uwsgi_queue_pull_slot(PyObject * self, PyObject * args) {
3009 
3010 	return PyLong_FromUnsignedLongLong(uwsgi.queue_header->pull_pos);
3011 }
3012 
3013 
py_uwsgi_queue_pull(PyObject * self,PyObject * args)3014 PyObject *py_uwsgi_queue_pull(PyObject * self, PyObject * args) {
3015 
3016 	char *message;
3017 	uint64_t size;
3018 	PyObject *res;
3019 	char *storage;
3020 
3021 	if (uwsgi.queue_size) {
3022 		UWSGI_RELEASE_GIL
3023 		uwsgi_wlock(uwsgi.queue_lock);
3024 
3025 		message = uwsgi_queue_pull(&size);
3026 
3027                 if (!message || size == 0) {
3028                 	uwsgi_rwunlock(uwsgi.queue_lock);
3029 			UWSGI_GET_GIL
3030                         Py_INCREF(Py_None);
3031                         return Py_None;
3032                 }
3033 
3034                 storage = uwsgi_malloc(size);
3035 		memcpy(storage, message, size);
3036 
3037                 uwsgi_rwunlock(uwsgi.queue_lock);
3038 		UWSGI_GET_GIL
3039 
3040 		res = PyString_FromStringAndSize(storage, size);
3041 		free(storage);
3042                 return res;
3043 	}
3044 
3045 	Py_INCREF(Py_None);
3046         return Py_None;
3047 
3048 }
3049 
py_uwsgi_queue_pop(PyObject * self,PyObject * args)3050 PyObject *py_uwsgi_queue_pop(PyObject * self, PyObject * args) {
3051 
3052         char *message;
3053         uint64_t size;
3054         PyObject *res;
3055 	char *storage;
3056 
3057         if (uwsgi.queue_size) {
3058 
3059 		UWSGI_RELEASE_GIL
3060                 uwsgi_wlock(uwsgi.queue_lock);
3061 
3062                 message = uwsgi_queue_pop(&size);
3063 		if (!message || size == 0) {
3064                 	uwsgi_rwunlock(uwsgi.queue_lock);
3065 			UWSGI_GET_GIL
3066                         Py_INCREF(Py_None);
3067 			return Py_None;
3068 		}
3069 
3070 		storage = uwsgi_malloc(size);
3071                 memcpy(storage, message, size);
3072 
3073                 uwsgi_rwunlock(uwsgi.queue_lock);
3074 		UWSGI_GET_GIL
3075 
3076 		res = PyString_FromStringAndSize(storage, size);
3077 		free(storage);
3078                 return res;
3079         }
3080 
3081         Py_INCREF(Py_None);
3082         return Py_None;
3083 
3084 }
3085 
3086 
py_uwsgi_queue_get(PyObject * self,PyObject * args)3087 PyObject *py_uwsgi_queue_get(PyObject * self, PyObject * args) {
3088 
3089 	long index = 0;
3090 	uint64_t size = 0;
3091 	char *message;
3092 	PyObject *res;
3093 	char *storage;
3094 
3095 	if (!PyArg_ParseTuple(args, "l:queue_get", &index)) {
3096                 return NULL;
3097         }
3098 
3099 	if (uwsgi.queue_size) {
3100 		UWSGI_RELEASE_GIL
3101 		uwsgi_rlock(uwsgi.queue_lock);
3102 
3103 		message = uwsgi_queue_get(index, &size);
3104                 if (!message || size == 0) {
3105 			uwsgi_rwunlock(uwsgi.queue_lock);
3106 			UWSGI_GET_GIL
3107                         Py_INCREF(Py_None);
3108 			return Py_None;
3109 		}
3110 
3111 		storage = uwsgi_malloc(size);
3112                 memcpy(storage, message, size);
3113 
3114 		uwsgi_rwunlock(uwsgi.queue_lock);
3115 		UWSGI_GET_GIL
3116 
3117                 res = PyString_FromStringAndSize(storage, size);
3118 		free(storage);
3119 		return res;
3120 	}
3121 
3122 	Py_INCREF(Py_None);
3123 	return Py_None;
3124 }
3125 
py_uwsgi_queue_last(PyObject * self,PyObject * args)3126 PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
3127 
3128         long i, num = 0;
3129         uint64_t size = 0;
3130         char *message;
3131         PyObject *res = NULL;
3132 	uint64_t base;
3133 	char *storage;
3134 
3135         if (!PyArg_ParseTuple(args, "|l:queue_last", &num)) {
3136                 return NULL;
3137         }
3138 
3139         if (uwsgi.queue_size) {
3140 
3141 		if (num > 0) {
3142 			res = PyList_New(0);
3143 		}
3144 
3145 		UWSGI_RELEASE_GIL
3146                 uwsgi_rlock(uwsgi.queue_lock);
3147 
3148 		if (uwsgi.queue_header->pos > 0) {
3149 			base = uwsgi.queue_header->pos-1;
3150 		}
3151 		else {
3152 			base = uwsgi.queue_size-1;
3153 		}
3154 
3155 		if (num == 0) {
3156                 	message = uwsgi_queue_get(base, &size);
3157                 	if (!message || size == 0) {
3158                 		uwsgi_rwunlock(uwsgi.queue_lock);
3159 				UWSGI_GET_GIL
3160                         	Py_INCREF(Py_None);
3161 				return Py_None;
3162 			}
3163 
3164 			storage = uwsgi_malloc(size);
3165                         memcpy(storage, message, size);
3166 
3167                 	uwsgi_rwunlock(uwsgi.queue_lock);
3168 			UWSGI_GET_GIL
3169 
3170 			res = PyString_FromStringAndSize(storage, size);
3171 			free(storage);
3172 			return res;
3173 		}
3174 
3175 		if (num > (long)uwsgi.queue_size) num = uwsgi.queue_size;
3176 
3177 		char **queue_items = uwsgi_malloc(sizeof(char *) * num);
3178 		uint64_t *queue_items_size = uwsgi_malloc(sizeof(uint64_t) * num);
3179 		long item_pos = 0;
3180 		while(num) {
3181                 	message = uwsgi_queue_get(base, &size);
3182                 	if (!message || size == 0) {
3183 				queue_items[item_pos] = NULL;
3184 				queue_items_size[item_pos] = 0;
3185                 	}
3186 			else {
3187 				queue_items[item_pos] = uwsgi_malloc(size);
3188 				memcpy(queue_items[item_pos], message, size);
3189 				queue_items_size[item_pos] = size;
3190 			}
3191 			item_pos++;
3192 			if (base > 0) {
3193 				base--;
3194 			}
3195 			else {
3196 				base = uwsgi.queue_size-1;
3197 			}
3198 			num--;
3199 		}
3200 
3201                 uwsgi_rwunlock(uwsgi.queue_lock);
3202 		UWSGI_GET_GIL
3203 
3204 		for(i=0;i<item_pos;i++) {
3205 			if (queue_items[i]) {
3206 				PyObject *zero = PyString_FromStringAndSize(queue_items[i], queue_items_size[i]);
3207 				PyList_Append(res, zero);
3208 				Py_DECREF(zero);
3209 				free(queue_items[i]);
3210 			}
3211 			else {
3212 				Py_INCREF(Py_None);
3213 				PyList_Append(res, Py_None);
3214 			}
3215 		}
3216 		free(queue_items);
3217 		free(queue_items_size);
3218                 return res;
3219         }
3220 
3221         Py_INCREF(Py_None);
3222         return Py_None;
3223 }
3224 
3225 
py_uwsgi_cache_get(PyObject * self,PyObject * args)3226 PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
3227 
3228 	char *key;
3229 	Py_ssize_t keylen = 0;
3230 	char *cache = NULL;
3231 
3232 	if (!PyArg_ParseTuple(args, "s#|s:cache_get", &key, &keylen, &cache)) {
3233 		return NULL;
3234 	}
3235 
3236 	uint64_t vallen = 0;
3237 	UWSGI_RELEASE_GIL
3238 	char *value = uwsgi_cache_magic_get(key, keylen, &vallen, NULL, cache);
3239 	UWSGI_GET_GIL
3240 	if (value) {
3241 		// in python 3.x we return bytes
3242 		PyObject *ret = PyString_FromStringAndSize(value, vallen);
3243 		free(value);
3244 		return ret;
3245 	}
3246 
3247 	Py_INCREF(Py_None);
3248 	return Py_None;
3249 
3250 }
3251 
py_uwsgi_cache_num(PyObject * self,PyObject * args)3252 PyObject *py_uwsgi_cache_num(PyObject * self, PyObject * args) {
3253 
3254         char *key;
3255         Py_ssize_t keylen = 0;
3256         char *cache = NULL;
3257 
3258         if (!PyArg_ParseTuple(args, "s#|s:cache_num", &key, &keylen, &cache)) {
3259                 return NULL;
3260         }
3261 
3262         uint64_t vallen = 0;
3263         UWSGI_RELEASE_GIL
3264         char *value = uwsgi_cache_magic_get(key, keylen, &vallen, NULL, cache);
3265         UWSGI_GET_GIL
3266         if (value && vallen == 8) {
3267 		int64_t *num = (int64_t *) value;
3268                 PyObject *ret = PyLong_FromLong(*num);
3269                 free(value);
3270                 return ret;
3271         }
3272 
3273         return PyLong_FromLong(0);
3274 
3275 }
3276 
py_uwsgi_cache_keys(PyObject * self,PyObject * args)3277 PyObject *py_uwsgi_cache_keys(PyObject * self, PyObject * args) {
3278 	char *cache = NULL;
3279         struct uwsgi_cache_item *uci = NULL;
3280         uint64_t pos = 0;
3281 
3282         if (!PyArg_ParseTuple(args, "|s:cache_keys", &cache)) {
3283                 return NULL;
3284         }
3285 
3286 	struct uwsgi_cache *uc = uwsgi_cache_by_name(cache);
3287 	if (!uc) {
3288 		return PyErr_Format(PyExc_ValueError, "no local uWSGI cache available");
3289 	}
3290 
3291 	PyObject *l = PyList_New(0);
3292 
3293 	uwsgi_rlock(uc->lock);
3294         for(;;) {
3295                 uci = uwsgi_cache_keys(uc, &pos, &uci);
3296                 if (!uci) break;
3297 		PyObject *ci = PyString_FromStringAndSize(uci->key, uci->keysize);
3298 		PyList_Append(l, ci);
3299 		Py_DECREF(ci);
3300         }
3301 	uwsgi_rwunlock(uc->lock);
3302 	return l;
3303 }
3304 
3305 
3306 static PyMethodDef uwsgi_cache_methods[] = {
3307 	{"cache_get", py_uwsgi_cache_get, METH_VARARGS, ""},
3308 	{"cache_set", py_uwsgi_cache_set, METH_VARARGS, ""},
3309 	{"cache_update", py_uwsgi_cache_update, METH_VARARGS, ""},
3310 	{"cache_del", py_uwsgi_cache_del, METH_VARARGS, ""},
3311 	{"cache_exists", py_uwsgi_cache_exists, METH_VARARGS, ""},
3312 	{"cache_clear", py_uwsgi_cache_clear, METH_VARARGS, ""},
3313 	{"cache_inc", py_uwsgi_cache_inc, METH_VARARGS, ""},
3314 	{"cache_dec", py_uwsgi_cache_dec, METH_VARARGS, ""},
3315 	{"cache_mul", py_uwsgi_cache_mul, METH_VARARGS, ""},
3316 	{"cache_div", py_uwsgi_cache_div, METH_VARARGS, ""},
3317 	{"cache_num", py_uwsgi_cache_num, METH_VARARGS, ""},
3318 	{"cache_keys", py_uwsgi_cache_keys, METH_VARARGS, ""},
3319 	{NULL, NULL},
3320 };
3321 
3322 static PyMethodDef uwsgi_queue_methods[] = {
3323 	{"queue_get", py_uwsgi_queue_get, METH_VARARGS, ""},
3324 	{"queue_set", py_uwsgi_queue_set, METH_VARARGS, ""},
3325 	{"queue_last", py_uwsgi_queue_last, METH_VARARGS, ""},
3326 	{"queue_push", py_uwsgi_queue_push, METH_VARARGS, ""},
3327 	{"queue_pull", py_uwsgi_queue_pull, METH_VARARGS, ""},
3328 	{"queue_pop", py_uwsgi_queue_pop, METH_VARARGS, ""},
3329 	{"queue_slot", py_uwsgi_queue_slot, METH_VARARGS, ""},
3330 	{"queue_pull_slot", py_uwsgi_queue_pull_slot, METH_VARARGS, ""},
3331 	{NULL, NULL},
3332 };
3333 
py_uwsgi_metric_inc(PyObject * self,PyObject * args)3334 PyObject *py_uwsgi_metric_inc(PyObject * self, PyObject * args) {
3335         char *key;
3336         int64_t value = 1;
3337         if (!PyArg_ParseTuple(args, "s|l:metric_inc", &key, &value)) return NULL;
3338 
3339         UWSGI_RELEASE_GIL
3340         if (uwsgi_metric_inc(key, NULL, value)) {
3341                 UWSGI_GET_GIL
3342                 Py_INCREF(Py_None);
3343                 return Py_None;
3344         }
3345         UWSGI_GET_GIL
3346         Py_INCREF(Py_True);
3347         return Py_True;
3348 
3349 }
3350 
py_uwsgi_metric_dec(PyObject * self,PyObject * args)3351 PyObject *py_uwsgi_metric_dec(PyObject * self, PyObject * args) {
3352         char *key;
3353         int64_t value = 1;
3354         if (!PyArg_ParseTuple(args, "s|l:metric_dec", &key, &value)) return NULL;
3355 
3356         UWSGI_RELEASE_GIL
3357         if (uwsgi_metric_dec(key, NULL, value)) {
3358                 UWSGI_GET_GIL
3359                 Py_INCREF(Py_None);
3360                 return Py_None;
3361         }
3362         UWSGI_GET_GIL
3363         Py_INCREF(Py_True);
3364         return Py_True;
3365 
3366 }
3367 
py_uwsgi_metric_mul(PyObject * self,PyObject * args)3368 PyObject *py_uwsgi_metric_mul(PyObject * self, PyObject * args) {
3369         char *key;
3370         int64_t value = 1;
3371         if (!PyArg_ParseTuple(args, "s|l:metric_mul", &key, &value)) return NULL;
3372 
3373         UWSGI_RELEASE_GIL
3374         if (uwsgi_metric_mul(key, NULL, value)) {
3375                 UWSGI_GET_GIL
3376                 Py_INCREF(Py_None);
3377                 return Py_None;
3378         }
3379         UWSGI_GET_GIL
3380         Py_INCREF(Py_True);
3381         return Py_True;
3382 
3383 }
3384 
py_uwsgi_metric_div(PyObject * self,PyObject * args)3385 PyObject *py_uwsgi_metric_div(PyObject * self, PyObject * args) {
3386         char *key;
3387         int64_t value = 1;
3388         if (!PyArg_ParseTuple(args, "s|l:metric_div", &key, &value)) return NULL;
3389 
3390         UWSGI_RELEASE_GIL
3391         if (uwsgi_metric_div(key, NULL, value)) {
3392                 UWSGI_GET_GIL
3393                 Py_INCREF(Py_None);
3394                 return Py_None;
3395         }
3396         UWSGI_GET_GIL
3397         Py_INCREF(Py_True);
3398         return Py_True;
3399 
3400 }
3401 
py_uwsgi_metric_set(PyObject * self,PyObject * args)3402 PyObject *py_uwsgi_metric_set(PyObject * self, PyObject * args) {
3403         char *key;
3404         int64_t value = 1;
3405         if (!PyArg_ParseTuple(args, "s|l:metric_set", &key, &value)) return NULL;
3406 
3407         UWSGI_RELEASE_GIL
3408         if (uwsgi_metric_set(key, NULL, value)) {
3409                 UWSGI_GET_GIL
3410                 Py_INCREF(Py_None);
3411                 return Py_None;
3412         }
3413         UWSGI_GET_GIL
3414         Py_INCREF(Py_True);
3415         return Py_True;
3416 
3417 }
3418 
py_uwsgi_metric_get(PyObject * self,PyObject * args)3419 PyObject *py_uwsgi_metric_get(PyObject * self, PyObject * args) {
3420         char *key;
3421         if (!PyArg_ParseTuple(args, "s:metric_get", &key)) return NULL;
3422 
3423         UWSGI_RELEASE_GIL
3424         int64_t value = uwsgi_metric_get(key, NULL);
3425         UWSGI_GET_GIL
3426         return PyLong_FromLongLong(value);
3427 }
3428 
py_uwsgi_metric_set_max(PyObject * self,PyObject * args)3429 PyObject *py_uwsgi_metric_set_max(PyObject * self, PyObject * args) {
3430         char *key;
3431         int64_t value = 1;
3432         if (!PyArg_ParseTuple(args, "s|l:metric_set_max", &key, &value)) return NULL;
3433 
3434         UWSGI_RELEASE_GIL
3435         if (uwsgi_metric_set_max(key, NULL, value)) {
3436                 UWSGI_GET_GIL
3437                 Py_INCREF(Py_None);
3438                 return Py_None;
3439         }
3440         UWSGI_GET_GIL
3441         Py_INCREF(Py_True);
3442         return Py_True;
3443 
3444 }
3445 
py_uwsgi_metric_set_min(PyObject * self,PyObject * args)3446 PyObject *py_uwsgi_metric_set_min(PyObject * self, PyObject * args) {
3447         char *key;
3448         int64_t value = 1;
3449         if (!PyArg_ParseTuple(args, "s|l:metric_set_min", &key, &value)) return NULL;
3450 
3451         UWSGI_RELEASE_GIL
3452         if (uwsgi_metric_set_min(key, NULL, value)) {
3453                 UWSGI_GET_GIL
3454                 Py_INCREF(Py_None);
3455                 return Py_None;
3456         }
3457         UWSGI_GET_GIL
3458         Py_INCREF(Py_True);
3459         return Py_True;
3460 
3461 }
3462 
3463 
3464 static PyMethodDef uwsgi_metrics_methods[] = {
3465 	{"metric_inc", py_uwsgi_metric_inc, METH_VARARGS, ""},
3466 	{"metric_dec", py_uwsgi_metric_dec, METH_VARARGS, ""},
3467 	{"metric_mul", py_uwsgi_metric_mul, METH_VARARGS, ""},
3468 	{"metric_div", py_uwsgi_metric_div, METH_VARARGS, ""},
3469 	{"metric_get", py_uwsgi_metric_get, METH_VARARGS, ""},
3470 	{"metric_set", py_uwsgi_metric_set, METH_VARARGS, ""},
3471 	{"metric_set_max", py_uwsgi_metric_set_max, METH_VARARGS, ""},
3472 	{"metric_set_min", py_uwsgi_metric_set_min, METH_VARARGS, ""},
3473 	{NULL, NULL},
3474 };
3475 
3476 
init_uwsgi_module_spooler(PyObject * current_uwsgi_module)3477 void init_uwsgi_module_spooler(PyObject * current_uwsgi_module) {
3478 	PyMethodDef *uwsgi_function;
3479 	PyObject *uwsgi_module_dict;
3480 
3481 	uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
3482 	if (!uwsgi_module_dict) {
3483 		uwsgi_log("could not get uwsgi module __dict__\n");
3484 		exit(1);
3485 	}
3486 
3487 	for (uwsgi_function = uwsgi_spooler_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
3488 		PyObject *func = PyCFunction_New(uwsgi_function, NULL);
3489 		PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
3490 		Py_DECREF(func);
3491 	}
3492 }
3493 
init_uwsgi_module_advanced(PyObject * current_uwsgi_module)3494 void init_uwsgi_module_advanced(PyObject * current_uwsgi_module) {
3495 	PyMethodDef *uwsgi_function;
3496 	PyObject *uwsgi_module_dict;
3497 
3498 	uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
3499 	if (!uwsgi_module_dict) {
3500 		uwsgi_log("could not get uwsgi module __dict__\n");
3501 		exit(1);
3502 	}
3503 
3504 	for (uwsgi_function = uwsgi_advanced_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
3505 		PyObject *func = PyCFunction_New(uwsgi_function, NULL);
3506 		PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
3507 		Py_DECREF(func);
3508 	}
3509 
3510 	for (uwsgi_function = uwsgi_metrics_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
3511                 PyObject *func = PyCFunction_New(uwsgi_function, NULL);
3512                 PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
3513                 Py_DECREF(func);
3514         }
3515 
3516 }
3517 
init_uwsgi_module_cache(PyObject * current_uwsgi_module)3518 void init_uwsgi_module_cache(PyObject * current_uwsgi_module) {
3519 	PyMethodDef *uwsgi_function;
3520 	PyObject *uwsgi_module_dict;
3521 
3522 	uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
3523 	if (!uwsgi_module_dict) {
3524 		uwsgi_log("could not get uwsgi module __dict__\n");
3525 		exit(1);
3526 	}
3527 
3528 	for (uwsgi_function = uwsgi_cache_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
3529 		PyObject *func = PyCFunction_New(uwsgi_function, NULL);
3530 		PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
3531 		Py_DECREF(func);
3532 	}
3533 }
3534 
init_uwsgi_module_queue(PyObject * current_uwsgi_module)3535 void init_uwsgi_module_queue(PyObject * current_uwsgi_module) {
3536         PyMethodDef *uwsgi_function;
3537         PyObject *uwsgi_module_dict;
3538 
3539         uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
3540         if (!uwsgi_module_dict) {
3541                 uwsgi_log("could not get uwsgi module __dict__\n");
3542                 exit(1);
3543         }
3544 
3545         for (uwsgi_function = uwsgi_queue_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
3546                 PyObject *func = PyCFunction_New(uwsgi_function, NULL);
3547                 PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
3548                 Py_DECREF(func);
3549         }
3550 
3551 	PyDict_SetItemString(uwsgi_module_dict, "queue_size", PyLong_FromUnsignedLongLong(uwsgi.queue_size));
3552 }
3553 
3554 
init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module)3555 void init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module) {
3556 	PyMethodDef *uwsgi_function;
3557 	PyObject *uwsgi_module_dict;
3558 
3559 	uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
3560 	if (!uwsgi_module_dict) {
3561 		uwsgi_log("could not get uwsgi module __dict__\n");
3562 		exit(1);
3563 	}
3564 
3565 	for (uwsgi_function = uwsgi_sa_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
3566 		PyObject *func = PyCFunction_New(uwsgi_function, NULL);
3567 		PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
3568 		Py_DECREF(func);
3569 	}
3570 }
3571 
py_snmp_set_counter32(PyObject * self,PyObject * args)3572 PyObject *py_snmp_set_counter32(PyObject * self, PyObject * args) {
3573 
3574                    uint8_t oid_num;
3575                    uint32_t oid_val = 0;
3576 
3577                    if (!PyArg_ParseTuple(args, "bI:snmp_set_counter32", &oid_num, &oid_val)) {
3578                    return NULL;
3579                    }
3580 
3581                    if (oid_num > 100 || oid_num < 1)
3582                    goto clear;
3583 
3584                    UWSGI_RELEASE_GIL
3585                    uwsgi_wlock(uwsgi.snmp_lock);
3586 
3587                    uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32;
3588                    uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
3589 
3590                    uwsgi_rwunlock(uwsgi.snmp_lock);
3591                    UWSGI_GET_GIL
3592 
3593                    Py_INCREF(Py_True);
3594                    return Py_True;
3595 
3596 clear:
3597 
3598 		Py_INCREF(Py_None);
3599 		return Py_None;
3600 }
3601 
py_snmp_set_counter64(PyObject * self,PyObject * args)3602 PyObject *py_snmp_set_counter64(PyObject * self, PyObject * args) {
3603 
3604 	uint8_t oid_num;
3605 	uint64_t oid_val = 0;
3606 
3607 	if (!PyArg_ParseTuple(args, "bK:snmp_set_counter64", &oid_num, &oid_val)) {
3608 		return NULL;
3609 	}
3610 
3611 	if (oid_num > 100 || oid_num < 1)
3612 	goto clear;
3613 
3614 	UWSGI_RELEASE_GIL
3615 	uwsgi_wlock(uwsgi.snmp_lock);
3616 
3617 	uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64;
3618 	uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
3619 
3620 	uwsgi_rwunlock(uwsgi.snmp_lock);
3621 	UWSGI_GET_GIL
3622 
3623 	Py_INCREF(Py_True);
3624 	return Py_True;
3625 
3626 clear:
3627 
3628 	Py_INCREF(Py_None);
3629 	return Py_None;
3630 }
3631 
py_snmp_set_gauge(PyObject * self,PyObject * args)3632 PyObject *py_snmp_set_gauge(PyObject * self, PyObject * args) {
3633 
3634 	uint8_t oid_num;
3635 	uint32_t oid_val = 0;
3636 
3637 	if (!PyArg_ParseTuple(args, "bI:snmp_set_gauge", &oid_num, &oid_val)) {
3638 		return NULL;
3639 	}
3640 
3641 	if (oid_num > 100 || oid_num < 1)
3642 		goto clear;
3643 
3644 	UWSGI_RELEASE_GIL
3645 	uwsgi_wlock(uwsgi.snmp_lock);
3646 
3647 	uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE;
3648 	uwsgi.shared->snmp_value[oid_num - 1].val = oid_val;
3649 
3650 	uwsgi_rwunlock(uwsgi.snmp_lock);
3651 	UWSGI_GET_GIL
3652 
3653 	Py_INCREF(Py_True);
3654 	return Py_True;
3655 
3656 clear:
3657 
3658 	Py_INCREF(Py_None);
3659 	return Py_None;
3660 }
3661 
py_snmp_incr_counter32(PyObject * self,PyObject * args)3662 PyObject *py_snmp_incr_counter32(PyObject * self, PyObject * args) {
3663 
3664 	uint8_t oid_num;
3665 	uint32_t oid_val = 1;
3666 
3667 	if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter32", &oid_num, &oid_val)) {
3668 		PyErr_Clear();
3669 		if (!PyArg_ParseTuple(args, "b:snmp_incr_counter32", &oid_num)) {
3670 			return NULL;
3671 		}
3672 	}
3673 
3674 	if (oid_num > 100 || oid_num < 1)
3675 		goto clear;
3676 
3677 	UWSGI_RELEASE_GIL
3678 	uwsgi_wlock(uwsgi.snmp_lock);
3679 
3680 	uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32;
3681 	uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val + oid_val;
3682 
3683 	uwsgi_rwunlock(uwsgi.snmp_lock);
3684 	UWSGI_GET_GIL
3685 
3686 	Py_INCREF(Py_True);
3687 	return Py_True;
3688 
3689 clear:
3690 
3691 	Py_INCREF(Py_None);
3692 	return Py_None;
3693 }
3694 
py_snmp_incr_counter64(PyObject * self,PyObject * args)3695 PyObject *py_snmp_incr_counter64(PyObject * self, PyObject * args) {
3696 
3697 	uint8_t oid_num;
3698 	uint64_t oid_val = 1;
3699 
3700 	if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter64", &oid_num, &oid_val)) {
3701 		PyErr_Clear();
3702 		if (!PyArg_ParseTuple(args, "b:snmp_incr_counter64", &oid_num)) {
3703 			return NULL;
3704 		}
3705 	}
3706 
3707 	if (oid_num > 100 || oid_num < 1)
3708 		goto clear;
3709 
3710 	UWSGI_RELEASE_GIL
3711 	uwsgi_wlock(uwsgi.snmp_lock);
3712 
3713 	uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64;
3714 	uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val + oid_val;
3715 
3716 	uwsgi_rwunlock(uwsgi.snmp_lock);
3717 	UWSGI_GET_GIL
3718 
3719 	Py_INCREF(Py_True);
3720 	return Py_True;
3721 
3722 clear:
3723 
3724 	Py_INCREF(Py_None);
3725 	return Py_None;
3726 }
3727 
py_snmp_incr_gauge(PyObject * self,PyObject * args)3728 PyObject *py_snmp_incr_gauge(PyObject * self, PyObject * args) {
3729 
3730 	uint8_t oid_num;
3731 	uint64_t oid_val = 1;
3732 
3733 	if (!PyArg_ParseTuple(args, "bI:snmp_incr_gauge", &oid_num, &oid_val)) {
3734 		PyErr_Clear();
3735 		if (!PyArg_ParseTuple(args, "b:snmp_incr_gauge", &oid_num)) {
3736 			return NULL;
3737 		}
3738 	}
3739 
3740 	if (oid_num > 100 || oid_num < 1)
3741 		goto clear;
3742 
3743 	UWSGI_RELEASE_GIL
3744 	uwsgi_wlock(uwsgi.snmp_lock);
3745 
3746 	uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE;
3747 	uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val + oid_val;
3748 
3749 	uwsgi_rwunlock(uwsgi.snmp_lock);
3750 	UWSGI_GET_GIL
3751 
3752 	Py_INCREF(Py_True);
3753 	return Py_True;
3754 
3755 clear:
3756 
3757 	Py_INCREF(Py_None);
3758 	return Py_None;
3759 }
3760 
py_snmp_decr_counter32(PyObject * self,PyObject * args)3761 PyObject *py_snmp_decr_counter32(PyObject * self, PyObject * args) {
3762 
3763 	uint8_t oid_num;
3764 	uint32_t oid_val = 1;
3765 
3766 	if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter32", &oid_num, &oid_val)) {
3767 		PyErr_Clear();
3768 		if (!PyArg_ParseTuple(args, "b:snmp_incr_counter32", &oid_num)) {
3769 			return NULL;
3770 		}
3771 	}
3772 
3773 	if (oid_num > 100 || oid_num < 1)
3774 		goto clear;
3775 
3776 	UWSGI_RELEASE_GIL
3777 	uwsgi_wlock(uwsgi.snmp_lock);
3778 
3779 	uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32;
3780 	uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val - oid_val;
3781 
3782 	uwsgi_rwunlock(uwsgi.snmp_lock);
3783 	UWSGI_GET_GIL
3784 
3785 	Py_INCREF(Py_True);
3786 	return Py_True;
3787 
3788 clear:
3789 
3790 	Py_INCREF(Py_None);
3791 	return Py_None;
3792 }
3793 
py_snmp_decr_counter64(PyObject * self,PyObject * args)3794 PyObject *py_snmp_decr_counter64(PyObject * self, PyObject * args) {
3795 
3796 	uint8_t oid_num;
3797 	uint64_t oid_val = 1;
3798 
3799 	if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter64", &oid_num, &oid_val)) {
3800 		PyErr_Clear();
3801 		if (!PyArg_ParseTuple(args, "b:snmp_incr_counter64", &oid_num)) {
3802 			return NULL;
3803 		}
3804 	}
3805 
3806 	if (oid_num > 100 || oid_num < 1)
3807 		goto clear;
3808 
3809 	UWSGI_RELEASE_GIL
3810 	uwsgi_wlock(uwsgi.snmp_lock);
3811 
3812 	uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64;
3813 	uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val - oid_val;
3814 
3815 	uwsgi_rwunlock(uwsgi.snmp_lock);
3816 	UWSGI_GET_GIL
3817 
3818 	Py_INCREF(Py_True);
3819 	return Py_True;
3820 
3821 clear:
3822 
3823 	Py_INCREF(Py_None);
3824 	return Py_None;
3825 }
3826 
py_snmp_decr_gauge(PyObject * self,PyObject * args)3827 static PyObject *py_snmp_decr_gauge(PyObject * self, PyObject * args) {
3828 
3829 	uint8_t oid_num;
3830 	uint64_t oid_val = 1;
3831 
3832 	if (!PyArg_ParseTuple(args, "bI:snmp_incr_gauge", &oid_num, &oid_val)) {
3833 		PyErr_Clear();
3834 		if (!PyArg_ParseTuple(args, "b:snmp_incr_gauge", &oid_num)) {
3835 			return NULL;
3836 		}
3837 	}
3838 
3839 	if (oid_num > 100 || oid_num < 1)
3840 		goto clear;
3841 
3842 	UWSGI_RELEASE_GIL
3843 	uwsgi_wlock(uwsgi.snmp_lock);
3844 
3845 	uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE;
3846 	uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val - oid_val;
3847 
3848 	uwsgi_rwunlock(uwsgi.snmp_lock);
3849 	UWSGI_GET_GIL
3850 
3851 	Py_INCREF(Py_True);
3852 	return Py_True;
3853 
3854 clear:
3855 
3856 	Py_INCREF(Py_None);
3857 	return Py_None;
3858 }
3859 
py_snmp_set_community(PyObject * self,PyObject * args)3860 static PyObject *py_snmp_set_community(PyObject * self, PyObject * args) {
3861 
3862         char *snmp_community;
3863 
3864         if (!PyArg_ParseTuple(args, "s:snmp_set_community", &snmp_community)) {
3865                 return NULL;
3866         }
3867 
3868         if (strlen(snmp_community) > 72) {
3869                 uwsgi_log( "*** warning the supplied SNMP community string will be truncated to 72 chars ***\n");
3870                 memcpy(uwsgi.shared->snmp_community, snmp_community, 72);
3871         }
3872         else {
3873                 memcpy(uwsgi.shared->snmp_community, snmp_community, strlen(snmp_community) + 1);
3874         }
3875 
3876         Py_INCREF(Py_True);
3877         return Py_True;
3878 
3879 }
3880 
3881 
3882 static PyMethodDef uwsgi_snmp_methods[] = {
3883         {"snmp_set_counter32", py_snmp_set_counter32, METH_VARARGS, ""},
3884         {"snmp_set_counter64", py_snmp_set_counter64, METH_VARARGS, ""},
3885         {"snmp_set_gauge", py_snmp_set_gauge, METH_VARARGS, ""},
3886         {"snmp_incr_counter32", py_snmp_incr_counter32, METH_VARARGS, ""},
3887         {"snmp_incr_counter64", py_snmp_incr_counter64, METH_VARARGS, ""},
3888         {"snmp_incr_gauge", py_snmp_incr_gauge, METH_VARARGS, ""},
3889         {"snmp_decr_counter32", py_snmp_decr_counter32, METH_VARARGS, ""},
3890         {"snmp_decr_counter64", py_snmp_decr_counter64, METH_VARARGS, ""},
3891         {"snmp_decr_gauge", py_snmp_decr_gauge, METH_VARARGS, ""},
3892         {"snmp_set_community", py_snmp_set_community, METH_VARARGS, ""},
3893         {NULL, NULL},
3894 };
3895 
init_uwsgi_module_snmp(PyObject * current_uwsgi_module)3896 void init_uwsgi_module_snmp(PyObject * current_uwsgi_module) {
3897 
3898         PyMethodDef *uwsgi_function;
3899 
3900 	PyObject *uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
3901         if (!uwsgi_module_dict) {
3902                 uwsgi_log("could not get uwsgi module __dict__\n");
3903                 exit(1);
3904         }
3905 
3906         for (uwsgi_function = uwsgi_snmp_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
3907                 PyObject *func = PyCFunction_New(uwsgi_function, NULL);
3908                 PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
3909                 Py_DECREF(func);
3910         }
3911 
3912         uwsgi_log( "SNMP python functions initialized.\n");
3913 }
3914