15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef IPC_FILE_DESCRIPTOR_SET_POSIX_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_FILE_DESCRIPTOR_SET_POSIX_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_vector.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_export.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A FileDescriptorSet is an ordered set of POSIX file descriptors. These are
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// associated with IPC messages so that descriptors can be transmitted over a
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// UNIX domain socket.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IPC_EXPORT FileDescriptorSet
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCountedThreadSafe<FileDescriptorSet> {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorSet();
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is the maximum number of descriptors per message. We need to know this
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because the control message kernel interface has to be given a buffer which
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is large enough to store all the descriptor numbers. Otherwise the kernel
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tells us that it truncated the control data and the extra descriptors are
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // lost.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In debugging mode, it's a fatal error to try and add more than this number
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of descriptors to a FileDescriptorSet.
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static const size_t kMaxDescriptorsPerMessage = 7;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------------------------------------------------------------------------
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Interfaces for building during message serialisation...
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a descriptor to the end of the set. Returns false iff the set is full.
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool AddToBorrow(base::PlatformFile fd);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a descriptor to the end of the set and automatically close it after
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transmission. Returns false iff the set is full.
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool AddToOwn(base::ScopedFD fd);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------------------------------------------------------------------------
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------------------------------------------------------------------------
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Interfaces for accessing during message deserialisation...
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the number of descriptors
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned size() const { return descriptors_.size(); }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return true if no unconsumed descriptors remain
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool empty() const { return 0 == size(); }
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Take the nth descriptor from the beginning of the set,
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // transferring the ownership of the descriptor taken. Code using this
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // /must/ access the descriptors in order, and must do it at most once.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This interface is designed for the deserialising code as it doesn't
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // support close flags.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   returns: file descriptor, or -1 on error
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::PlatformFile TakeDescriptorAt(unsigned n);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------------------------------------------------------------------------
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------------------------------------------------------------------------
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Interfaces for transmission...
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fill an array with file descriptors without 'consuming' them. CommitAll
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // must be called after these descriptors have been transmitted.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   buffer: (output) a buffer of, at least, size() integers.
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void PeekDescriptors(base::PlatformFile* buffer) const;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This must be called after transmitting the descriptors returned by
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // PeekDescriptors. It marks all the descriptors as consumed and closes those
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which are auto-close.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CommitAll();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if any contained file descriptors appear to be handles to a
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // directory.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ContainsDirectoryDescriptor() const;
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Fetch all filedescriptors with the "auto close" property.
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Used instead of CommitAll() when closing must be handled manually.
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void ReleaseFDsToClose(std::vector<base::PlatformFile>* fds);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------------------------------------------------------------------------
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------------------------------------------------------------------------
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Interfaces for receiving...
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the contents of the set from the given buffer. This set must be empty
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // before calling. The auto-close flag is set on all the descriptors so that
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unconsumed descriptors are closed on destruction.
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void AddDescriptorsToOwn(const base::PlatformFile* buffer, unsigned count);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------------------------------------------------------------------------
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCountedThreadSafe<FileDescriptorSet>;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~FileDescriptorSet();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A vector of descriptors and close flags. If this message is sent, then
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // these descriptors are sent as control data. After sending, any descriptors
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with a true flag are closed. If this message has been received, then these
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are the descriptors which were received and all close flags are true.
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<base::PlatformFile> descriptors_;
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ScopedVector<base::ScopedFD> owned_descriptors_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This contains the index of the next descriptor which should be consumed.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's used in a couple of ways. Firstly, at destruction we can check that
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all the descriptors have been read (with GetNthDescriptor). Secondly, we
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can check that they are read in order.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable unsigned consumed_descriptor_highwater_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FileDescriptorSet);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // IPC_FILE_DESCRIPTOR_SET_POSIX_H_
120