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