- Timestamp:
- Apr 19, 2011, 11:12:07 PM (14 years ago)
- Location:
- clamav/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
clamav/trunk ¶
-
Property svn:mergeinfo
set to
/clamav/vendor/0.97 merged eligible
-
Property svn:mergeinfo
set to
-
TabularUnified clamav/trunk/libclamav/c++/llvm/lib/System/Unix/Program.inc ¶
r189 r319 31 31 #include <fcntl.h> 32 32 #endif 33 #ifdef HAVE_POSIX_SPAWN 34 #include <spawn.h> 35 #if !defined(__APPLE__) 36 extern char **environ; 37 #else 38 #include <crt_externs.h> // _NSGetEnviron 39 #endif 40 #endif 33 41 34 42 namespace llvm { … … 95 103 96 104 static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) { 97 if (Path == 0) 98 // Noop 105 if (Path == 0) // Noop 99 106 return false; 100 std::stringFile;107 const char *File; 101 108 if (Path->isEmpty()) 102 109 // Redirect empty paths to /dev/null 103 110 File = "/dev/null"; 104 111 else 105 File = Path-> str();112 File = Path->c_str(); 106 113 107 114 // Open the file 108 int InFD = open(File .c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);115 int InFD = open(File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666); 109 116 if (InFD == -1) { 110 MakeErrMsg(ErrMsg, "Cannot open file '" + File+ "' for "117 MakeErrMsg(ErrMsg, "Cannot open file '" + std::string(File) + "' for " 111 118 + (FD == 0 ? "input" : "output")); 112 119 return true; … … 114 121 115 122 // Install it as the requested FD 116 if ( -1 == dup2(InFD, FD)) {123 if (dup2(InFD, FD) == -1) { 117 124 MakeErrMsg(ErrMsg, "Cannot dup2"); 125 close(InFD); 118 126 return true; 119 127 } … … 121 129 return false; 122 130 } 131 132 #ifdef HAVE_POSIX_SPAWN 133 static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg, 134 posix_spawn_file_actions_t &FileActions) { 135 if (Path == 0) // Noop 136 return false; 137 const char *File; 138 if (Path->isEmpty()) 139 // Redirect empty paths to /dev/null 140 File = "/dev/null"; 141 else 142 File = Path->c_str(); 143 144 if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD, 145 File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666)) 146 return MakeErrMsg(ErrMsg, "Cannot dup2", Err); 147 return false; 148 } 149 #endif 123 150 124 151 static void TimeOutHandler(int Sig) { … … 151 178 152 179 bool 153 Program::Execute(const Path& path, 154 const char** args, 155 const char** envp, 156 const Path** redirects, 157 unsigned memoryLimit, 158 std::string* ErrMsg) 159 { 180 Program::Execute(const Path &path, const char **args, const char **envp, 181 const Path **redirects, unsigned memoryLimit, 182 std::string *ErrMsg) { 183 // If this OS has posix_spawn and there is no memory limit being implied, use 184 // posix_spawn. It is more efficient than fork/exec. 185 #ifdef HAVE_POSIX_SPAWN 186 if (memoryLimit == 0) { 187 posix_spawn_file_actions_t FileActions; 188 posix_spawn_file_actions_init(&FileActions); 189 190 if (redirects) { 191 // Redirect stdin/stdout. 192 if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) || 193 RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions)) 194 return false; 195 if (redirects[1] == 0 || redirects[2] == 0 || 196 *redirects[1] != *redirects[2]) { 197 // Just redirect stderr 198 if (RedirectIO_PS(redirects[2], 2, ErrMsg, FileActions)) return false; 199 } else { 200 // If stdout and stderr should go to the same place, redirect stderr 201 // to the FD already open for stdout. 202 if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2)) 203 return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err); 204 } 205 } 206 207 if (!envp) 208 #if !defined(__APPLE__) 209 envp = const_cast<const char **>(environ); 210 #else 211 // environ is missing in dylibs. 212 envp = const_cast<const char **>(*_NSGetEnviron()); 213 #endif 214 215 pid_t PID; 216 int Err = posix_spawn(&PID, path.c_str(), &FileActions, /*attrp*/0, 217 const_cast<char **>(args), const_cast<char **>(envp)); 218 219 posix_spawn_file_actions_destroy(&FileActions); 220 221 if (Err) 222 return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err); 223 224 Data_ = reinterpret_cast<void*>(PID); 225 return true; 226 } 227 #endif 228 160 229 if (!path.canExecute()) { 161 230 if (ErrMsg) … … 201 270 // Execute! 202 271 if (envp != 0) 203 execve(path.c_str(), (char**)args, (char**)envp); 272 execve(path.c_str(), 273 const_cast<char **>(args), 274 const_cast<char **>(envp)); 204 275 else 205 execv(path.c_str(), (char**)args); 276 execv(path.c_str(), 277 const_cast<char **>(args)); 206 278 // If the execve() failed, we should exit. Follow Unix protocol and 207 279 // return 127 if the executable was not found, and 126 otherwise. … … 239 311 // unlike if we used SIG_IGN. 240 312 if (secondsToWait) { 241 Act.sa_sigaction = 0;313 memset(&Act, 0, sizeof(Act)); 242 314 Act.sa_handler = TimeOutHandler; 243 315 sigemptyset(&Act.sa_mask); 244 Act.sa_flags = 0;245 316 sigaction(SIGALRM, &Act, &Old); 246 317 alarm(secondsToWait);
Note:
See TracChangeset
for help on using the changeset viewer.