Browse Source

Fixes #12 Using libpyfcgi.IoOut for stdout & stderr PEP333 workers

libpyfcgi.IoOut can be use for stdout & stderr for alternate workers too
Yann Weber 4 years ago
parent
commit
794324f494
5 changed files with 74 additions and 21 deletions
  1. 6
    1
      include/python_pyfcgi.h
  2. 2
    0
      include/pyutils.h
  3. 29
    4
      src/python_pyfcgi.c
  4. 26
    9
      src/pyutils.c
  5. 11
    7
      src/pyworker.c

+ 6
- 1
include/python_pyfcgi.h View File

63
 	 * @ingroup libpyfcgi */
63
 	 * @ingroup libpyfcgi */
64
 	PyObject *headers;
64
 	PyObject *headers;
65
 	/**@brief libpyfcgi.IoIn instance */
65
 	/**@brief libpyfcgi.IoIn instance */
66
-	IoIn *ioin;
66
+	PyIO_t *ioin;
67
+	/**@brief libpyfcgi.IoOut instances for stdout & stderr */
68
+	PyIO_t *stdio[2];
67
 	/**@brief Indicate if headers was sent in a PEP333 application
69
 	/**@brief Indicate if headers was sent in a PEP333 application
68
 	 * @ingroup libpyfcgi */
70
 	 * @ingroup libpyfcgi */
69
 	short headers_sent;
71
 	short headers_sent;
157
  */
159
  */
158
 PyObject* pyfcgi_write_body(PyObject*, PyObject**, Py_ssize_t);
160
 PyObject* pyfcgi_write_body(PyObject*, PyObject**, Py_ssize_t);
159
 
161
 
162
+int _libpyfcgi_stdout_write(const char*, size_t);
163
+int _libpyfcgi_stderr_write(const char*, size_t);
164
+
160
 #endif
165
 #endif

+ 2
- 0
include/pyutils.h View File

72
  * from PyFCGI_conf.py_entrymod & PyFCGI_conf.py_entryfun */
72
  * from PyFCGI_conf.py_entrymod & PyFCGI_conf.py_entryfun */
73
 PyObject* import_entrypoint();
73
 PyObject* import_entrypoint();
74
 
74
 
75
+/**@brief Init and return libpyfcgi */
76
+PyObject* pyinit_libpyfcgi();
75
 /**@brief Return the start_response() python function for pep333 worker */
77
 /**@brief Return the start_response() python function for pep333 worker */
76
 PyObject* get_start_response();
78
 PyObject* get_start_response();
77
 
79
 

+ 29
- 4
src/python_pyfcgi.c View File

21
 
21
 
22
 /* Globals definitions */
22
 /* Globals definitions */
23
 /* libpyfcgi context */
23
 /* libpyfcgi context */
24
-libpyfcgi_context_t libpyfcgi = { NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 };
24
+libpyfcgi_context_t libpyfcgi = { NULL, NULL, NULL, NULL, {NULL, NULL}, 0, NULL, NULL, 0 };
25
 /* Python module methods specs */
25
 /* Python module methods specs */
26
 /**@todo Add doc in last field */
26
 /**@todo Add doc in last field */
27
 PyMethodDef pyfcgimodule_methods[] = {
27
 PyMethodDef pyfcgimodule_methods[] = {
308
 	{
308
 	{
309
 		return NULL;
309
 		return NULL;
310
 	}
310
 	}
311
+	// init IoOut type
312
+	IoOutType.tp_new = PyType_GenericNew;
313
+	if(PyType_Ready(&IoOutType) < 0)
314
+	{
315
+		return NULL;
316
+	}
311
 
317
 
312
 	// init module & globals
318
 	// init module & globals
313
 	libpyfcgi.status = NULL;
319
 	libpyfcgi.status = NULL;
316
 	libpyfcgi.self = PyModule_Create(&pyfcgimodule);
322
 	libpyfcgi.self = PyModule_Create(&pyfcgimodule);
317
 	if(libpyfcgi.self == NULL) { return NULL; }
323
 	if(libpyfcgi.self == NULL) { return NULL; }
318
 
324
 
319
-	// Add type to module (optionnal)
325
+	// Add type to module
320
 	PyModule_AddObject(libpyfcgi.self, "IoIn", (PyObject*)&IoInType);
326
 	PyModule_AddObject(libpyfcgi.self, "IoIn", (PyObject*)&IoInType);
327
+	PyModule_AddObject(libpyfcgi.self, "IoOut", (PyObject*)&IoOutType);
321
 
328
 
322
 	// Create a new instance of IoIn
329
 	// Create a new instance of IoIn
323
-	libpyfcgi.ioin = (IoIn*)PyObject_CallObject((PyObject*)&IoInType, NULL);
330
+	libpyfcgi.ioin = (PyIO_t*)PyObject_CallObject((PyObject*)&IoInType, NULL);
324
 	Py_INCREF(libpyfcgi.ioin);
331
 	Py_INCREF(libpyfcgi.ioin);
325
 	if(!libpyfcgi.ioin)
332
 	if(!libpyfcgi.ioin)
326
 	{
333
 	{
327
 		return NULL;
334
 		return NULL;
328
 	}
335
 	}
329
-	libpyfcgi.ioin->in_stream = &libpyfcgi.in; // point on stream pointer
336
+	libpyfcgi.ioin->io_stream = &libpyfcgi.in; // point on stream pointer
330
 	libpyfcgi.ioin->bin = 1; // binary stream (bytes for python)
337
 	libpyfcgi.ioin->bin = 1; // binary stream (bytes for python)
331
 
338
 
339
+	// Add stdout & stderr
340
+pyfcgi_log(LOG_DEBUG, "libpyfcgi INIT0");
341
+	libpyfcgi.stdio[0] = (PyIO_t*)PyObject_CallObject((PyObject*)&IoOutType, NULL);
342
+pyfcgi_log(LOG_DEBUG, "libpyfcgi INIT1");
343
+	libpyfcgi.stdio[0]->write = _libpyfcgi_stdout_write;
344
+	libpyfcgi.stdio[1] = (PyIO_t*)PyObject_CallObject((PyObject*)&IoOutType, NULL);
345
+	libpyfcgi.stdio[1]->write = _libpyfcgi_stderr_write;
346
+
332
 	// Add it to wsgi dict
347
 	// Add it to wsgi dict
333
 	if(PyDict_SetItemString(PyFCGI_conf.context.wsgi_dict, "wsgi.input",
348
 	if(PyDict_SetItemString(PyFCGI_conf.context.wsgi_dict, "wsgi.input",
334
 		(PyObject*)libpyfcgi.ioin))
349
 		(PyObject*)libpyfcgi.ioin))
542
 	}
557
 	}
543
 }
558
 }
544
 
559
 
560
+int _libpyfcgi_stdout_write(const char* buff, size_t sz)
561
+{
562
+	pyfcgi_log(LOG_INFO, "stdout : '%s'", buff);
563
+	return 1;
564
+}
565
+int _libpyfcgi_stderr_write(const char* buff, size_t sz)
566
+{
567
+	pyfcgi_log(LOG_ERR, "stderr : '%s'", buff);
568
+	return 1;
569
+}

+ 26
- 9
src/pyutils.c View File

434
 	return entry_fun;
434
 	return entry_fun;
435
 }
435
 }
436
 
436
 
437
-PyObject* get_start_response()
437
+PyObject* pyinit_libpyfcgi()
438
 {
438
 {
439
 	PyObject *module;
439
 	PyObject *module;
440
-	if(!libpyfcgi.self)
440
+	if(libpyfcgi.self) { return libpyfcgi.self; }
441
+
442
+	module = PyInit_libpyfcgi();
443
+	if(module == NULL)
441
 	{
444
 	{
442
-		module = PyInit_libpyfcgi();
443
-		if(module == NULL)
444
-		{
445
-			pyfcgi_log(LOG_ERR, "Unable to create libpyfcgi python module");
446
-			return NULL;
447
-		}
448
-		libpyfcgi.self = module;
445
+		pyfcgi_log(LOG_ERR, "Unable to create libpyfcgi python module");
446
+		return NULL;
447
+	}
448
+	libpyfcgi.self = module;
449
+	if(PySys_SetObject("stdout", (PyObject*)libpyfcgi.stdio[0]))
450
+	{
451
+		pyfcgi_log(LOG_ERR, "Unable to set sys.stdout");
452
+		log_expt(LOG_ALERT);
453
+		return NULL;
449
 	}
454
 	}
455
+	if(PySys_SetObject("stderr", (PyObject*)libpyfcgi.stdio[1]))
456
+	{
457
+		pyfcgi_log(LOG_ERR, "Unable to set sys.stderr");
458
+		log_expt(LOG_ALERT);
459
+		return NULL;
460
+	}
461
+	return module;
462
+}
463
+
464
+PyObject* get_start_response()
465
+{
466
+	pyinit_libpyfcgi();
450
 	return PyObject_GetAttrString(libpyfcgi.self, "start_response");
467
 	return PyObject_GetAttrString(libpyfcgi.self, "start_response");
451
 }
468
 }
452
 
469
 

+ 11
- 7
src/pyworker.c View File

39
 
39
 
40
 int work333(int wrk_id)
40
 int work333(int wrk_id)
41
 {
41
 {
42
-	PyObject *entry_fun, *pyflush[2], *py_osmod, *entry_ret, *environ,
42
+	PyObject *entry_fun, *py_osmod, *entry_ret, *environ,
43
 		*start_response, *args;
43
 		*start_response, *args;
44
 	FCGX_Stream *in_stream, *out_stream, *err_stream;
44
 	FCGX_Stream *in_stream, *out_stream, *err_stream;
45
 	char **envp;
45
 	char **envp;
46
-	int count, pipe_out[2], pipe_err[2];
46
+	int count;
47
 	int max_reqs;
47
 	int max_reqs;
48
 	struct timeval start, stop;
48
 	struct timeval start, stop;
49
 	FCGX_Request *request;
49
 	FCGX_Request *request;
54
 
54
 
55
 	pyinit();
55
 	pyinit();
56
 	pyfcgi_log(LOG_DEBUG, "Python started");
56
 	pyfcgi_log(LOG_DEBUG, "Python started");
57
-	update_python_fd(pipe_out, pipe_err);
58
-	fetch_pyflush(&(pyflush[0]), &(pyflush[1]));
59
-
60
 	//importing os
57
 	//importing os
61
 	py_osmod = python_osmod();
58
 	py_osmod = python_osmod();
59
+	pyfcgi_log(LOG_DEBUG, "Python OSMOD");
60
+	//importing libpyfcgi
61
+	if(!pyinit_libpyfcgi())
62
+	{
63
+		exit(PYFCGI_FATAL);
64
+	}
65
+	pyfcgi_log(LOG_DEBUG, "libpyfcgi imported");
66
+
67
+
62
 	// loading module
68
 	// loading module
63
 	entry_fun = import_entrypoint();
69
 	entry_fun = import_entrypoint();
64
 
70
 
146
 		// clean stuffs
152
 		// clean stuffs
147
 		Py_DECREF(args);
153
 		Py_DECREF(args);
148
 		Py_DECREF(environ);
154
 		Py_DECREF(environ);
149
-		// flush & logs pystdout & pystderr
150
-		worker_log_pipes(pipe_out[0], pipe_err[0], pyflush);
151
 
155
 
152
 		FCGX_FClose(out_stream);
156
 		FCGX_FClose(out_stream);
153
 		FCGX_FClose(in_stream);
157
 		FCGX_FClose(in_stream);

Loading…
Cancel
Save