Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: base/process/launch_posix.cc

Issue 22750002: Move AlterEnvironment to base/environment.h, implement on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/process/launch.cc ('k') | base/process/process_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/process/launch.h" 5 #include "base/process/launch.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <signal.h> 10 #include <signal.h>
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 // own use and will complain if we try to close them. All of 263 // own use and will complain if we try to close them. All of
264 // these FDs are >= |max_fds|, so we can check against that here 264 // these FDs are >= |max_fds|, so we can check against that here
265 // before closing. See https://bugs.kde.org/show_bug.cgi?id=191758 265 // before closing. See https://bugs.kde.org/show_bug.cgi?id=191758
266 if (fd < static_cast<int>(max_fds)) { 266 if (fd < static_cast<int>(max_fds)) {
267 int ret = HANDLE_EINTR(close(fd)); 267 int ret = HANDLE_EINTR(close(fd));
268 DPCHECK(ret == 0); 268 DPCHECK(ret == 0);
269 } 269 }
270 } 270 }
271 } 271 }
272 272
273 char** AlterEnvironment(const EnvironmentVector& changes,
274 const char* const* const env) {
275 unsigned count = 0;
276 unsigned size = 0;
277
278 // First assume that all of the current environment will be included.
279 for (unsigned i = 0; env[i]; i++) {
280 const char *const pair = env[i];
281 count++;
282 size += strlen(pair) + 1 /* terminating NUL */;
283 }
284
285 for (EnvironmentVector::const_iterator j = changes.begin();
286 j != changes.end();
287 ++j) {
288 bool found = false;
289 const char *pair;
290
291 for (unsigned i = 0; env[i]; i++) {
292 pair = env[i];
293 const char *const equals = strchr(pair, '=');
294 if (!equals)
295 continue;
296 const unsigned keylen = equals - pair;
297 if (keylen == j->first.size() &&
298 memcmp(pair, j->first.data(), keylen) == 0) {
299 found = true;
300 break;
301 }
302 }
303
304 // if found, we'll either be deleting or replacing this element.
305 if (found) {
306 count--;
307 size -= strlen(pair) + 1;
308 if (j->second.size())
309 found = false;
310 }
311
312 // if !found, then we have a new element to add.
313 if (!found && !j->second.empty()) {
314 count++;
315 size += j->first.size() + 1 /* '=' */ + j->second.size() + 1 /* NUL */;
316 }
317 }
318
319 count++; // for the final NULL
320 uint8_t *buffer = new uint8_t[sizeof(char*) * count + size];
321 char **const ret = reinterpret_cast<char**>(buffer);
322 unsigned k = 0;
323 char *scratch = reinterpret_cast<char*>(buffer + sizeof(char*) * count);
324
325 for (unsigned i = 0; env[i]; i++) {
326 const char *const pair = env[i];
327 const char *const equals = strchr(pair, '=');
328 if (!equals) {
329 const unsigned len = strlen(pair);
330 ret[k++] = scratch;
331 memcpy(scratch, pair, len + 1);
332 scratch += len + 1;
333 continue;
334 }
335 const unsigned keylen = equals - pair;
336 bool handled = false;
337 for (EnvironmentVector::const_iterator
338 j = changes.begin(); j != changes.end(); j++) {
339 if (j->first.size() == keylen &&
340 memcmp(j->first.data(), pair, keylen) == 0) {
341 if (!j->second.empty()) {
342 ret[k++] = scratch;
343 memcpy(scratch, pair, keylen + 1);
344 scratch += keylen + 1;
345 memcpy(scratch, j->second.c_str(), j->second.size() + 1);
346 scratch += j->second.size() + 1;
347 }
348 handled = true;
349 break;
350 }
351 }
352
353 if (!handled) {
354 const unsigned len = strlen(pair);
355 ret[k++] = scratch;
356 memcpy(scratch, pair, len + 1);
357 scratch += len + 1;
358 }
359 }
360
361 // Now handle new elements
362 for (EnvironmentVector::const_iterator
363 j = changes.begin(); j != changes.end(); j++) {
364 if (j->second.empty())
365 continue;
366
367 bool found = false;
368 for (unsigned i = 0; env[i]; i++) {
369 const char *const pair = env[i];
370 const char *const equals = strchr(pair, '=');
371 if (!equals)
372 continue;
373 const unsigned keylen = equals - pair;
374 if (keylen == j->first.size() &&
375 memcmp(pair, j->first.data(), keylen) == 0) {
376 found = true;
377 break;
378 }
379 }
380
381 if (!found) {
382 ret[k++] = scratch;
383 memcpy(scratch, j->first.data(), j->first.size());
384 scratch += j->first.size();
385 *scratch++ = '=';
386 memcpy(scratch, j->second.c_str(), j->second.size() + 1);
387 scratch += j->second.size() + 1;
388 }
389 }
390
391 ret[k] = NULL;
392 return ret;
393 }
394
395 bool LaunchProcess(const std::vector<std::string>& argv, 273 bool LaunchProcess(const std::vector<std::string>& argv,
396 const LaunchOptions& options, 274 const LaunchOptions& options,
397 ProcessHandle* process_handle) { 275 ProcessHandle* process_handle) {
398 size_t fd_shuffle_size = 0; 276 size_t fd_shuffle_size = 0;
399 if (options.fds_to_remap) { 277 if (options.fds_to_remap) {
400 fd_shuffle_size = options.fds_to_remap->size(); 278 fd_shuffle_size = options.fds_to_remap->size();
401 } 279 }
402 280
403 InjectiveMultimap fd_shuffle1; 281 InjectiveMultimap fd_shuffle1;
404 InjectiveMultimap fd_shuffle2; 282 InjectiveMultimap fd_shuffle2;
405 fd_shuffle1.reserve(fd_shuffle_size); 283 fd_shuffle1.reserve(fd_shuffle_size);
406 fd_shuffle2.reserve(fd_shuffle_size); 284 fd_shuffle2.reserve(fd_shuffle_size);
407 285
408 scoped_ptr<char*[]> argv_cstr(new char*[argv.size() + 1]); 286 scoped_ptr<char*[]> argv_cstr(new char*[argv.size() + 1]);
409 scoped_ptr<char*[]> new_environ; 287 scoped_ptr<char*[]> new_environ;
410 if (options.environ) 288 if (!options.environ.empty())
411 new_environ.reset(AlterEnvironment(*options.environ, GetEnvironment())); 289 new_environ = AlterEnvironment(GetEnvironment(), options.environ);
412 290
413 sigset_t full_sigset; 291 sigset_t full_sigset;
414 sigfillset(&full_sigset); 292 sigfillset(&full_sigset);
415 const sigset_t orig_sigmask = SetSignalMask(full_sigset); 293 const sigset_t orig_sigmask = SetSignalMask(full_sigset);
416 294
417 pid_t pid; 295 pid_t pid;
418 #if defined(OS_LINUX) 296 #if defined(OS_LINUX)
419 if (options.clone_flags) { 297 if (options.clone_flags) {
420 // Signal handling in this function assumes the creation of a new 298 // Signal handling in this function assumes the creation of a new
421 // process, so we check that a thread is not being created by mistake 299 // process, so we check that a thread is not being created by mistake
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 407
530 if (options.fds_to_remap) { 408 if (options.fds_to_remap) {
531 for (FileHandleMappingVector::const_iterator 409 for (FileHandleMappingVector::const_iterator
532 it = options.fds_to_remap->begin(); 410 it = options.fds_to_remap->begin();
533 it != options.fds_to_remap->end(); ++it) { 411 it != options.fds_to_remap->end(); ++it) {
534 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false)); 412 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false));
535 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false)); 413 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false));
536 } 414 }
537 } 415 }
538 416
539 if (options.environ) 417 if (!options.environ.empty())
540 SetEnvironment(new_environ.get()); 418 SetEnvironment(new_environ.get());
541 419
542 // fd_shuffle1 is mutated by this call because it cannot malloc. 420 // fd_shuffle1 is mutated by this call because it cannot malloc.
543 if (!ShuffleFileDescriptors(&fd_shuffle1)) 421 if (!ShuffleFileDescriptors(&fd_shuffle1))
544 _exit(127); 422 _exit(127);
545 423
546 CloseSuperfluousFds(fd_shuffle2); 424 CloseSuperfluousFds(fd_shuffle2);
547 425
548 for (size_t i = 0; i < argv.size(); i++) 426 for (size_t i = 0; i < argv.size(); i++)
549 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 427 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 std::string* output, 629 std::string* output,
752 int* exit_code) { 630 int* exit_code) {
753 // Run |execve()| with the current environment and store "unlimited" data. 631 // Run |execve()| with the current environment and store "unlimited" data.
754 GetAppOutputInternalResult result = GetAppOutputInternal( 632 GetAppOutputInternalResult result = GetAppOutputInternal(
755 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true, 633 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true,
756 exit_code); 634 exit_code);
757 return result == EXECUTE_SUCCESS; 635 return result == EXECUTE_SUCCESS;
758 } 636 }
759 637
760 } // namespace base 638 } // namespace base
OLDNEW
« no previous file with comments | « base/process/launch.cc ('k') | base/process/process_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698