ns-3 Direct Code Execution
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dce-fd.cc
Go to the documentation of this file.
1 #define _LARGEFILE64_SOURCE 1
2 #include "dce-manager.h"
3 #include "process.h"
4 #include "utils.h"
5 #include "unix-fd.h"
6 #include "unix-file-fd.h"
7 #include "socket-fd-factory.h"
8 #include "waiter.h"
9 #include "dce-fcntl.h"
10 #include "dce-unistd.h"
11 #include "dce-poll.h"
12 #include "dce-stdio.h"
13 #include "sys/dce-socket.h"
14 #include "sys/dce-ioctl.h"
15 #include "sys/dce-stat.h"
16 #include "sys/dce-mman.h"
17 #include "sys/dce-select.h"
18 #include "ns3/log.h"
19 #include "ns3/event-id.h"
20 #include "ns3/simulator.h"
21 #include "ns3/nstime.h"
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <linux/netlink.h>
25 #include <linux/rtnetlink.h>
26 #include <sys/mman.h>
27 #include <sys/types.h>
28 #include "ns3/node.h"
30 #include "ns3-socket-fd-factory.h"
31 #include "file-usage.h"
32 #include "dce-stdlib.h"
33 #include "pipe-fd.h"
34 
35 NS_LOG_COMPONENT_DEFINE ("SimuFd");
36 
37 
38 #ifdef _K_SS_MAXSIZE
39 #define SOCK_MAX_ADDRESS_SIZE _K_SS_MAXSIZE
40 #else
41 #define SOCK_MAX_ADDRESS_SIZE 128
42 #endif
43 
44 #define DEFINE_FORWARDER_PATH(name, pathname, ...) \
45  { \
46  Thread *current = Current (); \
47  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << pathname); \
48  NS_ASSERT (Current () != 0); \
49  \
50  if (std::string (pathname) == std::string ("")) \
51  { \
52  current->err = ENOENT; \
53  return -1; \
54  } \
55  std::string fullpath = UtilsGetRealFilePath (pathname); \
56  int status = ::name (fullpath.c_str (), ## __VA_ARGS__); \
57  if (status == -1) \
58  { \
59  current->err = errno; \
60  return -1; \
61  } \
62  return status; \
63  }
64 
65 
66 using namespace ns3;
67 int dce_open64 (const char *path, int flags, ...)
68 {
69  va_list vl;
70  va_start (vl, flags);
71  // hope this trick actually works...
72  int status = dce_open (path, flags, vl);
73  va_end (vl);
74 
75  return status;
76 }
77 
78 int dce_open (const char *path, int flags, ...)
79 {
80  va_list vl;
81  va_start (vl, flags);
82 
83  mode_t mode = 0;
84  if (flags & O_CREAT)
85  {
86  mode = va_arg (vl, mode_t);
87  }
88  va_end (vl);
89  Thread *current = Current ();
90  NS_LOG_FUNCTION (current << UtilsGetNodeId () << path << flags);
91  NS_ASSERT (current != 0);
92 
93  if (std::string (path) == "")
94  {
95  current->err = ENOENT;
96  return -1;
97  }
98 
99  int fd = UtilsAllocateFd ();
100  if (fd == -1)
101  {
102  current->err = EMFILE;
103  return -1;
104  }
105  UnixFd *unixFd = 0;
106 
107  if ((std::string (path) == "/dev/random") || (std::string (path) == "/dev/urandom")
108  || (std::string (path) == "/dev/srandom"))
109  {
110  unixFd = new UnixRandomFd (path);
111  }
112  else
113  {
114  std::string fullpath = UtilsGetRealFilePath (path);
115 
116  int realFd = ::open (fullpath.c_str (), flags, mode);
117  if (realFd == -1)
118  {
119  current->err = errno;
120  return -1;
121  }
122 
123  if (((2 == fd) || (1 == fd)) && (Current ()->process->minimizeFiles))
124  {
125  unixFd = new UnixFileFdLight (fullpath);
126  close (realFd);
127  }
128  else
129  {
130  unixFd = new UnixFileFd (realFd);
131  }
132  }
133  unixFd->IncFdCount ();
134  current->process->openFiles[fd] = new FileUsage (fd, unixFd);
135  return fd;
136 }
137 
138 int dce_creat (const char *path, mode_t mode)
139 {
140  return dce_open (path, O_CREAT | O_WRONLY | O_TRUNC, mode);
141 }
142 
143 int dce_unlink_real (const char *pathname)
144 {
145  DEFINE_FORWARDER_PATH (unlink, pathname);
146 }
147 
148 void unlink_notify (std::string fullpath)
149 {
150  NS_LOG_FUNCTION ("UNLINK FULL PATH " << fullpath);
151 
152  Ptr<SocketFdFactory> factory = Current ()->process->manager->GetObject<LocalSocketFdFactory> ();
153 
154  if (0 != factory)
155  {
156  factory->UnlinkNotify (fullpath);
157  }
158  factory = Current ()->process->manager->GetObject<SocketFdFactory> ();
159  if (0 != factory)
160  {
161  factory->UnlinkNotify (fullpath);
162  }
163 }
164 
165 int dce_unlink (const char *pathname)
166 {
167  NS_LOG_FUNCTION (pathname);
168  int ret = dce_unlink_real (pathname);
169 
170  if (0 == ret)
171  {
172  std::string fullpath = UtilsGetRealFilePath (pathname);
173 
174  unlink_notify (fullpath);
175  }
176 
177  return ret;
178 }
179 int dce_mkdir (const char *pathname, mode_t mode)
180 {
181  mode_t m = (mode & ~(Current ()->process->uMask));
182  DEFINE_FORWARDER_PATH (mkdir, pathname, m);
183 }
184 int dce_rmdir (const char *pathname)
185 {
186  DEFINE_FORWARDER_PATH (rmdir, pathname);
187 }
188 int dce_access (const char *pathname, int mode)
189 {
190  DEFINE_FORWARDER_PATH (access, pathname, mode);
191 }
192 int dce_close (int fd)
193 {
194  int retval = 0;
195  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << fd);
196  NS_ASSERT (Current () != 0);
197  Thread *current = Current ();
198  std::map<int,FileUsage *>::iterator it = current->process->openFiles.find (fd);
199 
200  if (it == current->process->openFiles.end ())
201  {
202  current->err = EBADF;
203  return -1;
204  }
205 
206  FileUsage *fu = current->process->openFiles[fd];
207 
208  if (fu->GetFile () && (1 == fu->GetFile ()->GetFdCount ()))
209  {
210  // If only one process point to file we can really close it
211  // else we be closed while the last process close it
212  retval = fu->GetFile ()->Close ();
213  }
214  if (fu->CanForget ())
215  {
216  // If no thread of this process is using it we can free the corresponding fd entry
217  // else we be freed by last thread renoncing of using it
218  current->process->openFiles.erase (fd);
219  delete fu;
220  fu = 0;
221  }
222 
223  return retval;
224 }
225 
226 int dce_isatty (int fd)
227 {
228  Thread *current = Current ();
229  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd);
230  NS_ASSERT (current != 0);
231 
232  OPENED_FD_METHOD (int, Isatty ());
233 }
234 char* dce_ttyname (int fd)
235 {
236  Thread *current = Current ();
237  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd);
238  NS_ASSERT (current != 0);
239 
240  OPENED_FD_METHOD (char*, Ttyname ());
241 }
242 ssize_t dce_send (int fd, const void *buf, size_t len, int flags)
243 {
244  NS_LOG_FUNCTION (fd << buf << len << flags);
245  return dce_sendto (fd, buf, len, flags, 0, 0);
246 }
247 ssize_t dce_sendto (int fd, const void *buf, size_t len, int flags,
248  const struct sockaddr *to, socklen_t tolen)
249 {
250  NS_LOG_FUNCTION (Current () << fd << buf << len << flags << to << tolen);
251  NS_ASSERT (Current () != 0);
252  struct msghdr msg;
253  struct iovec iov;
254  msg.msg_control = 0;
255  msg.msg_controllen = 0;
256  msg.msg_iovlen = 1;
257  msg.msg_iov = &iov;
258  iov.iov_len = len;
259  iov.iov_base = (void *)buf;
260  msg.msg_name = (void *)to;
261  msg.msg_namelen = tolen;
262  ssize_t retval = dce_sendmsg (fd, &msg, flags);
263  return retval;
264 }
265 
266 ssize_t dce_sendmsg (int fd, const struct msghdr *msg, int flags)
267 {
268  Thread *current = Current ();
269  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << msg << flags);
270  NS_ASSERT (current != 0);
271 
272  OPENED_FD_METHOD (ssize_t, Sendmsg (msg, flags))
273 }
274 
275 int dce_ioctl (int fd, long unsigned int request, ...)
276 {
277  va_list vl;
278  va_start (vl, request);
279  char *argp = va_arg (vl, char*);
280  va_end (vl);
281 
282  Thread *current = Current ();
283  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << request << argp);
284  NS_ASSERT (current != 0);
285 
286  OPENED_FD_METHOD (int, Ioctl (request, argp))
287 }
288 ssize_t dce_write (int fd, const void *buf, size_t count)
289 {
290  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << fd << buf << count);
291  Thread *current = Current ();
292  NS_ASSERT (current != 0);
293 
294  OPENED_FD_METHOD (int, Write (buf, count))
295 }
296 
297 ssize_t dce_writev (int fd, const struct iovec *iov, int iovcnt)
298 {
299  Thread *current = Current ();
300  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << iov << iovcnt);
301  NS_ASSERT (current != 0);
302 
303  if (!CheckFdExists (current->process, fd, true))
304  {
305  NS_LOG_DEBUG ("write error");
306  current->err = EBADF;
307  return -1;
308  }
309 
310  size_t count = 0;
311  for (int i = 0; i < iovcnt; ++i)
312  {
313  count += iov[i].iov_len;
314  }
315 
316  if (count == 0)
317  {
318  current->err = EINVAL;
319  return -1;
320  }
321 
322  char buf[count], *bufp = buf;
323  for (int i = 0; i < iovcnt; ++i)
324  {
325  memcpy (bufp, iov[i].iov_base, iov[i].iov_len);
326  bufp += iov[i].iov_len;
327  }
328 
329  UnixFd *unixFd = current->process->openFiles[fd]->GetFileInc ();
330  int retval = unixFd->Write (buf, count);
331  FdDecUsage (fd);
332 
333  return retval;
334 }
335 
336 ssize_t dce_read (int fd, void *buf, size_t count)
337 {
338  Thread *current = Current ();
339  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << buf << count);
340  NS_ASSERT (current != 0);
341 
342  OPENED_FD_METHOD (int, Read (buf, count))
343 }
344 int dce_socket (int domain, int type, int protocol)
345 {
346  Thread *current = Current ();
347  DceManager *manager = current->process->manager;
348  NS_LOG_FUNCTION (current << UtilsGetNodeId () << domain << type << protocol);
349  NS_ASSERT (current != 0);
350  NS_ASSERT (manager != 0);
351 
352  Ptr<SocketFdFactory> factory = 0;
353 
354  if (domain != AF_UNIX)
355  {
356  factory = manager->GetObject<SocketFdFactory> ();
357  }
358  else
359  {
360  if (type != SOCK_DGRAM && type != SOCK_STREAM)
361  {
362  current->err = EINVAL;
363  return -1;
364  }
365  factory = manager->GetObject<LocalSocketFdFactory> ();
366  }
367  UnixFd *socket = factory->CreateSocket (domain, type, protocol);
368  if (!socket)
369  {
370 
371  current->err = EINVAL;
372  return -1;
373  }
374 
375  int fd = UtilsAllocateFd ();
376  if (fd == -1)
377  {
378  current->err = EMFILE;
379  return -1;
380  }
381  if (!socket)
382  {
383  return -1;
384  }
385  socket->IncFdCount ();
386  current->process->openFiles[fd] = new FileUsage (fd, socket);
387 
388  return fd;
389 }
390 ssize_t dce_readv (int fd, const struct iovec *iov, int iovcnt)
391 {
392  Thread *current = Current ();
393  ssize_t ret = 0;
394 
395  if ((0 == iov)||(iovcnt < 0))
396  {
397  current->err = EINVAL;
398  return -1;
399  }
400  for (int b = 0; b < iovcnt; b++)
401  {
402  ssize_t r = dce_read (fd, iov[b].iov_base, iov[b].iov_len);
403  if (r >= 0)
404  {
405  ret += r;
406  if (!r || (r < (ssize_t)iov[b].iov_len))
407  {
408  return ret;
409  }
410  }
411  else
412  {
413  return -1;
414  }
415  }
416  return ret;
417 }
418 int dce_socketpair (int domain, int type, int protocol, int sv[2])
419 {
420  sv[0] = dce_socket (domain, type, protocol);
421  if (sv[0] < 0)
422  {
423  return -1;
424  }
425 
426  sv[1] = dce_socket (domain, type, protocol);
427  if (sv[1] < 0)
428  {
429  return -1;
430  }
431 
432  return 0;
433 }
434 
435 int dce_bind (int fd, const struct sockaddr *my_addr, socklen_t addrlen)
436 {
437  Thread *current = Current ();
438  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << my_addr << addrlen);
439  NS_ASSERT (current != 0);
440 
441  OPENED_FD_METHOD (int, Bind (my_addr, addrlen))
442 }
443 int dce_connect (int fd, const struct sockaddr *my_addr, socklen_t addrlen)
444 {
445  Thread *current = Current ();
446  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << my_addr << addrlen);
447  NS_ASSERT (current != 0);
448 
449  OPENED_FD_METHOD (int, Connect (my_addr, addrlen))
450 }
451 int dce_listen (int fd, int backlog)
452 {
453  Thread *current = Current ();
454  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << backlog);
455  NS_ASSERT (current != 0);
456 
457  OPENED_FD_METHOD (int, Listen (backlog))
458 }
459 int dce_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
460 {
461  Thread *current = Current ();
462  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << addr << addrlen);
463  NS_ASSERT (current != 0);
464 
465  OPENED_FD_METHOD (int, Accept (addr, addrlen))
466 }
467 int dce_shutdown (int fd, int how)
468 {
469  Thread *current = Current ();
470  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << how);
471  NS_ASSERT (current != 0);
472 
473  OPENED_FD_METHOD (int, Shutdown (how))
474 }
475 ssize_t dce_recv (int fd, void *buf, size_t count, int flags)
476 {
477  NS_LOG_FUNCTION (fd << buf << count << flags);
478  return dce_recvfrom (fd, buf, count, flags, 0, 0);
479 }
480 ssize_t dce_recvfrom (int fd, void *buf, size_t len, int flags,
481  struct sockaddr *from, socklen_t *fromlen)
482 {
483  NS_LOG_FUNCTION (fd << buf << len << flags << from << fromlen);
484  uint8_t address[SOCK_MAX_ADDRESS_SIZE];
485  struct msghdr msg;
486  struct iovec iov;
487  msg.msg_control = 0;
488  msg.msg_controllen = 0;
489  msg.msg_iovlen = 1;
490  msg.msg_iov = &iov;
491  iov.iov_len = len;
492  iov.iov_base = buf;
493  msg.msg_name = address;
494  msg.msg_namelen = SOCK_MAX_ADDRESS_SIZE;
495  ssize_t retval = dce_recvmsg (fd, &msg, flags);
496  if (retval != -1 && from != 0)
497  {
498  if (*fromlen < msg.msg_namelen)
499  {
500  Thread *current = Current ();
501  current->err = EINVAL;
502  return -1;
503  }
504  else
505  {
506  *fromlen = msg.msg_namelen;
507  memcpy (from, msg.msg_name, msg.msg_namelen);
508  }
509  }
510  return retval;
511 }
512 ssize_t dce_recvmsg (int fd, struct msghdr *msg, int flags)
513 {
514  Thread *current = Current ();
515  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << msg << flags);
516  NS_ASSERT (current != 0);
517 
518  OPENED_FD_METHOD (ssize_t, Recvmsg (msg, flags))
519 }
520 int dce_setsockopt (int fd, int level, int optname,
521  const void *optval, socklen_t optlen)
522 {
523  Thread *current = Current ();
524  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << level << optname << optval << optlen);
525  NS_ASSERT (current != 0);
526 
527  OPENED_FD_METHOD (int, Setsockopt (level, optname, optval, optlen))
528 }
529 int dce_getsockopt (int fd, int level, int optname,
530  void *optval, socklen_t *optlen)
531 {
532  Thread *current = Current ();
533  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << level << optname << optval << optlen);
534  NS_ASSERT (current != 0);
535 
536  OPENED_FD_METHOD (int, Getsockopt (level, optname, optval, optlen))
537 }
538 int dce_getsockname (int fd, struct sockaddr *name, socklen_t *namelen)
539 {
540  Thread *current = Current ();
541  NS_LOG_FUNCTION (current << UtilsGetNodeId () << name << namelen);
542  NS_ASSERT (current != 0);
543 
544  OPENED_FD_METHOD (int, Getsockname (name, namelen))
545 }
546 int dce_getpeername (int fd, struct sockaddr *name, socklen_t *namelen)
547 {
548  Thread *current = Current ();
549  NS_LOG_FUNCTION (current << UtilsGetNodeId () << name << namelen);
550  NS_ASSERT (current != 0);
551 
552  OPENED_FD_METHOD (int, Getpeername (name, namelen))
553 }
554 int dce_dup (int oldfd)
555 {
556  Thread *current = Current ();
557  NS_LOG_FUNCTION (current << UtilsGetNodeId () << oldfd);
558  NS_ASSERT (current != 0);
559 
560  if (!CheckFdExists (current->process, oldfd, true))
561  {
562  current->err = EBADF;
563  return -1;
564  }
565  int fd = UtilsAllocateFd ();
566  if (fd == -1)
567  {
568  current->err = EMFILE;
569  return -1;
570  }
571 
572  UnixFd *unixFd = current->process->openFiles[oldfd]->GetFile ();
573  unixFd->IncFdCount ();
574  unixFd->Ref ();
575  current->process->openFiles[fd] = new FileUsage (fd, unixFd);
576 
577  return fd;
578 }
579 int dce_dup2 (int oldfd, int newfd)
580 {
581  Thread *current = Current ();
582  NS_LOG_FUNCTION (current << UtilsGetNodeId () << oldfd << newfd);
583  NS_ASSERT (current != 0);
584  if (!CheckFdExists (current->process, oldfd, true) || (newfd > MAX_FDS))
585  {
586  current->err = EBADF;
587  return -1;
588  }
589 
590  if (oldfd == newfd)
591  {
592  return newfd;
593  }
594  if (CheckFdExists (current->process, newfd, true))
595  {
596  if (dce_close (newfd))
597  {
598  current->err = EBADF;
599  return -1;
600  }
601  }
602  if (CheckFdExists (current->process, newfd, false))
603  {
604  current->err = EBADF;
605  return -1;
606  }
607 
608  UnixFd *unixFd = current->process->openFiles[oldfd]->GetFile ();
609  unixFd->IncFdCount ();
610  unixFd->Ref ();
611  current->process->openFiles[newfd] = new FileUsage (newfd, unixFd);
612 
613  return newfd;
614 }
615 void * dce_mmap (void *addr, size_t length, int prot, int flags,
616  int fd, off_t offset)
617 {
618  return dce_mmap64 (addr, length, prot, flags, fd, offset);
619 }
620 
621 void * dce_mmap64 (void *start, size_t length, int prot, int flags,
622  int fd, off64_t offset)
623 {
624  Thread *current = Current ();
625  NS_LOG_FUNCTION (current << UtilsGetNodeId () << start << length << prot << flags << fd << offset);
626  NS_ASSERT (current != 0);
627 
628  OPENED_FD_METHOD_ERR (MAP_FAILED, void *, Mmap (start, length, prot, flags, offset))
629 }
630 int dce_munmap (void *start, size_t length)
631 {
632  Thread *current = Current ();
633  NS_LOG_FUNCTION (current << UtilsGetNodeId () << start << length);
634  NS_ASSERT (current != 0);
635  int retval = ::munmap (start, length);
636  if (retval == -1)
637  {
638  current->err = errno;
639  return -1;
640  }
641  return 0;
642 }
643 off_t dce_lseek (int fildes, off_t offset, int whence)
644 {
645  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << fildes << offset << whence);
646  return dce_lseek64 (fildes, offset, whence);
647 }
648 off64_t dce_lseek64 (int fd, off64_t offset, int whence)
649 {
650  Thread *current = Current ();
651  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << offset << whence);
652  NS_ASSERT (current != 0);
653 
654  OPENED_FD_METHOD (int, Lseek (offset, whence))
655 }
656 int dce_fcntl (int fd, int cmd, ... /*unsigned long arg*/)
657 {
658  va_list vl;
659  va_start (vl, cmd);
660  unsigned long arg = va_arg (vl, unsigned long);
661  va_end (vl);
662 
663  NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << fd << cmd << arg);
664  NS_ASSERT (Current () != 0);
665  Thread *current = Current ();
666  // XXX: we should handle specially some fcntl commands.
667  // For example, FD_DUP, etc.
668 
669  switch (cmd)
670  {
671  case F_DUPFD:
672  {
673  return dce_dup (fd);
674  }
675  }
676 
677 
678  OPENED_FD_METHOD (int, Fcntl (cmd, arg))
679 }
680 
681 int dce_truncate (const char *path, off_t length)
682 {
683  Thread *current = Current ();
684  NS_ASSERT (current != 0);
685  NS_LOG_FUNCTION (current << UtilsGetNodeId () << path << length);
686 
687  int fd = dce_open (path, O_WRONLY, 0);
688  if (fd == -1)
689  {
690  current->err = errno;
691  return -1;
692  }
693 
694  return dce_ftruncate (fd, length);
695 }
696 
697 int dce_ftruncate (int fd, off_t length)
698 {
699  Thread *current = Current ();
700  NS_ASSERT (current != 0);
701  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << length);
702  /*
703  int index = UtilsSearchOpenFd (fildes);
704  if (index == -1)
705  {
706  current->err = EBADF;
707  return -1;
708  }
709  UnixFd *unixFd = current->process->openFiles[index].second;
710  int retval = unixFd->Ftruncate (length);
711  return retval;
712  */
713  OPENED_FD_METHOD (int, Ftruncate (length))
714 }
715 int dce_ftruncate64 (int fd, off_t length)
716 {
717  Thread *current = Current ();
718  NS_ASSERT (current != 0);
719  NS_LOG_FUNCTION (current << UtilsGetNodeId () << fd << length);
720  return dce_ftruncate (fd, length);
721 }
722 
723 int dce_pipe (int pipefd[2])
724 {
725  Thread *current = Current ();
726  NS_ASSERT (current != 0);
727  NS_LOG_FUNCTION (current << UtilsGetNodeId ());
728 
729  if (0 == pipefd)
730  {
731  current->err = EFAULT;
732  return -1;
733  }
734  int fdRead = UtilsAllocateFd ();
735  if (fdRead == -1)
736  {
737  current->err = EMFILE;
738  return -1;
739  }
740  PipeFd *reader = new PipeFd ();
741 
742  if (!reader)
743  {
744  current->err = EMFILE;
745  return -1;
746  }
747  current->process->openFiles[fdRead] = new FileUsage (fdRead, reader);
748 
749  int fdWrite = UtilsAllocateFd ();
750  if (fdWrite == -1)
751  {
752  delete current->process->openFiles[fdRead];
753  current->process->openFiles.erase (fdRead);
754  delete reader;
755  current->err = EMFILE;
756  return -1;
757  }
758 
759  PipeFd *writer = new PipeFd (reader);
760 
761  if (!writer)
762  {
763  delete current->process->openFiles[fdRead];
764  current->process->openFiles.erase (fdRead);
765  delete reader;
766  current->err = EMFILE;
767  return -1;
768  }
769  current->process->openFiles[fdWrite] = new FileUsage (fdWrite, writer);
770 
771 // writer->m_peer = reader;
772  reader->IncFdCount ();
773  writer->IncFdCount ();
774 
775  pipefd [0] = fdRead;
776  pipefd [1] = fdWrite;
777 
778  return 0;
779 }
780 ssize_t dce_pread (int fd, void *buf, size_t count, off_t offset)
781 {
782  Thread *current = Current ();
783  NS_ASSERT (current != 0);
784  NS_LOG_FUNCTION (current << UtilsGetNodeId ());
785 
786  off_t currentOffset = dce_lseek (fd, 0, SEEK_CUR);
787  if (-1 == currentOffset)
788  {
789  return (ssize_t) -1;
790  }
791  off_t res = dce_lseek (fd, offset, SEEK_SET);
792  if (res != offset)
793  {
794  current->err = EINVAL;
795  return (ssize_t) -1;
796  }
797  ssize_t ret = dce_read (fd, buf, count);
798  if (-1 == ret)
799  {
800  return ret;
801  }
802  // Return to original offset.
803  res = dce_lseek (fd, currentOffset, SEEK_SET);
804  if (res != currentOffset)
805  {
806  return (ssize_t) -1;
807  }
808  return ret;
809 }
810 ssize_t dce_pwrite (int fd, const void *buf, size_t count, off_t offset)
811 {
812  Thread *current = Current ();
813  NS_ASSERT (current != 0);
814  NS_LOG_FUNCTION (current << UtilsGetNodeId ());
815 
816  off_t currentOffset = dce_lseek (fd, 0, SEEK_CUR);
817  if (-1 == currentOffset)
818  {
819  return (ssize_t) -1;
820  }
821  off_t res = dce_lseek (fd, offset, SEEK_SET);
822  if (res != offset)
823  {
824  current->err = EINVAL;
825  return (ssize_t) -1;
826  }
827  ssize_t ret = dce_write (fd, buf, count);
828  if (-1 == ret)
829  {
830  return ret;
831  }
832  // Return to original offset.
833  res = dce_lseek (fd, currentOffset, SEEK_SET);
834  if (res != currentOffset)
835  {
836  return (ssize_t) -1;
837  }
838  return ret;
839 }