The Pedigree Project  0.1
FileDescriptor.cc
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 #include "FileDescriptor.h"
21 #include "net-syscalls.h" // to get destructor for SharedPointer<NetworkSyscalls>
22 
23 #include "modules/subsys/posix/IoEvent.h"
24 #include "modules/system/vfs/File.h"
25 
26 #include <fcntl.h>
27 
28 #define ENABLE_LOCKED_FILES 0
29 
30 #if ENABLE_LOCKED_FILES
31 RadixTree<LockedFile *> g_PosixGlobalLockedFiles;
32 #endif
33 
36  : file(0), offset(0), fd(0xFFFFFFFF), lockedFile(0), networkImpl(nullptr),
37  ioevent(nullptr), fdflags(0), flflags(0)
38 {
39 }
40 
43  File *newFile, uint64_t newOffset, size_t newFd, int fdFlags, int flFlags,
44  LockedFile *lf)
45  : file(newFile), offset(newOffset), fd(newFd), lockedFile(lf),
46  networkImpl(nullptr), ioevent(nullptr), fdflags(fdFlags), flflags(flFlags)
47 {
49  if (file)
50  {
51 #if ENABLE_LOCKED_FILES
52  lockedFile = g_PosixGlobalLockedFiles.lookup(file->getFullPath());
53 #endif
54  file->increaseRefCount((flflags & O_RDWR) || (flflags & O_WRONLY));
55  }
56 }
57 
60  : file(desc.file), offset(desc.offset), fd(desc.fd), lockedFile(0),
61  networkImpl(desc.networkImpl), ioevent(nullptr), fdflags(desc.fdflags),
62  flflags(desc.flflags)
63 {
64  if (file)
65  {
66 #if ENABLE_LOCKED_FILES
67  lockedFile = g_PosixGlobalLockedFiles.lookup(file->getFullPath());
68 #endif
69  file->increaseRefCount((flflags & O_RDWR) || (flflags & O_WRONLY));
70  }
71 
72 #ifdef THREADS
73  if (desc.ioevent)
74  {
75  ioevent = new IoEvent(*desc.ioevent);
76  }
77 #endif
78 }
79 
82  : file(0), offset(0), fd(0), lockedFile(0), ioevent(nullptr), fdflags(0),
83  flflags(0)
84 {
85  if (!desc)
86  return;
87 
88  file = desc->file;
89  offset = desc->offset;
90  fd = desc->fd;
91  fdflags = desc->fdflags;
92  flflags = desc->flflags;
93  networkImpl = desc->networkImpl;
94  if (file)
95  {
96 #if ENABLE_LOCKED_FILES
97  lockedFile = g_PosixGlobalLockedFiles.lookup(file->getFullPath());
98 #endif
99  file->increaseRefCount((flflags & O_RDWR) || (flflags & O_WRONLY));
100  }
101 
102 #ifdef THREADS
103  if (desc->ioevent)
104  {
105  ioevent = new IoEvent(*desc->ioevent);
106  }
107 #endif
108 }
109 
112 {
113  file = desc.file;
114  offset = desc.offset;
115  fd = desc.fd;
116  fdflags = desc.fdflags;
117  flflags = desc.flflags;
118  networkImpl = desc.networkImpl;
119  if (file)
120  {
121 #if ENABLE_LOCKED_FILES
122  lockedFile = g_PosixGlobalLockedFiles.lookup(file->getFullPath());
123 #endif
124  file->increaseRefCount((flflags & O_RDWR) || (flflags & O_WRONLY));
125  }
126 #ifdef THREADS
127  if (desc.ioevent)
128  {
129  ioevent = new IoEvent(*desc.ioevent);
130  }
131  else
132  {
133  ioevent = nullptr;
134  }
135 #endif
136  return *this;
137 }
138 
141 {
142  if (file)
143  {
144 #if ENABLE_LOCKED_FILES
145  // Unlock the file we have a lock on, release from the global lock table
146  if (lockedFile)
147  {
148  g_PosixGlobalLockedFiles.remove(file->getFullPath());
149  lockedFile->unlock();
150  delete lockedFile;
151  }
152 #endif
153  file->decreaseRefCount((flflags & O_RDWR) || (flflags & O_WRONLY));
154  }
155 #ifdef THREADS
156  if (ioevent)
157  {
158  if (networkImpl)
159  {
160  networkImpl->unmonitor(ioevent);
161  }
162  delete ioevent;
163  }
164 #endif
165 
168 
169  if (networkImpl)
170  {
171  if (networkImpl->getFileDescriptor() == this)
172  {
173  // disassociate from this descriptor
174  networkImpl->associate(nullptr);
175  }
176  }
177 }
178 
179 void FileDescriptor::setFlags(int newFlags)
180 {
181  fdflags = newFlags;
182 }
183 
184 void FileDescriptor::addFlag(int newFlag)
185 {
186  setFlags(fdflags | newFlag);
187 }
188 
190 {
191  return fdflags;
192 }
193 
195 {
196  flflags = newFlags;
197 
198  if (networkImpl)
199  {
204  bool nonblock = (flflags & O_NONBLOCK) == O_NONBLOCK;
205  networkImpl->setBlocking(!nonblock);
206  }
207 }
208 
210 {
211  setFlags(flflags | newFlag);
212 }
213 
215 {
216  return flflags;
217 }
uint64_t offset
Offset within the file for I/O.
LockedFile * lockedFile
Locked file, non-zero if there is an advisory lock on the file.
A key/value dictionary for string keys.
Definition: RadixTree.h:45
void setFlags(int newFlags)
Set flags, distributing any associated changes as needed.
SharedPointer< class NetworkSyscalls > networkImpl
Network syscall implementation for this descriptor (if it&#39;s a socket).
void addFlag(int newFlag)
Helper to add a single flag to the descriptor flags.
virtual ~FileDescriptor()
Destructor - decreases file reference count.
int getFlags() const
Get current descriptor flags.
int getStatusFlags() const
Get current status flags.
size_t fd
Descriptor number.
File * file
Our open file pointer.
Result< T, bool > lookup(const String &key) const
Definition: RadixTree.h:462
virtual String getFullPath(bool bWithLabel=true)
Definition: File.cc:718
int flflags
File status flags (fcntl)
void addStatusFlag(int newFlag)
Helper to add a single flag to the status flags.
FileDescriptor & operator=(FileDescriptor &desc)
Assignment operator implementation.
void setStatusFlags(int newFlags)
Set status flags, distributing any associated changes as needed.
int fdflags
File descriptor flags (fcntl)
IoEvent * ioevent
IO event for reporting changes to files.
FileDescriptor()
Default constructor.
void unlock()
Definition: LockedFile.cc:76
void remove(const String &key)
Definition: RadixTree.h:511
Definition: File.h:66