2626
2727#include " pb_utils.h"
2828
29+ #include < sys/stat.h>
30+
31+ #include < fstream>
32+
2933#ifdef _WIN32
3034#include < windows.h>
3135
3236#include < algorithm>
3337#else
3438#include < dlfcn.h>
39+ #include < unistd.h>
40+ #endif
41+
42+ #ifndef _WIN32
43+ extern char ** environ;
3544#endif
3645
3746
@@ -315,6 +324,30 @@ WrapTritonErrorInSharedPtr(TRITONSERVER_Error* error)
315324}
316325#endif // NOT TRITON_PB_STUB
317326
327+ bool
328+ IsValidIdentifier (const std::string& input)
329+ {
330+ // Check for invalid characters
331+ if (input.empty () ||
332+ input.find_first_of (INVALID_CHARS) != std::string::npos) {
333+ return false ;
334+ }
335+
336+ return true ;
337+ }
338+
339+ bool
340+ IsExecutableFile (const std::string& filepath)
341+ {
342+ struct stat file_stat;
343+ if (stat (filepath.c_str (), &file_stat) != 0 ) {
344+ return false ;
345+ }
346+
347+ // Check if it's a regular file and executable by owner
348+ return S_ISREG (file_stat.st_mode ) && (file_stat.st_mode & S_IXUSR);
349+ }
350+
318351std::string
319352GenerateUUID ()
320353{
@@ -323,4 +356,85 @@ GenerateUUID()
323356 return boost::uuids::to_string (uuid);
324357}
325358
359+ // Helper function to get environment variables for Python virtual environments
360+ std::map<std::string, std::string>
361+ ParseActivationScript (const std::string& activate_path)
362+ {
363+ std::map<std::string, std::string> env_vars;
364+
365+ // Read the current environment as baseline
366+ #ifndef _WIN32
367+ if (environ != nullptr ) {
368+ for (char ** env = environ; *env != nullptr ; env++) {
369+ std::string env_str (*env);
370+ size_t eq_pos = env_str.find (' =' );
371+ if (eq_pos != std::string::npos) {
372+ std::string key = env_str.substr (0 , eq_pos);
373+ std::string value = env_str.substr (eq_pos + 1 );
374+ env_vars[key] = value;
375+ }
376+ }
377+ }
378+ #endif
379+
380+ // Extract virtual environment root from activation script path
381+ std::string venv_path = activate_path;
382+ size_t bin_activate_pos = venv_path.find (" /bin/activate" );
383+ if (bin_activate_pos != std::string::npos) {
384+ venv_path = venv_path.substr (0 , bin_activate_pos);
385+ }
386+
387+ // Set standard virtual environment variables
388+ env_vars[" VIRTUAL_ENV" ] = venv_path;
389+ env_vars[" VIRTUAL_ENV_PROMPT" ] = " (" + venv_path + " )" ;
390+
391+ // Update PATH to include the virtual environment's bin directory
392+ std::string new_path = venv_path + " /bin" ;
393+ if (env_vars.find (" PATH" ) != env_vars.end ()) {
394+ new_path += " :" + env_vars[" PATH" ];
395+ }
396+ env_vars[" PATH" ] = new_path;
397+
398+ // Update LD_LIBRARY_PATH to include the virtual environment's lib directory
399+ std::string new_lib_path = venv_path + " /lib" ;
400+ if (env_vars.find (" LD_LIBRARY_PATH" ) != env_vars.end ()) {
401+ new_lib_path += " :" + env_vars[" LD_LIBRARY_PATH" ];
402+ }
403+ env_vars[" LD_LIBRARY_PATH" ] = new_lib_path;
404+
405+ // Remove PYTHONHOME if it exists
406+ env_vars.erase (" PYTHONHOME" );
407+
408+ return env_vars;
409+ }
410+
411+ // Helper function to prepare environment array for execve
412+ std::pair<std::vector<std::string>, std::vector<char *>>
413+ PrepareEnvironment (
414+ const std::map<std::string, std::string>& env_vars,
415+ const std::string& additional_lib_path)
416+ {
417+ std::vector<std::string> env_strings;
418+ std::vector<char *> env_array;
419+
420+ for (const auto & [key, value] : env_vars) {
421+ std::string env_string;
422+ if (key == " LD_LIBRARY_PATH" && !additional_lib_path.empty ()) {
423+ // Prepend the additional library path
424+ env_string = key + " =" + additional_lib_path + " :" + value;
425+ } else {
426+ env_string = key + " =" + value;
427+ }
428+ env_strings.push_back (env_string);
429+ }
430+
431+ // Convert to char* array
432+ for (auto & env_str : env_strings) {
433+ env_array.push_back (const_cast <char *>(env_str.c_str ()));
434+ }
435+ env_array.push_back (nullptr );
436+
437+ return std::make_pair (std::move (env_strings), std::move (env_array));
438+ }
439+
326440}}} // namespace triton::backend::python
0 commit comments