123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #include "pyutils.h"
-
- void pyinit()
- {
- update_python_path();
- Py_Initialize();
- }
-
- void update_python_path()
- {
- wchar_t *ppath, *wcwd, *wtmp;
- char *cwd, *ncwd, *err_fmt;
- size_t wcwd_sz, ppath_sz;
- int err;
-
- // Add a ':' in front of CWD and convert to wchar_t*
- cwd = get_current_dir_name();
- if(!cwd)
- {
- err = errno;
- err_fmt = "Unable to fecth CWD : %s";
- goto update_python_path_err;
- }
- ncwd = malloc(sizeof(char) * (strlen(cwd) + 2));
- if(!ncwd)
- {
- err = errno;
- err_fmt = "Unable to allocate memory for new CWD : %s";
- goto update_python_path_err_cwd;
- }
- ncwd[0] = ':';
- strcpy(ncwd+1, cwd);
- free(cwd);
- cwd = ncwd;
-
- wcwd_sz = mbstowcs(NULL, cwd, 0);
- if(wcwd_sz == (size_t)-1)
- {
- err = errno;
- err_fmt = "Unable to convert CWD to wchar : %s";
- goto update_python_path_err_cwd;
- }
- wcwd_sz++;
- wcwd = malloc(sizeof(wchar_t) * wcwd_sz);
- if(!wcwd)
- {
- err = errno;
- err_fmt = "Unable to allocate wchar for CWD : %s";
- goto update_python_path_err_cwd;
-
- }
- if(mbstowcs(wcwd, cwd, wcwd_sz) == -1)
- {
- err = errno;
- err_fmt = "Unable to convert CWD to wchar : %s";
- goto update_python_path_err_wcwd;
- }
-
- // Fetch, dup & update the python path
- ppath = Py_GetPath();
- if(!ppath)
- {
- if(PyErr_Occurred())
- {
- log_expt(LOG_ALERT);
- }
- else
- {
- pyfcgi_log(LOG_ALERT, "Unable to fetch python path, got NULL.");
- }
- err_fmt = NULL;
- err = 0;
- goto update_python_path_err_wcwd;
- }
- ppath = wcsdup(ppath);
- if(!wcwd)
- {
- err = errno;
- err_fmt = "Unable to dup the python PATH : %s";
- goto update_python_path_err_wcwd;
- }
-
- ppath_sz = wcslen(ppath);
- wtmp = realloc(ppath, sizeof(wchar_t) * (ppath_sz + wcwd_sz + 1));
- if(!wtmp)
- {
- err = errno;
- err_fmt = "Unable reallocate new python path : %s";
- goto update_python_path_err_ppath;
- }
- ppath = wtmp;
- wcsncpy(ppath+ppath_sz, wcwd, wcwd_sz);
- Py_SetPath(ppath);
-
- free(ppath);
- free(wcwd);
- free(cwd);
-
- return;
-
- update_python_path_err_ppath:
- free(ppath);
- update_python_path_err_wcwd:
- free(wcwd);
- update_python_path_err_cwd:
- free(cwd);
- update_python_path_err:
- if(err_fmt)
- {
- pyfcgi_log( LOG_ALERT, err_fmt, strerror(err));
- }
- exit(err);
- }
-
- PyObject* import_entrypoint()
- {
- PyObject *entry_fname, *entry_module, *entry_fun;
- entry_fname = PyUnicode_DecodeFSDefault(PyFCGI_conf.py_entrymod);
- entry_module = PyImport_Import(entry_fname);
- Py_DECREF(entry_fname);
-
- if(!entry_module)
- {
- //TODO syslog python error / traceback
- pyfcgi_log( LOG_CRIT,
- "Unable to import python file '%s'",
- PyFCGI_conf.py_entrymod);
- pyfcgi_log( LOG_INFO,
- "%s", getcwd(NULL, 256));
- log_expt(LOG_ERR);
- sleep(1);
- return NULL;
- }
-
- // getting entrypoint function
- entry_fun = PyObject_GetAttrString(entry_module, PyFCGI_conf.py_entryfun);
- Py_DECREF(entry_module);
-
- if(!entry_fun)
- {
- //TODO syslog python error / traceback
- pyfcgi_log( LOG_CRIT,
- "Unable to import object '%s' from '%s'",
- PyFCGI_conf.py_entryfun, PyFCGI_conf.py_entrymod);
- return NULL;
- }
- if(!PyCallable_Check(entry_fun))
- {
- pyfcgi_log( LOG_CRIT,
- "When imported from '%s', '%s' was not a callable",
- PyFCGI_conf.py_entrymod, PyFCGI_conf.py_entryfun);
- return NULL;
- }
- return entry_fun;
- }
-
- void log_expt(int priority)
- {
- if(!PyErr_Occurred())
- {
- pyfcgi_log(priority, "No exception");
- return;
- }
-
- PyObject *expt, *expt_str, *expt_bytes, *expt_cls,
- *expt_val, *expt_type, *traceback;
- char *msg, *type, *val;
- int msg_sz;
- char msg_fmt[] = "%s: %s";
-
- PyErr_Fetch(&expt_cls, &expt, &traceback);
-
- // Fetching exception message using __str__()
- expt_str = PyObject_GetAttrString(expt, "__str__");
- if(!expt_str)
- {
- pyfcgi_log(LOG_ERR, "Unable to fetch __str__ from exception");
- }
- expt_val = PyObject_CallObject(expt_str, NULL);
- expt_bytes = PyUnicode_AsUTF8String(expt_val);
-
- msg = PyBytes_AsString(expt_bytes);
- val = strndup(msg, 1024); // TODO check out of mem if !val
-
- // Fetching exception class name
- expt_type = PyObject_GetAttrString(expt_cls, "__name__");
- expt_bytes = PyUnicode_AsUTF8String(expt_type);
- msg = PyBytes_AsString(expt_bytes);
- type = strndup(msg, 1024); // TODO check out of mem if !type
-
- msg_sz = snprintf(NULL, 0, msg_fmt, type, val);
- msg_sz++;
- msg = malloc(sizeof(char) * msg_sz);
- snprintf(msg, msg_sz, msg_fmt, type, val);
-
- pyfcgi_log(priority, msg);
- }
-
- void pyfcgi_python_version(char version[16])
- {
- snprintf(version, 16, "%d.%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION,
- PY_MICRO_VERSION);
- }
|