2626
2727#include " pb_utils.h"
2828
29+ #include < sys/stat.h>
30+ #include < fstream>
31+
2932#ifdef _WIN32
3033#include < windows.h>
3134
3235#include < algorithm>
3336#else
3437#include < dlfcn.h>
38+ #include < unistd.h>
39+ #endif
40+
41+ #ifndef _WIN32
42+ extern char **environ;
3543#endif
3644
3745
@@ -315,6 +323,42 @@ WrapTritonErrorInSharedPtr(TRITONSERVER_Error* error)
315323}
316324#endif // NOT TRITON_PB_STUB
317325
326+ bool IsValidIdentifier (const std::string& input) {
327+ if (input.empty ()) {
328+ return false ;
329+ }
330+
331+ // Check for invalid characters
332+ if (input.find_first_of (INVALID_CHARS) != std::string::npos) {
333+ return false ;
334+ }
335+
336+ return true ;
337+ }
338+
339+ bool IsValidPath (const std::string& path) {
340+ if (path.empty ()) {
341+ return false ;
342+ }
343+
344+ // Must be absolute path
345+ if (path[0 ] != ' /' ) {
346+ return false ;
347+ }
348+
349+ return true ;
350+ }
351+
352+ bool IsExecutableFile (const std::string& filepath) {
353+ struct stat file_stat;
354+ if (stat (filepath.c_str (), &file_stat) != 0 ) {
355+ return false ;
356+ }
357+
358+ // Check if it's a regular file and executable by owner
359+ return S_ISREG (file_stat.st_mode ) && (file_stat.st_mode & S_IXUSR);
360+ }
361+
318362std::string
319363GenerateUUID ()
320364{
@@ -323,4 +367,95 @@ GenerateUUID()
323367 return boost::uuids::to_string (uuid);
324368}
325369
370+ // Helper function to parse environment variables from activation script
371+ std::map<std::string, std::string>
372+ ParseActivationScript (const std::string& activate_path) {
373+ std::map<std::string, std::string> env_vars;
374+
375+ // Read the current environment as baseline
376+ #ifndef _WIN32
377+ if (environ != nullptr ) {
378+ for (char **env = environ; *env != nullptr ; env++) {
379+ std::string env_str (*env);
380+ size_t eq_pos = env_str.find (' =' );
381+ if (eq_pos != std::string::npos) {
382+ std::string key = env_str.substr (0 , eq_pos);
383+ std::string value = env_str.substr (eq_pos + 1 );
384+ env_vars[key] = value;
385+ }
386+ }
387+ }
388+ #endif
389+
390+ // Parse activation script for environment changes
391+ std::ifstream activate_file (activate_path);
392+ if (!activate_file.is_open ()) {
393+ return env_vars; // Return current environment if can't read activation script
394+ }
395+
396+ std::string line;
397+ while (std::getline (activate_file, line)) {
398+ // Look for export statements or direct assignments
399+ if (line.find (" export " ) == 0 ) {
400+ // Handle: export VAR=value
401+ line = line.substr (7 ); // Remove "export "
402+ }
403+
404+ size_t eq_pos = line.find (' =' );
405+ if (eq_pos != std::string::npos && line[0 ] != ' #' ) {
406+ std::string key = line.substr (0 , eq_pos);
407+ std::string value = line.substr (eq_pos + 1 );
408+
409+ // Remove quotes if present
410+ if (value.size () >= 2 &&
411+ ((value[0 ] == ' "' && value.back () == ' "' ) ||
412+ (value[0 ] == ' \' ' && value.back () == ' \' ' ))) {
413+ value = value.substr (1 , value.size () - 2 );
414+ }
415+
416+ // Handle variable substitution for common cases
417+ if (value.find (" $PATH" ) != std::string::npos) {
418+ size_t pos = value.find (" $PATH" );
419+ value.replace (pos, 5 , env_vars[" PATH" ]);
420+ }
421+ if (value.find (" $LD_LIBRARY_PATH" ) != std::string::npos) {
422+ size_t pos = value.find (" $LD_LIBRARY_PATH" );
423+ value.replace (pos, 16 , env_vars[" LD_LIBRARY_PATH" ]);
424+ }
425+
426+ env_vars[key] = value;
427+ }
428+ }
429+
430+ return env_vars;
431+ }
432+
433+ // Helper function to prepare environment array for execve
434+ std::pair<std::vector<std::string>, std::vector<char *>>
435+ PrepareEnvironment (const std::map<std::string, std::string>& env_vars,
436+ const std::string& additional_lib_path) {
437+
438+ std::vector<std::string> env_strings;
439+ std::vector<char *> env_array;
440+
441+ for (const auto & [key, value] : env_vars) {
442+ std::string env_string;
443+ if (key == " LD_LIBRARY_PATH" && !additional_lib_path.empty ()) {
444+ // Prepend the additional library path
445+ env_string = key + " =" + additional_lib_path + " :" + value;
446+ } else {
447+ env_string = key + " =" + value;
448+ }
449+ env_strings.push_back (env_string);
450+ }
451+
452+ // Convert to char* array
453+ for (auto & env_str : env_strings) {
454+ env_array.push_back (const_cast <char *>(env_str.c_str ()));
455+ }
456+ env_array.push_back (nullptr );
457+
458+ return std::make_pair (std::move (env_strings), std::move (env_array));
459+ }
460+
326461}}} // namespace triton::backend::python
0 commit comments