ipc/chromium/src/base/file_descriptor_shuffle.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/base/file_descriptor_shuffle.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,79 @@
     1.4 +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#ifndef BASE_FILE_DESCRIPTOR_SHUFFLE_H_
     1.9 +#define BASE_FILE_DESCRIPTOR_SHUFFLE_H_
    1.10 +
    1.11 +// This code exists to perform the shuffling of file descriptors which is
    1.12 +// commonly needed when forking subprocesses. The naive approve is very simple,
    1.13 +// just call dup2 to setup the desired descriptors, but wrong. It's tough to
    1.14 +// handle the edge cases (like mapping 0 -> 1, 1 -> 0) correctly.
    1.15 +//
    1.16 +// In order to unittest this code, it's broken into the abstract action (an
    1.17 +// injective multimap) and the concrete code for dealing with file descriptors.
    1.18 +// Users should use the code like this:
    1.19 +//   base::InjectiveMultimap file_descriptor_map;
    1.20 +//   file_descriptor_map.push_back(base::InjectionArc(devnull, 0, true));
    1.21 +//   file_descriptor_map.push_back(base::InjectionArc(devnull, 2, true));
    1.22 +//   file_descriptor_map.push_back(base::InjectionArc(pipe[1], 1, true));
    1.23 +//   base::ShuffleFileDescriptors(file_descriptor_map);
    1.24 +//
    1.25 +// and trust the the Right Thing will get done.
    1.26 +
    1.27 +#include <vector>
    1.28 +
    1.29 +namespace base {
    1.30 +
    1.31 +// A Delegate which performs the actions required to perform an injective
    1.32 +// multimapping in place.
    1.33 +class InjectionDelegate {
    1.34 + public:
    1.35 +  // Duplicate |fd|, an element of the domain, and write a fresh element of the
    1.36 +  // domain into |result|. Returns true iff successful.
    1.37 +  virtual bool Duplicate(int* result, int fd) = 0;
    1.38 +  // Destructively move |src| to |dest|, overwriting |dest|. Returns true iff
    1.39 +  // successful.
    1.40 +  virtual bool Move(int src, int dest) = 0;
    1.41 +  // Delete an element of the domain.
    1.42 +  virtual void Close(int fd) = 0;
    1.43 +};
    1.44 +
    1.45 +// An implementation of the InjectionDelegate interface using the file
    1.46 +// descriptor table of the current process as the domain.
    1.47 +class FileDescriptorTableInjection : public InjectionDelegate {
    1.48 +  bool Duplicate(int* result, int fd);
    1.49 +  bool Move(int src, int dest);
    1.50 +  void Close(int fd);
    1.51 +};
    1.52 +
    1.53 +// A single arc of the directed graph which describes an injective multimapping.
    1.54 +struct InjectionArc {
    1.55 +  InjectionArc(int in_source, int in_dest, bool in_close)
    1.56 +      : source(in_source),
    1.57 +        dest(in_dest),
    1.58 +        close(in_close) {
    1.59 +  }
    1.60 +
    1.61 +  int source;
    1.62 +  int dest;
    1.63 +  bool close;  // if true, delete the source element after performing the
    1.64 +               // mapping.
    1.65 +};
    1.66 +
    1.67 +typedef std::vector<InjectionArc> InjectiveMultimap;
    1.68 +
    1.69 +bool PerformInjectiveMultimap(const InjectiveMultimap& map,
    1.70 +                              InjectionDelegate* delegate);
    1.71 +bool PerformInjectiveMultimapDestructive(InjectiveMultimap* map,
    1.72 +                                         InjectionDelegate* delegate);
    1.73 +
    1.74 +// This function will not call malloc but will mutate |map|
    1.75 +static inline bool ShuffleFileDescriptors(InjectiveMultimap *map) {
    1.76 +  FileDescriptorTableInjection delegate;
    1.77 +  return PerformInjectiveMultimapDestructive(map, &delegate);
    1.78 +}
    1.79 +
    1.80 +}  // namespace base
    1.81 +
    1.82 +#endif  // !BASE_FILE_DESCRIPTOR_SHUFFLE_H_

mercurial