The Pedigree Project  0.1
UnixFilesystem.h
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef _UNIX_FILESYSTEM_H
21 #define _UNIX_FILESYSTEM_H
22 
23 #include "modules/system/vfs/Directory.h"
24 #include "modules/system/vfs/File.h"
25 #include "modules/system/vfs/Filesystem.h"
26 
27 #include "pedigree/kernel/utilities/Buffer.h"
28 #include "pedigree/kernel/utilities/RingBuffer.h"
29 
30 #include <sys/socket.h>
31 
32 class Mutex;
33 
34 #define MAX_UNIX_DGRAM_BACKLOG 65536
35 #define MAX_UNIX_STREAM_QUEUE 65536
36 
43 class UnixFilesystem : public Filesystem
44 {
45  public:
47  virtual ~UnixFilesystem();
48 
49  virtual bool initialise(Disk *pDisk)
50  {
51  return false;
52  }
53 
54  virtual File *getRoot() const
55  {
56  return m_pRoot;
57  }
58 
59  virtual String getVolumeLabel() const
60  {
61  return m_VolumeLabel;
62  }
63 
64  virtual void truncate(File *pFile)
65  {
66  }
67 
68  virtual void fileAttributeChanged(File *pFile)
69  {
70  }
71 
72  virtual void cacheDirectoryContents(File *pFile)
73  {
74  if (pFile->isDirectory())
75  {
76  Directory *pDir = Directory::fromFile(pFile);
77  pDir->cacheDirectoryContents();
78  }
79  }
80 
81  virtual void extend(File *pFile, size_t size)
82  {
83  }
84 
85  protected:
86  virtual bool
87  createFile(File *parent, const String &filename, uint32_t mask);
88  virtual bool
89  createDirectory(File *parent, const String &filename, uint32_t mask);
90  virtual bool
91  createSymlink(File *parent, const String &filename, const String &value)
92  {
93  return false;
94  }
95  virtual bool remove(File *parent, File *file);
96 
97  private:
98  File *m_pRoot;
99 
100  static String m_VolumeLabel;
101 
102  virtual bool isBytewise() const
103  {
104  return true;
105  }
106 };
107 
111 class UnixSocket : public File
112 {
113  public:
114  enum SocketType
115  {
116  Streaming,
117  Datagram
118  };
119 
120  enum SocketState
121  {
122  Listening, // listening for connections
123  Connecting, // waiting for bind to be acked
124  Inactive, // unbound
125  Active, // bound, ready for data transfer
126  Closed // unbound but was once bound
127  };
128 
129  UnixSocket(
130  String name, Filesystem *pFs, File *pParent,
131  UnixSocket *other = nullptr, SocketType type = Datagram);
132  virtual ~UnixSocket();
133 
134  virtual uint64_t readBytewise(
135  uint64_t location, uint64_t size, uintptr_t buffer,
136  bool bCanBlock = true);
137  virtual uint64_t writeBytewise(
138  uint64_t location, uint64_t size, uintptr_t buffer,
139  bool bCanBlock = true);
140 
141  uint64_t
142  recvfrom(uint64_t size, uintptr_t buffer, bool bCanBlock, String &from);
143 
144  virtual int select(bool bWriting = false, int timeout = 0);
145 
146  virtual bool isSocket() const
147  {
148  return true;
149  }
150 
151  UnixSocket *getOther() const
152  {
153  return m_pOther;
154  }
155 
156  // Bind this socket to another socket.
157  // The other socket should not already be bound.
158  bool bind(UnixSocket *other, bool block = false);
159 
160  // Break the bound socket.
161  void unbind();
162 
163  // Acknowledges binding from another socket
164  void acknowledgeBind();
165 
166  // Add a new socket for a client/server connection (for accept())
167  void addSocket(UnixSocket *socket);
168 
169  // Get the next socket in the listening queue (for non-datagram sockets).
170  UnixSocket *getSocket(bool block = false);
171 
172  // Add a semaphore to be notified when the socket data changes.
173  void addWaiter(Semaphore *waiter);
174 
175  // Remove a waiter semaphore.
176  void removeWaiter(Semaphore *waiter);
177 
178  // Add an event to fire when the socket data changes.
179  void addWaiter(Thread *thread, Event *event);
180 
181  // Remove a socket data change event.
182  void removeWaiter(Event *event);
183 
184  // Get this socket's type
185  SocketType getType() const
186  {
187  return m_Type;
188  }
189 
190  // Get this socket's state
191  SocketState getState() const
192  {
193  return m_State;
194  }
195 
196  // Mark this socket a listening socket
197  bool markListening();
198 
199  // Get our credentials.
200  struct ucred getCredentials() const
201  {
202  return m_Creds;
203  }
204 
205  // Get the credentials of the other side.
206  struct ucred getPeerCredentials() const
207  {
208  return m_pOther->getCredentials();
209  }
210 
211  private:
213 
214  void setCreds();
215 
216  virtual bool isBytewise() const
217  {
218  return true;
219  }
220 
221  struct buf
222  {
223  char *pBuffer;
224  uint64_t len;
225  char *remotePath; // Path of the socket that dumped data here, if any.
226  };
227 
228  SocketType m_Type;
229  SocketState m_State;
230 
231  // For datagram sockets.
232 
233  // Note: "servers" own the actual UNIX socket address, while clients get a
234  // virtual address to track their existence (or are bound to a specific
235  // name themselves).
236  RingBuffer<struct buf *> m_Datagrams;
237 
238  // For stream sockets.
239 
240  // Other side of the connection (for stream sockets).
241  UnixSocket *m_pOther;
242 
243  // Data stream.
244  UnixSocketStream m_Stream;
245 
246  // List of sockets pending accept() on this socket.
247  List<UnixSocket *> m_PendingSockets;
248 
249  // Mutual exclusion for this socket.
250  Mutex m_Mutex;
251 
252  // Ack waiter lock
253 #ifdef THREADS
254  Semaphore m_AckWaiter;
255 #endif
256 
257  // Credentials associated at the time of bind()
258  struct ucred m_Creds;
259 };
260 
264 class UnixDirectory : public Directory
265 {
266  public:
267  UnixDirectory(String name, Filesystem *pFs, File *pParent);
268  virtual ~UnixDirectory();
269 
270  bool addEntry(String filename, File *pFile);
271  bool removeEntry(File *pFile);
272 
273  virtual void cacheDirectoryContents();
274 
275  private:
276  Mutex m_Lock;
277 };
278 
279 #endif
virtual bool createDirectory(File *parent, const String &filename, uint32_t mask)
virtual bool createFile(File *parent, const String &filename, uint32_t mask)
static Directory * fromFile(File *pF)
Definition: Directory.h:50
Definition: Mutex.h:58
Definition: String.h:49
virtual bool isSocket() const
virtual bool initialise(Disk *pDisk)
Definition: Disk.h:32
virtual bool createSymlink(File *parent, const String &filename, const String &value)
virtual File * getRoot() const
virtual String getVolumeLabel() const
Definition: Thread.h:54
Definition: Event.h:48
virtual bool isDirectory()
Definition: File.cc:436
Utility class to provide a ring buffer.
Definition: RingBuffer.h:61
virtual void cacheDirectoryContents()
Definition: Directory.cc:85
Definition: File.h:66
virtual bool isBytewise() const