1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_GLOBAL_DESCRIPTORS_POSIX_H_
6#define BASE_GLOBAL_DESCRIPTORS_POSIX_H_
7#pragma once
8
9#include "build/build_config.h"
10
11#include <vector>
12#include <utility>
13
14#include <stdint.h>
15
16#include "base/memory/singleton.h"
17
18namespace base {
19
20// It's common practice to install file descriptors into well known slot
21// numbers before execing a child; stdin, stdout and stderr are ubiqutous
22// examples.
23//
24// However, when using a zygote model, this becomes troublesome. Since the
25// descriptors which need to be in these slots generally aren't known, any code
26// could open a resource and take one of the reserved descriptors. Simply
27// overwriting the slot isn't a viable solution.
28//
29// We could try to fill the reserved slots as soon as possible, but this is a
30// fragile solution since global constructors etc are able to open files.
31//
32// Instead, we retreat from the idea of installing descriptors in specific
33// slots and add a layer of indirection in the form of this singleton object.
34// It maps from an abstract key to a descriptor. If independent modules each
35// need to define keys, then values should be chosen randomly so as not to
36// collide.
37class GlobalDescriptors {
38 public:
39  typedef uint32_t Key;
40  typedef std::vector<std::pair<Key, int> > Mapping;
41
42  // Often we want a canonical descriptor for a given Key. In this case, we add
43  // the following constant to the key value:
44  static const int kBaseDescriptor = 3;  // 0, 1, 2 are already taken.
45
46  // Return the singleton instance of GlobalDescriptors.
47  static GlobalDescriptors* GetInstance();
48
49  // Get a descriptor given a key. It is a fatal error if the key is not known.
50  int Get(Key key) const;
51
52  // Get a descriptor give a key. Returns -1 on error.
53  int MaybeGet(Key key) const;
54
55  // Set the descriptor for the given key.
56  void Set(Key key, int fd);
57
58  void Reset(const Mapping& mapping);
59
60 private:
61  friend struct DefaultSingletonTraits<GlobalDescriptors>;
62  GlobalDescriptors();
63  ~GlobalDescriptors();
64
65  Mapping descriptors_;
66};
67
68}  // namespace base
69
70#endif  // BASE_GLOBAL_DESCRIPTORS_POSIX_H_
71