int CPython::ExecCmds(const std::wstring &cmds, std::wstring &err, HANDLE hfile) { int id = 0; FILE *pfile = nullptr; DWORD count = 0; PyObject *poldout, *polderr, *pnewout, *pnewerr; if (cmds.length() <= 0) { err = text("No python command found"); return 1; } if (DuplicateHandle ( GetCurrentProcess(), hfile, GetCurrentProcess(), &hfile, 0, false, DUPLICATE_SAME_ACCESS )) { id = open_osfhandle((intptr_t)hfile, _O_WRONLY); pfile = fdopen(id,"w"); setvbuf(pfile,nullptr,_IONBF,1024); poldout = PySys_GetObject("stdout"); polderr = PySys_GetObject("stderr"); pnewout = PyFile_FromFile(pfile, "logger", "w", nullptr); pnewerr = PyFile_FromFile(pfile, "logger", "w", nullptr); PySys_SetObject("stdout", pnewout); PySys_SetObject("stderr", pnewerr); } else poldout = polderr = pnewout = pnewerr = nullptr; std::wstring_convert<std::codecvt_utf8_utf16<wchar>> cvt; std::string str = cvt.to_bytes(cmds); int irslt = PyRun_SimpleString(str.c_str()); if (irslt != 0) err = text("Internal error that PyRun_SimpleString fail"); else err = text("Execute python commands successfully .."); if (pnewout != nullptr) PySys_SetObject("stdout", poldout); if (pnewerr != nullptr) PySys_SetObject("stderr", polderr); if (pfile != nullptr) fclose(pfile); return irslt; }
int CPython::ExecFile(const std::vector<std::wstring> &argv, std::wstring &err, HANDLE hfile) { int id = 0; FILE *pfile = nullptr; DWORD count = 0; PyObject *poldout, *polderr, *pnewout, *pnewerr; if (argv.size() <= 0) { err = text("No python script file found"); return 1; } if (DuplicateHandle ( GetCurrentProcess(), hfile, GetCurrentProcess(), &hfile, 0, false, DUPLICATE_SAME_ACCESS )) { id = open_osfhandle((intptr_t)hfile, _O_WRONLY); pfile = fdopen(id,"w"); setvbuf(pfile,nullptr,_IONBF,1024); poldout = PySys_GetObject("stdout"); polderr = PySys_GetObject("stderr"); pnewout = PyFile_FromFile(pfile, "logger", "w", nullptr); pnewerr = PyFile_FromFile(pfile, "logger", "w", nullptr); PySys_SetObject("stdout", pnewout); PySys_SetObject("stderr", pnewerr); } else poldout = polderr = pnewout = pnewerr = nullptr; // Pack up the arguments .. std::vector<char*> args; int irslt = 0; std::vector<std::wstring>::const_iterator itr, eitr; std::wstring_convert<std::codecvt_utf8_utf16<wchar>> cvt; itr = argv.cbegin(); eitr = argv.cend(); for (size_t len = 0; itr != eitr; ++itr) { // Allocate buffer each time, not good .. std::string str = cvt.to_bytes(*itr); len = str.length(); char *arg = new char[len+1]; strncpy_s(arg,len+1,str.data(),len); arg[len] = '\0'; args.push_back(arg); } PySys_SetArgv(args.size(), args.data()); // pass args . PyObject *pobj = PyFile_FromString(args.at(0), "r"); if (pobj == nullptr) { err = text("Internal error that PyFile_FromString fail"); irslt = -1; } else { PyRun_SimpleFileEx(PyFile_AsFile(pobj), args.at(0), true); err = text("Execute python script file successfully .."); irslt = 00; } // Free resource ... std::vector<char*>::iterator sitr, seitr; sitr = args.begin(); seitr = args.end(); for (sitr; sitr != seitr; ++sitr) { if (*sitr) delete [] *sitr; } args.clear(); if (pnewout != nullptr) PySys_SetObject("stdout", poldout); if (pnewerr != nullptr) PySys_SetObject("stderr", polderr); if (pfile != nullptr) fclose(pfile); return irslt; }
int CPython::ExecFunc(const std::vector<std::wstring> &argv, std::wstring &err, HANDLE hfile) { std::vector<std::wstring>::const_iterator itr, eitr; itr = argv.cbegin(); eitr = argv.cend(); err = *itr; if (argv.size() <= 0) { err = text("No python command function found"); return 1; } err.push_back(text('(')); for (++itr; itr != eitr; ++itr) { err.append(*itr); err.push_back(text(',')); } if (err.back() == text(',')) err.pop_back(); err.push_back(text(')')); Addtolist(1,1,text("Execute Function: %s"),err.c_str()); int id = 0; FILE *pfile = nullptr; DWORD count = 0; PyObject *poldout, *polderr, *pnewout, *pnewerr; if (DuplicateHandle ( GetCurrentProcess(), hfile, GetCurrentProcess(), &hfile, 0, false, DUPLICATE_SAME_ACCESS )) { id = open_osfhandle((intptr_t)hfile, _O_WRONLY); pfile = fdopen(id,"w"); setvbuf(pfile,nullptr,_IONBF,1024); poldout = PySys_GetObject("stdout"); polderr = PySys_GetObject("stderr"); pnewout = PyFile_FromFile(pfile, "logger", "w", nullptr); pnewerr = PyFile_FromFile(pfile, "logger", "w", nullptr); PySys_SetObject("stdout", pnewout); PySys_SetObject("stderr", pnewerr); } else poldout = polderr = pnewout = pnewerr = nullptr; std::wstring_convert<std::codecvt_utf8_utf16<wchar>> cvt; std::string str = cvt.to_bytes(err); std::size_t pos = str.find(text('.')); if (pos != std::string::npos) { std::string mod = str.substr(0, pos); PyObject* dest = PyImport_ImportModule(mod.c_str()); PyObject* main = PyImport_AddModule("__main__"); PyObject_SetAttrString(main, mod.c_str(), dest); } str.insert(0, "print "); int irslt = PyRun_SimpleString(str.c_str()); if (irslt != 0) err = text("Internal error that PyRun_SimpleString fail"); else err = text("Execute python function successfully .."); if (pnewout != nullptr) PySys_SetObject("stdout", poldout); if (pnewerr != nullptr) PySys_SetObject("stderr", polderr); if (pfile != nullptr) fclose(pfile); return irslt; }
static PyObject* PySemsAudioFile_exportRaw(PySemsAudioFile* self, PyObject*) { if(self->af->getMode() == AmAudioFile::Write) self->af->on_close(); self->af->rewind(); return PyFile_FromFile(self->af->getfp(),"","rwb",NULL); }
object MakeFile() { FILE* fp = pcap_dump_file( mFileHandle ); if( fp == NULL ) { PyErr_SetString( PyExc_Exception, "Can't make file." ); throw_error_already_set(); } PyObject* o = PyFile_FromFile( fp, "savefile", "wb", fclose ); return object(borrowed(o)); }
void write_label(FILE *fp, LABEL y) { /* Writes label y to file handle fp. */ PyObject *pFunc, *pValue, *pArgs; // Call the relevant Python function. pFunc = getFunction(PYTHON_WRITE_LABEL); pArgs = Py_BuildValue ("NO", PyFile_FromFile(fp, "foobar", "w", dummy_file_closer), y.py_y); pValue = PyObject_CallObject(pFunc, pArgs); Py_DECREF(pArgs); PY_RUNCHECK; Py_DECREF(pValue); }
int CPython::ExecEcho(const std::wstring &cmds, std::wstring &err, HANDLE hfile) { int id = 0; FILE *pfile = nullptr; DWORD count = 0; PyObject *poldout, *polderr, *pnewout, *pnewerr; if (cmds.length() <= 0) { err = text("No python command found"); return 1; } if (DuplicateHandle ( GetCurrentProcess(), hfile, GetCurrentProcess(), &hfile, 0, false, DUPLICATE_SAME_ACCESS )) { id = open_osfhandle((intptr_t)hfile, _O_WRONLY); pfile = fdopen(id,"w"); setvbuf(pfile,nullptr,_IONBF,1024); poldout = PySys_GetObject("stdout"); polderr = PySys_GetObject("stderr"); pnewout = PyFile_FromFile(pfile, "logger", "w", nullptr); pnewerr = PyFile_FromFile(pfile, "logger", "w", nullptr); PySys_SetObject("stdout", pnewout); PySys_SetObject("stderr", pnewerr); } else poldout = polderr = pnewout = pnewerr = nullptr; std::wstring_convert<std::codecvt_utf8_utf16<wchar>> cvt; std::string str = cvt.to_bytes(cmds); std::size_t pos = str.find(text('.')); if (pos != std::string::npos) { std::string mod = str.substr(0, pos); PyObject* dest = PyImport_ImportModule(mod.c_str()); PyObject* main = PyImport_AddModule("__main__"); PyObject_SetAttrString(main, mod.c_str(), dest); } str.insert(0, "print "); int irslt = PyRun_SimpleString(str.c_str()); if (irslt != 0) err = text("Internal error that PyRun_SimpleString fail"); else err = text("Execute python expression successfully .."); if (pnewout != nullptr) PySys_SetObject("stdout", poldout); if (pnewerr != nullptr) PySys_SetObject("stderr", polderr); if (pfile != nullptr) fclose(pfile); return irslt; }
/** * Creates a Message instance with default values. * To modify those values, use the corresponding functions. * * \param module the module to debug. If you don't know, set "layman" * \param out where to write info * \param err where to write errors * \param dbg where to write debug information * * \return a new instance of a Message object. It must be freed with messageFree() */ Message *messageCreate(const char* module, FILE* out, FILE* err, FILE* dbg) { PyObject *pyout, *pyerr, *pydbg; if (!out || fileno(out) <= 0) out = stdout; if (!err || fileno(err) <= 0) err = stderr; if (!dbg || fileno(dbg) <= 0) dbg = stderr; pyout = PyFile_FromFile(out, "", "w", 0); pyerr = PyFile_FromFile(err, "", "w", 0); pydbg = PyFile_FromFile(dbg, "", "w", 0); PyObject *object = executeFunction("layman.debug", "Message", "(sOOO)", module, pyout, pyerr, pydbg); Py_DECREF(pyout); Py_DECREF(pyerr); Py_DECREF(pydbg); if (!object) return NULL; Message *ret = malloc(sizeof(Message)); ret->object = object; return ret; }
PyObject * PyFile_FromString(char *name, char *mode) { extern int fclose(FILE *); PyFileObject *f; f = (PyFileObject *)PyFile_FromFile((FILE *)NULL, name, mode, fclose); if (f != NULL) { if (open_the_file(f, name, mode) == NULL) { Py_DECREF(f); f = NULL; } } return (PyObject *)f; }
static void xmlsec_KeyDataDebugDumpMethod(xmlSecKeyDataPtr data, FILE *output) { PyObject *args, *result; PyObject *func = NULL; func = xmlHashLookup(KeyDataDebugDumpMethods, data->id->name); args = Py_BuildValue((char *) "OO", wrap_xmlSecKeyDataPtr(data), PyFile_FromFile(output, NULL, NULL, NULL)); Py_INCREF(func); result = PyEval_CallObject(func, args); Py_DECREF(func); Py_DECREF(args); Py_XDECREF(result); }
static PyObject * p_cgi_filehandle (PyObject *self, PyObject *args) { CGI *cgi = ((CGIObject *) self)->cgi; char *name; FILE *fp; if (!PyArg_ParseTuple(args, "s:filehandle(form_name)", &name)) return NULL; fp = cgi_filehandle (cgi, name); if (fp == NULL) { Py_INCREF(Py_None); return Py_None; } return PyFile_FromFile (fp, name, "w+", NULL); }
static PyObject *boinc_boinc_fopen(PyObject *self, PyObject *args) { char *name; char *mode; if (!PyArg_ParseTuple(args, "ss", &name, &mode)) return NULL; FILE *fp; PyObject *object; fp = boinc_fopen(name, mode); object = PyFile_FromFile(fp, name, mode, fclose); Py_INCREF(object); return object; }
static void xmlsec_PtrDebugXmlDumpItemMethod(xmlSecPtr ptr, FILE *output) { xmlSecPtrListPtr list; PyObject *args, *result; PyObject *func = NULL; list = (xmlSecPtrListPtr) ptr; func = xmlHashLookup(PtrDebugXmlDumpItemMethods, list->id->name); /* FIXME */ args = Py_BuildValue((char *) "OO", wrap_xmlSecPtr(ptr), PyFile_FromFile(output, NULL, NULL, NULL)); /* Protect refcount against reentrant manipulation of callback hash */ Py_INCREF(func); result = PyEval_CallObject(func, args); Py_DECREF(func); Py_DECREF(args); Py_XDECREF(result); }
static PyObject * py_univention_debug_init(PyObject *self, PyObject *args) { char *logfile; int flush, function; FILE * fd; PyObject * file; if (!PyArg_ParseTuple(args, "sii", &logfile, &flush, &function)) { Py_RETURN_NONE; } fd = univention_debug_init(logfile, (char)flush, (char)function); if ( fd == NULL ) { Py_RETURN_NONE; } file = PyFile_FromFile( fd, logfile, "a+", NULL ); return file; }
static int fp_setreadl(struct tok_state *tok, const char* enc) { PyObject *reader, *stream, *readline; /* XXX: constify filename argument. */ stream = PyFile_FromFile(tok->fp, (char*)tok->filename, "rb", NULL); if (stream == NULL) return 0; reader = PyCodec_StreamReader(enc, stream, NULL); Py_DECREF(stream); if (reader == NULL) return 0; readline = PyObject_GetAttrString(reader, "readline"); Py_DECREF(reader); if (readline == NULL) return 0; tok->decoding_readline = readline; return 1; }
static PyObject* cdrom_open(PyObject *self, PyObject *args) { int cdrom_fd; FILE *cdrom_file; char *cdrom_device = CDDB_DEFAULT_CDROM_DEVICE; int cdrom_open_flags = CDDB_DEFAULT_CDROM_FLAGS; PyObject *cdrom_file_object; if (!PyArg_ParseTuple(args, "|si", &cdrom_device, &cdrom_open_flags)) return NULL; cdrom_fd = open(cdrom_device, cdrom_open_flags); if (cdrom_fd == -1) { PyErr_SetFromErrno(cdrom_error); return NULL; } cdrom_file = fdopen(cdrom_fd, "r"); if (cdrom_file == NULL) { PyErr_SetFromErrno(cdrom_error); return NULL; } cdrom_file_object = PyFile_FromFile(cdrom_file, cdrom_device, "r", cdrom_close); if (cdrom_file_object == NULL) { PyErr_SetString(cdrom_error, "Internal conversion from file pointer to Python object failed"); fclose(cdrom_file); return NULL; } return Py_BuildValue("O", cdrom_file_object); }
void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) { PyObject *zero; int i; PyObject *pydictkey, *pydictvalue; char *path_info; for (i = 0; i < wsgi_req->var_cnt; i += 2) { #ifdef UWSGI_DEBUG uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base); #endif #ifdef PYTHREE pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL); pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL); #else pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len); pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len); #endif #ifdef UWSGI_DEBUG uwsgi_log("%p %d %p %d\n", pydictkey, wsgi_req->hvec[i].iov_len, pydictvalue, wsgi_req->hvec[i + 1].iov_len); #endif PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue); Py_DECREF(pydictkey); Py_DECREF(pydictvalue); } if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) { wsgi_req->uh.modifier1 = 0; pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME"); if (pydictkey) { if (PyString_Check(pydictkey)) { pydictvalue = PyDict_GetItemString(wsgi_req->async_environ, "PATH_INFO"); if (pydictvalue) { if (PyString_Check(pydictvalue)) { path_info = PyString_AsString(pydictvalue); PyDict_SetItemString(wsgi_req->async_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey))); } } } } } // if async_post is mapped as a file, directly use it as wsgi.input if (wsgi_req->async_post) { #ifdef PYTHREE wsgi_req->async_input = PyFile_FromFd(fileno((FILE *)wsgi_req->async_post), "wsgi_input", "rb", 0, NULL, NULL, NULL, 0); #else wsgi_req->async_input = PyFile_FromFile(wsgi_req->async_post, "wsgi_input", "r", NULL); #endif } else { // create wsgi.input custom object wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; ((uwsgi_Input*)wsgi_req->async_input)->pos = 0; ((uwsgi_Input*)wsgi_req->async_input)->readline_pos = 0; ((uwsgi_Input*)wsgi_req->async_input)->readline_max_size = 0; } PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input); #ifdef UWSGI_SENDFILE PyDict_SetItemString(wsgi_req->async_environ, "wsgi.file_wrapper", wi->sendfile); #endif #ifdef UWSGI_ASYNC if (uwsgi.async > 1) { PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.readable", wi->eventfd_read); PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.writable", wi->eventfd_write); PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.timeout", Py_None); } #endif PyDict_SetItemString(wsgi_req->async_environ, "wsgi.version", wi->gateway_version); zero = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL); PyDict_SetItemString(wsgi_req->async_environ, "wsgi.errors", zero); Py_DECREF(zero); PyDict_SetItemString(wsgi_req->async_environ, "wsgi.run_once", Py_False); if (uwsgi.threads > 1) { PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multithread", Py_True); } else { PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multithread", Py_False); } if (uwsgi.numproc == 1) { PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multiprocess", Py_False); } else { PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multiprocess", Py_True); } if (wsgi_req->scheme_len > 0) { zero = UWSGI_PYFROMSTRINGSIZE(wsgi_req->scheme, wsgi_req->scheme_len); } else if (wsgi_req->https_len > 0) { if (!strncasecmp(wsgi_req->https, "on", 2) || wsgi_req->https[0] == '1') { zero = UWSGI_PYFROMSTRING("https"); } else { zero = UWSGI_PYFROMSTRING("http"); } } else { zero = UWSGI_PYFROMSTRING("http"); } PyDict_SetItemString(wsgi_req->async_environ, "wsgi.url_scheme", zero); Py_DECREF(zero); wsgi_req->async_app = wi->callable; // export .env only in non-threaded mode if (uwsgi.threads < 2) { PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ); } PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version); if (uwsgi.cores > 1) { zero = PyInt_FromLong(wsgi_req->async_id); PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", zero); Py_DECREF(zero); } // cache this ? if (uwsgi.cluster_fd >= 0) { zero = PyString_FromString(uwsgi.cluster); PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster", zero); Py_DECREF(zero); zero = PyString_FromString(uwsgi.hostname); PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster_node", zero); Py_DECREF(zero); } PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node); // call PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ); return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req); }
int main(int argc, char *argv[]) { sys_argc = argc; sys_argv = argv; origPid = getpid(); #ifdef __APPLE__ extern void install_breakpoint_handlers(); install_breakpoint_handlers(); #endif forkExecProc = haveArg("--forkExecProc"); bool shell = haveArg("--shell"); bool pyShell = haveArg("--pyshell"); bool pyExec = haveArg("--pyexec"); bool noLog = haveArg("--nolog"); bool help = haveArg("--help") || haveArg("-h"); bool beingDebugged = AmIBeingDebugged(); const char* logDisabledReason = NULL; if(pyShell || pyExec || shell || forkExecProc || help) {} // be quiet else if(beingDebugged) { logDisabledReason = "debugger detected, not redirecting stdout/stderr"; } else if(noLog) { logDisabledReason = "not redirecting stdout/stderr"; } else { // current workaround to log stdout/stderr. see http://stackoverflow.com/questions/13104588/how-to-get-stdout-into-console-app logEnabled = true; printf("MusicPlayer: stdout/stderr goes to %s now\n", logFilename.c_str()); fflush(stdout); int newFd = open(getTildeExpandedPath(logFilename).c_str(), O_WRONLY|O_APPEND|O_CREAT); dup2(newFd, fileno(stdout)); dup2(newFd, fileno(stderr)); close(newFd); //freopen(logFilename.c_str(), "a", stdout); //freopen(logFilename.c_str(), "a", stderr); stderr = stdout; // well, hack, ... I don't like two seperate buffers. just messes up the output } if(!forkExecProc) { printf("%s", StartupStr); install_signal_handler(); } if(help) { printf( "Help: Available options:\n" " --nolog : don't redirect stdout/stderr to log. also implied when run in debugger\n" ); } if(!logEnabled && logDisabledReason) printf("%s\n", logDisabledReason); std::string mainPyFilename = getResourcePath() + "/Python/main.py"; Py_SetProgramName(argv[0]); if(!forkExecProc) printf("Python version: %s, prefix: %s, main: %s\n", Py_GetVersion(), Py_GetPrefix(), mainPyFilename.c_str()); Py_Initialize(); PyEval_InitThreads(); addPyPath(); if(logEnabled) { PySys_SetObject((char*)"stdout", PyFile_FromFile(stdout, (char*)"<stdout>", (char*)"w", fclose)); PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"stdout")); } PySys_SetObject((char*)"MusicPlayerBin", PyString_FromString(argv[0])); // Preload imp and thread. I hope to fix this bug: https://github.com/albertz/music-player/issues/8 , there was a crash in initthread which itself has called initimp PyObject* m = NULL; m = PyImport_ImportModule("imp"); Py_XDECREF(m); m = PyImport_ImportModule("thread"); Py_XDECREF(m); PySys_SetArgvEx(argc, argv, 0); FILE* fp = fopen((char*)mainPyFilename.c_str(), "r"); if(fp) PyRun_SimpleFile(fp, "main.py"); else printf("Could not open main.py!\n"); if(!forkExecProc && !help && !pyShell && !pyExec && !shell) { bool successStartup = checkStartupSuccess(); if(!successStartup) { printf("Error at startup.\n"); handleFatalError("There was an error at startup."); } } return 0; }
int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThreadState *interpreter, int app_type) { PyObject *app_list = NULL, *applications = NULL; if (uwsgi_apps_cnt >= uwsgi.max_apps) { uwsgi_log("ERROR: you cannot load more than %d apps in a worker\n", uwsgi.max_apps); return -1; } int id = uwsgi_apps_cnt; int multiapp = 0; int i; struct uwsgi_app *wi; time_t now = uwsgi_now(); if (uwsgi_get_app_id(NULL, wsgi_req->appid, wsgi_req->appid_len, -1) != -1) { uwsgi_log( "mountpoint %.*s already configured. skip.\n", wsgi_req->appid_len, wsgi_req->appid); return -1; } wi = &uwsgi_apps[id]; memset(wi, 0, sizeof(struct uwsgi_app)); wi->mountpoint_len = wsgi_req->appid_len < 0xff ? wsgi_req->appid_len : (0xff-1); strncpy(wi->mountpoint, wsgi_req->appid, wi->mountpoint_len); // dynamic chdir ? if (wsgi_req->chdir_len > 0) { strncpy(wi->chdir, wsgi_req->chdir, wsgi_req->chdir_len < 0xff ? wsgi_req->chdir_len : (0xff-1)); #ifdef UWSGI_DEBUG uwsgi_debug("chdir to %s\n", wi->chdir); #endif if (chdir(wi->chdir)) { uwsgi_error("chdir()"); } } // Initialize a new environment for the new interpreter // reload "os" environ to allow dynamic setenv() if (up.reload_os_env) { char **e, *p; PyObject *k, *env_value; PyObject *os_module = PyImport_ImportModule("os"); if (os_module) { PyObject *os_module_dict = PyModule_GetDict(os_module); PyObject *py_environ = PyDict_GetItemString(os_module_dict, "environ"); if (py_environ) { for (e = environ; *e != NULL; e++) { p = strchr(*e, '='); if (p == NULL) continue; k = PyString_FromStringAndSize(*e, (int)(p-*e)); if (k == NULL) { PyErr_Print(); continue; } env_value = PyString_FromString(p+1); if (env_value == NULL) { PyErr_Print(); Py_DECREF(k); continue; } #ifdef UWSGI_DEBUG uwsgi_log("%s = %s\n", PyString_AsString(k), PyString_AsString(env_value)); #endif if (PyObject_SetItem(py_environ, k, env_value)) { PyErr_Print(); } Py_DECREF(k); Py_DECREF(env_value); } } } } if (interpreter == NULL && id) { wi->interpreter = Py_NewInterpreter(); if (!wi->interpreter) { uwsgi_log( "unable to initialize the new python interpreter\n"); exit(1); } PyThreadState_Swap(wi->interpreter); init_pyargv(); // we need to inizialize an embedded module for every interpreter init_uwsgi_embedded_module(); init_uwsgi_vars(); } else if (interpreter) { wi->interpreter = interpreter; } else { wi->interpreter = up.main_thread; } if (wsgi_req->home_len) { set_dyn_pyhome(wsgi_req->home, wsgi_req->home_len); } if (wsgi_req->touch_reload_len > 0 && wsgi_req->touch_reload_len < 0xff) { struct stat trst; strncpy(wi->touch_reload, wsgi_req->touch_reload, wsgi_req->touch_reload_len); if (!stat(wi->touch_reload, &trst)) { wi->touch_reload_mtime = trst.st_mtime; } } wi->callable = up.loaders[loader](arg1); if (!wi->callable) { uwsgi_log("unable to load app %d (mountpoint='%s') (callable not found or import error)\n", id, wi->mountpoint); goto doh; } // the module contains multiple apps if (PyDict_Check((PyObject *)wi->callable)) { applications = wi->callable; uwsgi_log("found a multiapp module...\n"); app_list = PyDict_Keys(applications); multiapp = PyList_Size(app_list); if (multiapp < 1) { uwsgi_log("you have to define at least one app in the apllications dictionary\n"); goto doh; } PyObject *app_mnt = PyList_GetItem(app_list, 0); if (!PyString_Check(app_mnt)) { uwsgi_log("the app mountpoint must be a string\n"); goto doh; } char *tmp_mountpoint = PyString_AsString(app_mnt); wi->mountpoint_len = strlen(wi->mountpoint) < 0xff ? strlen(wi->mountpoint) : (0xff-1); strncpy(wi->mountpoint, tmp_mountpoint, wi->mountpoint_len); wsgi_req->appid = wi->mountpoint; wsgi_req->appid_len = wi->mountpoint_len; #ifdef UWSGI_DEBUG uwsgi_log("main mountpoint = %s\n", wi->mountpoint); #endif wi->callable = PyDict_GetItem(applications, app_mnt); if (PyString_Check((PyObject *) wi->callable)) { PyObject *callables_dict = get_uwsgi_pydict((char *)arg1); if (callables_dict) { wi->callable = PyDict_GetItem(callables_dict, (PyObject *)wi->callable); } } } Py_INCREF((PyObject *)wi->callable); wi->environ = malloc(sizeof(PyObject*)*uwsgi.cores); if (!wi->environ) { uwsgi_error("malloc()"); exit(1); } for(i=0;i<uwsgi.cores;i++) { wi->environ[i] = PyDict_New(); if (!wi->environ[i]) { uwsgi_log("unable to allocate new env dictionary for app\n"); exit(1); } } wi->argc = 1; if (app_type == PYTHON_APP_TYPE_WSGI) { #ifdef UWSGI_DEBUG uwsgi_log("-- WSGI callable selected --\n"); #endif wi->request_subhandler = uwsgi_request_subhandler_wsgi; wi->response_subhandler = uwsgi_response_subhandler_wsgi; wi->argc = 2; } else if (app_type == PYTHON_APP_TYPE_WEB3) { #ifdef UWSGI_DEBUG uwsgi_log("-- Web3 callable selected --\n"); #endif wi->request_subhandler = uwsgi_request_subhandler_web3; wi->response_subhandler = uwsgi_response_subhandler_web3; } else if (app_type == PYTHON_APP_TYPE_PUMP) { #ifdef UWSGI_DEBUG uwsgi_log("-- Pump callable selected --\n"); #endif wi->request_subhandler = uwsgi_request_subhandler_pump; wi->response_subhandler = uwsgi_response_subhandler_pump; } wi->args = malloc(sizeof(PyObject*)*uwsgi.cores); if (!wi->args) { uwsgi_error("malloc()"); exit(1); } for(i=0;i<uwsgi.cores;i++) { wi->args[i] = PyTuple_New(wi->argc); if (!wi->args[i]) { uwsgi_log("unable to allocate new tuple for app args\n"); exit(1); } // add start_response on WSGI app Py_INCREF((PyObject *)up.wsgi_spitout); if (app_type == PYTHON_APP_TYPE_WSGI) { if (PyTuple_SetItem(wi->args[i], 1, up.wsgi_spitout)) { uwsgi_log("unable to set start_response in args tuple\n"); exit(1); } } } if (app_type == PYTHON_APP_TYPE_WSGI) { // prepare sendfile() for WSGI app wi->sendfile = PyCFunction_New(uwsgi_sendfile_method, NULL); wi->eventfd_read = PyCFunction_New(uwsgi_eventfd_read_method, NULL); wi->eventfd_write = PyCFunction_New(uwsgi_eventfd_write_method, NULL); } // cache most used values wi->error = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL); Py_INCREF((PyObject *)wi->error); wi->gateway_version = PyTuple_New(2); PyTuple_SetItem(wi->gateway_version, 0, PyInt_FromLong(1)); PyTuple_SetItem(wi->gateway_version, 1, PyInt_FromLong(0)); Py_INCREF((PyObject *)wi->gateway_version); wi->uwsgi_version = PyString_FromString(UWSGI_VERSION); Py_INCREF((PyObject *)wi->uwsgi_version); wi->uwsgi_node = PyString_FromString(uwsgi.hostname); Py_INCREF((PyObject *)wi->uwsgi_node); if (uwsgi.threads > 1 && id) { // if we have multiple threads we need to initialize a PyThreadState for each one for(i=0;i<uwsgi.threads;i++) { //uwsgi_log("%p\n", uwsgi.core[i]->ts[id]); uwsgi.workers[uwsgi.mywid].cores[i].ts[id] = PyThreadState_New( ((PyThreadState *)wi->interpreter)->interp); if (!uwsgi.workers[uwsgi.mywid].cores[i].ts[id]) { uwsgi_log("unable to allocate new PyThreadState structure for app %s", wi->mountpoint); goto doh; } } PyThreadState_Swap((PyThreadState *) pthread_getspecific(up.upt_save_key) ); } else if (interpreter == NULL && id) { PyThreadState_Swap(up.main_thread); } const char *default_app = ""; if ((wsgi_req->appid_len == 0 || (wsgi_req->appid_len = 1 && wsgi_req->appid[0] == '/')) && uwsgi.default_app == -1) { default_app = " (default app)" ; uwsgi.default_app = id; } wi->started_at = now; wi->startup_time = uwsgi_now() - now; if (app_type == PYTHON_APP_TYPE_WSGI) { uwsgi_log( "WSGI app %d (mountpoint='%.*s') ready in %d seconds on interpreter %p pid: %d%s\n", id, wi->mountpoint_len, wi->mountpoint, (int) wi->startup_time, wi->interpreter, (int) getpid(), default_app); } else if (app_type == PYTHON_APP_TYPE_WEB3) { uwsgi_log( "Web3 app %d (mountpoint='%.*s') ready in %d seconds on interpreter %p pid: %d%s\n", id, wi->mountpoint_len, wi->mountpoint, (int) wi->startup_time, wi->interpreter, (int) getpid(), default_app); } else if (app_type == PYTHON_APP_TYPE_PUMP) { uwsgi_log( "Pump app %d (mountpoint='%.*s') ready in %d seconds on interpreter %p pid: %d%s\n", id, wi->mountpoint_len, wi->mountpoint, (int) wi->startup_time, wi->interpreter, (int) getpid(), default_app); } uwsgi_apps_cnt++; if (multiapp > 1) { for(i=1;i<multiapp;i++) { PyObject *app_mnt = PyList_GetItem(app_list, i); if (!PyString_Check(app_mnt)) { uwsgi_log("applications dictionary key must be a string, skipping.\n"); continue; } wsgi_req->appid = PyString_AsString(app_mnt); wsgi_req->appid_len = strlen(wsgi_req->appid); PyObject *a_callable = PyDict_GetItem(applications, app_mnt); if (PyString_Check(a_callable)) { PyObject *callables_dict = get_uwsgi_pydict((char *)arg1); if (callables_dict) { a_callable = PyDict_GetItem(callables_dict, a_callable); } } if (!a_callable) { uwsgi_log("skipping broken app %s\n", wsgi_req->appid); continue; } init_uwsgi_app(LOADER_CALLABLE, a_callable, wsgi_req, wi->interpreter, app_type); } } // emulate COW uwsgi_emulate_cow_for_apps(id); return id; doh: if (PyErr_Occurred()) PyErr_Print(); if (interpreter == NULL && id) { Py_EndInterpreter(wi->interpreter); if (uwsgi.threads > 1) { PyThreadState_Swap((PyThreadState *) pthread_getspecific(up.upt_save_key)); } else { PyThreadState_Swap(up.main_thread); } } return -1; }
static PyObject *posixfile(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"name", "mode", "buffering", NULL}; PyObject *file_obj = NULL; char *name = NULL; char *mode = "rb"; DWORD access = 0; DWORD creation; HANDLE handle; int fd, flags = 0; int bufsize = -1; char m0, m1, m2; char fpmode[4]; int fppos = 0; int plus; FILE *fp; if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:posixfile", kwlist, Py_FileSystemDefaultEncoding, &name, &mode, &bufsize)) return NULL; m0 = mode[0]; m1 = m0 ? mode[1] : '\0'; m2 = m1 ? mode[2] : '\0'; plus = m1 == '+' || m2 == '+'; fpmode[fppos++] = m0; if (m1 == 'b' || m2 == 'b') { flags = _O_BINARY; fpmode[fppos++] = 'b'; } else flags = _O_TEXT; if (plus) { flags |= _O_RDWR; access = GENERIC_READ | GENERIC_WRITE; fpmode[fppos++] = '+'; } fpmode[fppos++] = '\0'; switch (m0) { case 'r': creation = OPEN_EXISTING; if (!plus) { flags |= _O_RDONLY; access = GENERIC_READ; } break; case 'w': creation = CREATE_ALWAYS; if (!plus) { access = GENERIC_WRITE; flags |= _O_WRONLY; } break; case 'a': creation = OPEN_ALWAYS; flags |= _O_APPEND; if (!plus) { flags |= _O_WRONLY; access = GENERIC_WRITE; } break; default: PyErr_Format(PyExc_ValueError, "mode string must begin with one of 'r', 'w', " "or 'a', not '%c'", m0); goto bail; } handle = CreateFile(name, access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, creation, FILE_ATTRIBUTE_NORMAL, 0); if (handle == INVALID_HANDLE_VALUE) { PyErr_SetFromWindowsErrWithFilename(GetLastError(), name); goto bail; } fd = _open_osfhandle((intptr_t)handle, flags); if (fd == -1) { CloseHandle(handle); PyErr_SetFromErrnoWithFilename(PyExc_IOError, name); goto bail; } #ifndef IS_PY3K fp = _fdopen(fd, fpmode); if (fp == NULL) { _close(fd); PyErr_SetFromErrnoWithFilename(PyExc_IOError, name); goto bail; } file_obj = PyFile_FromFile(fp, name, mode, fclose); if (file_obj == NULL) { fclose(fp); goto bail; } PyFile_SetBufSize(file_obj, bufsize); #else file_obj = PyFile_FromFd(fd, name, mode, bufsize, NULL, NULL, NULL, 1); if (file_obj == NULL) goto bail; #endif bail: PyMem_Free(name); return file_obj; }
static PyObject *getMapDataFile(PyObject *self, PyObject *args) { if(!server::mapdata) server::mapdata = opentempfile("mapdata", "w+b"); return PyFile_FromFile(((filestream *) server::mapdata)->file,"mapdata","w+b",NULL); }
static void run_interpreter(FILE *input, FILE *output) { PyThreadState *tstate; PyObject *new_stdin, *new_stdout; PyObject *mainmod, *globals; char buffer[1000]; char *p, *q; int n, end; PyEval_AcquireLock(); tstate = Py_NewInterpreter(); if (tstate == NULL) { fprintf(output, "Sorry -- can't create an interpreter\n"); return; } mainmod = PyImport_AddModule("__main__"); globals = PyModule_GetDict(mainmod); Py_INCREF(globals); new_stdin = PyFile_FromFile(input, "<socket-in>", "r", NULL); new_stdout = PyFile_FromFile(output, "<socket-out>", "w", NULL); PySys_SetObject("stdin", new_stdin); PySys_SetObject("stdout", new_stdout); PySys_SetObject("stderr", new_stdout); for (n = 1; !PyErr_Occurred(); n++) { Py_BEGIN_ALLOW_THREADS fprintf(output, "%d> ", n); p = fgets(buffer, sizeof buffer, input); Py_END_ALLOW_THREADS if (p == NULL) break; if (p[0] == '\377' && p[1] == '\354') break; q = strrchr(p, '\r'); if (q && q[1] == '\n' && q[2] == '\0') { *q++ = '\n'; *q++ = '\0'; } while (*p && isspace(*p)) p++; if (p[0] == '#' || p[0] == '\0') continue; end = run_command(buffer, globals); if (end < 0) PyErr_Print(); if (end) break; } Py_XDECREF(globals); Py_XDECREF(new_stdin); Py_XDECREF(new_stdout); Py_EndInterpreter(tstate); PyEval_ReleaseLock(); fprintf(output, "Goodbye!\n"); }
void *uwsgi_request_subhandler_web3(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) { PyObject *zero; int i; PyObject *pydictkey, *pydictvalue; char *path_info; for (i = 0; i < wsgi_req->var_cnt; i += 2) { #ifdef UWSGI_DEBUG uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base); #endif #ifdef PYTHREE pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL); pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL); #else pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len); pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len); #endif PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue); Py_DECREF(pydictkey); Py_DECREF(pydictvalue); } if (wsgi_req->uh->modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) { wsgi_req->uh->modifier1 = python_plugin.modifier1; pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME"); if (pydictkey) { if (PyString_Check(pydictkey)) { pydictvalue = PyDict_GetItemString(wsgi_req->async_environ, "PATH_INFO"); if (pydictvalue) { if (PyString_Check(pydictvalue)) { path_info = PyString_AsString(pydictvalue); PyDict_SetItemString(wsgi_req->async_environ, "PATH_INFO", PyString_FromString(path_info + PyString_Size(pydictkey))); } } } } } // create wsgi.input custom object wsgi_req->async_input = (PyObject *) PyObject_New(uwsgi_Input, &uwsgi_InputType); ((uwsgi_Input*)wsgi_req->async_input)->wsgi_req = wsgi_req; PyDict_SetItemString(wsgi_req->async_environ, "web3.input", wsgi_req->async_input); PyDict_SetItemString(wsgi_req->async_environ, "web3.version", wi->gateway_version); zero = PyFile_FromFile(stderr, "web3_input", "w", NULL); PyDict_SetItemString(wsgi_req->async_environ, "web3.errors", zero); Py_DECREF(zero); PyDict_SetItemString(wsgi_req->async_environ, "web3.run_once", Py_False); PyDict_SetItemString(wsgi_req->async_environ, "web3.multithread", Py_False); if (uwsgi.numproc == 1) { PyDict_SetItemString(wsgi_req->async_environ, "web3.multiprocess", Py_False); } else { PyDict_SetItemString(wsgi_req->async_environ, "web3.multiprocess", Py_True); } if (wsgi_req->scheme_len > 0) { zero = UWSGI_PYFROMSTRINGSIZE(wsgi_req->scheme, wsgi_req->scheme_len); } else if (wsgi_req->https_len > 0) { if (!strncasecmp(wsgi_req->https, "on", 2) || wsgi_req->https[0] == '1') { zero = UWSGI_PYFROMSTRING("https"); } else { zero = UWSGI_PYFROMSTRING("http"); } } else { zero = UWSGI_PYFROMSTRING("http"); } PyDict_SetItemString(wsgi_req->async_environ, "web3.url_scheme", zero); Py_DECREF(zero); wsgi_req->async_app = wi->callable; // export .env only in non-threaded mode if (uwsgi.threads < 2) { PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ); } PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version); if (uwsgi.cores > 1) { PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id)); } PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.node", wi->uwsgi_node); // call if (PyTuple_GetItem(wsgi_req->async_args, 0) != wsgi_req->async_environ) { if (PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ)) { uwsgi_log_verbose("unable to set environ to the python application callable, consider using the holy env allocator\n"); return NULL; } } return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req); }
static inline void prepare_call_wsgi(client_t *client) { PyObject *input = NULL, *c = NULL; char *val; set_current_request(client); //check Expect if(client->http->http_minor == 1){ c = PyDict_GetItemString(client->environ, "HTTP_EXPECT"); if(c){ val = PyString_AS_STRING(c); if(!strcasecmp(val, "100-continue")){ int ret = write(client->fd, "HTTP/1.1 100 Continue\r\n\r\n", 25); if(ret < 0){ PyErr_SetFromErrno(PyExc_IOError); write_error_log(__FILE__, __LINE__); client->keep_alive = 0; client->status_code = 500; send_error_page(client); close_conn(client, main_loop); return; } }else{ //417 client->keep_alive = 0; client->status_code = 417; send_error_page(client); close_conn(client, main_loop); return; } } } if(client->body_type == BODY_TYPE_TMPFILE){ FILE *tmp = (FILE *)client->body; fflush(tmp); rewind(tmp); input = PyFile_FromFile(tmp, "<tmpfile>", "r", fclose); PyDict_SetItem((PyObject *)client->environ, wsgi_input_key, input); Py_DECREF(input); client->body = NULL; }else{ if(client->body_type == BODY_TYPE_BUFFER){ input = StringIOObject_New((buffer *)client->body); PyDict_SetItem((PyObject *)client->environ, wsgi_input_key, input); }else{ if(client->body){ input = StringIOObject_New((buffer *)client->body); }else{ input = StringIOObject_New(new_buffer(0, 0)); } PyDict_SetItem((PyObject *)client->environ, wsgi_input_key, input); } client->body = NULL;; Py_DECREF(input); } if(is_keep_alive){ //support keep-alive c = PyDict_GetItemString(client->environ, "HTTP_CONNECTION"); if(client->http->http_minor == 1){ //HTTP 1.1 if(c){ val = PyString_AS_STRING(c); if(!strcasecmp(val, "close")){ client->keep_alive = 0; }else{ client->keep_alive = 1; } }else{ client->keep_alive = 1; } }else{ //HTTP 1.0 if(c){ val = PyString_AS_STRING(c); if(!strcasecmp(val, "keep-alive")){ client->keep_alive = 1; }else{ client->keep_alive = 0; } }else{ client->keep_alive = 0; } } } }
// The following code is based off of KB: Q190351 static PyObject *_PyPopen(char *cmdstring, int mode, int n) { HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup, hChildStderrRdDup, hProcess; // hChildStdoutWrDup; SECURITY_ATTRIBUTES saAttr; BOOL fSuccess; int fd1, fd2, fd3; FILE *f1, *f2, *f3; long file_count; PyObject *f; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) return PyWin_SetAPIError("CreatePipe"); // Create new output read handle and the input write handle. Set // the inheritance properties to FALSE. Otherwise, the child inherits // the these handles; resulting in non-closeable handles to the pipes // being created. fSuccess = DuplicateHandle( GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS); if (!fSuccess) return PyWin_SetAPIError("DuplicateHandle"); // Close the inheritable version of ChildStdin // that we're using. CloseHandle(hChildStdinWr); if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) return PyWin_SetAPIError("CreatePipe"); fSuccess = DuplicateHandle( GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(), &hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS); if (!fSuccess) return PyWin_SetAPIError("DuplicateHandle"); // Close the inheritable version of ChildStdout // that we're using. CloseHandle(hChildStdoutRd); if (n != POPEN_4) { if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0)) return PyWin_SetAPIError("CreatePipe"); fSuccess = DuplicateHandle( GetCurrentProcess(), hChildStderrRd, GetCurrentProcess(), &hChildStderrRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS); if (!fSuccess) return PyWin_SetAPIError("DuplicateHandle"); // Close the inheritable version of ChildStdErr that we're using. CloseHandle(hChildStderrRd); } switch (n) { case POPEN_1: switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) { case _O_WRONLY | _O_TEXT: // Case for writing to child Stdin in text mode. fd1 = _open_osfhandle((INT_PTR)hChildStdinWrDup, mode); f1 = _fdopen(fd1, "w"); f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose); PyFile_SetBufSize(f, 0); // We don't care about these pipes anymore, so close them. CloseHandle(hChildStdoutRdDup); CloseHandle(hChildStderrRdDup); break; case _O_RDONLY | _O_TEXT: // Case for reading from child Stdout in text mode. fd1 = _open_osfhandle((INT_PTR)hChildStdoutRdDup, mode); f1 = _fdopen(fd1, "r"); f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose); PyFile_SetBufSize(f, 0); // We don't care about these pipes anymore, so close them. CloseHandle(hChildStdinWrDup); CloseHandle(hChildStderrRdDup); break; case _O_RDONLY | _O_BINARY: // Case for readinig from child Stdout in binary mode. fd1 = _open_osfhandle((INT_PTR)hChildStdoutRdDup, mode); f1 = _fdopen(fd1, "rb"); f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose); PyFile_SetBufSize(f, 0); // We don't care about these pipes anymore, so close them. CloseHandle(hChildStdinWrDup); CloseHandle(hChildStderrRdDup); break; case _O_WRONLY | _O_BINARY: // Case for writing to child Stdin in binary mode. fd1 = _open_osfhandle((INT_PTR)hChildStdinWrDup, mode); f1 = _fdopen(fd1, "wb"); f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose); PyFile_SetBufSize(f, 0); // We don't care about these pipes anymore, so close them. CloseHandle(hChildStdoutRdDup); CloseHandle(hChildStderrRdDup); break; } file_count = 1; break; case POPEN_2: case POPEN_4: { char *m1, *m2; PyObject *p1, *p2; if (mode & _O_TEXT) { m1="r"; m2="w"; } else { m1="rb"; m2="wb"; } fd1 = _open_osfhandle((INT_PTR)hChildStdinWrDup, mode); f1 = _fdopen(fd1, m2); fd2 = _open_osfhandle((INT_PTR)hChildStdoutRdDup, mode); f2 = _fdopen(fd2, m1); p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose); PyFile_SetBufSize(p1, 0); p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose); PyFile_SetBufSize(p2, 0); if (n != 4) CloseHandle(hChildStderrRdDup); f = Py_BuildValue("OO",p1,p2); Py_XDECREF(p1); Py_XDECREF(p2); file_count = 2; break; } case POPEN_3: { char *m1, *m2; PyObject *p1, *p2, *p3; if (mode & _O_TEXT) { m1="r"; m2="w"; } else { m1="rb"; m2="wb"; } fd1 = _open_osfhandle((INT_PTR)hChildStdinWrDup, mode); f1 = _fdopen(fd1, m2); fd2 = _open_osfhandle((INT_PTR)hChildStdoutRdDup, mode); f2 = _fdopen(fd2, m1); fd3 = _open_osfhandle((INT_PTR)hChildStderrRdDup, mode); f3 = _fdopen(fd3, m1); p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose); p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose); p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose); PyFile_SetBufSize(p1, 0); PyFile_SetBufSize(p2, 0); PyFile_SetBufSize(p3, 0); f = Py_BuildValue("OOO",p1,p2,p3); Py_XDECREF(p1); Py_XDECREF(p2); Py_XDECREF(p3); file_count = 3; break; } } if (n == POPEN_4) { if (!_PyPopenCreateProcess(cmdstring, hChildStdinRd, hChildStdoutWr, hChildStdoutWr, &hProcess)) return PyWin_SetAPIError("CreateProcess"); } else { if (!_PyPopenCreateProcess(cmdstring, hChildStdinRd, hChildStdoutWr, hChildStderrWr, &hProcess)) return PyWin_SetAPIError("CreateProcess"); } /* * Insert the files we've created into the process dictionary * all referencing the list with the process handle and the * initial number of files (see description below in _PyPclose). * Since if _PyPclose later tried to wait on a process when all * handles weren't closed, it could create a deadlock with the * child, we spend some energy here to try to ensure that we * either insert all file handles into the dictionary or none * at all. It's a little clumsy with the various popen modes * and variable number of files involved. */ if (!_PyPopenProcs) { _PyPopenProcs = PyDict_New(); } if (_PyPopenProcs) { PyObject *procObj, *hProcessObj, *intObj, *fileObj[3]; int ins_rc[3]; fileObj[0] = fileObj[1] = fileObj[2] = NULL; ins_rc[0] = ins_rc[1] = ins_rc[2] = 0; procObj = PyList_New(2); hProcessObj = PyLong_FromVoidPtr(hProcess); intObj = PyInt_FromLong(file_count); if (procObj && hProcessObj && intObj) { PyList_SetItem(procObj,0,hProcessObj); PyList_SetItem(procObj,1,intObj); fileObj[0] = PyLong_FromVoidPtr(f1); if (fileObj[0]) { ins_rc[0] = PyDict_SetItem(_PyPopenProcs, fileObj[0], procObj); } if (file_count >= 2) { fileObj[1] = PyLong_FromVoidPtr(f2); if (fileObj[1]) { ins_rc[1] = PyDict_SetItem(_PyPopenProcs, fileObj[1], procObj); } } if (file_count >= 3) { fileObj[2] = PyLong_FromVoidPtr(f3); if (fileObj[2]) { ins_rc[2] = PyDict_SetItem(_PyPopenProcs, fileObj[2], procObj); } } if (ins_rc[0] < 0 || !fileObj[0] || ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) || ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) { /* Something failed - remove any dictionary * entries that did make it. */ if (!ins_rc[0] && fileObj[0]) { PyDict_DelItem(_PyPopenProcs, fileObj[0]); } if (!ins_rc[1] && fileObj[1]) { PyDict_DelItem(_PyPopenProcs, fileObj[1]); } if (!ins_rc[2] && fileObj[2]) { PyDict_DelItem(_PyPopenProcs, fileObj[2]); } } } /* * Clean up our localized references for the dictionary keys * and value since PyDict_SetItem will Py_INCREF any copies * that got placed in the dictionary. */ Py_XDECREF(procObj); Py_XDECREF(fileObj[0]); Py_XDECREF(fileObj[1]); Py_XDECREF(fileObj[2]); } // Child is launched. Close the parents copy of those pipe handles // that only the child should have open. // You need to make sure that no handles to the write end of the // output pipe are maintained in this process or else the pipe will // not close when the child process exits and the ReadFile will hang. if (!CloseHandle(hChildStdinRd)) return PyWin_SetAPIError("CloseHandle"); if (!CloseHandle(hChildStdoutWr)) return PyWin_SetAPIError("CloseHandle"); if ((n != 4) && (!CloseHandle(hChildStderrWr))) return PyWin_SetAPIError("CloseHandle"); return f; }