MCPcopy Create free account
hub / github.com/danoon2/Boxedwine / portable_execvpe

Function portable_execvpe

lib/tiny-process/process_unix.cpp:17–103  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

15namespace TinyProcessLib {
16
17static int portable_execvpe(const char *file, char *const argv[], char *const envp[]) {
18#ifdef __GLIBC__
19 // Prefer native implementation.
20 return execvpe(file, argv, envp);
21#else
22 if(!file || !*file) {
23 errno = ENOENT;
24 return -1;
25 }
26
27 if(strchr(file, '/') != nullptr) {
28 // If file contains a slash, no search is needed.
29 return execve(file, argv, envp);
30 }
31
32 const char *path = getenv("PATH");
33 char cspath[PATH_MAX + 1] = {};
34 if(!path) {
35 // If env variable is not set, use static path string.
36 confstr(_CS_PATH, cspath, sizeof(cspath));
37 path = cspath;
38 }
39
40 const size_t path_len = strlen(path);
41 const size_t file_len = strlen(file);
42
43 if(file_len > NAME_MAX) {
44 errno = ENAMETOOLONG;
45 return -1;
46 }
47
48 // Indicates whether we encountered EACCESS at least once.
49 bool eacces = false;
50
51 const char *curr = nullptr;
52 const char *next = nullptr;
53
54 for(curr = path; *curr; curr = *next ? next + 1 : next) {
55 next = strchr(curr, ':');
56 if(!next) {
57 next = path + path_len;
58 }
59
60 const size_t sz = (next - curr);
61 if(sz > PATH_MAX) {
62 // Path is too long. Proceed to next path in list.
63 continue;
64 }
65
66 char exe_path[PATH_MAX + 1 + NAME_MAX + 1]; // 1 byte for slash + 1 byte for \0
67 memcpy(exe_path, curr, sz);
68 exe_path[sz] = '/';
69 memcpy(exe_path + sz + 1, file, file_len);
70 exe_path[sz + 1 + file_len] = '\0';
71
72 execve(exe_path, argv, envp);
73
74 switch(errno) {

Callers 1

openMethod · 0.85

Calls 1

memcpyFunction · 0.85

Tested by

no test coverage detected