master
cpp 66 lines 1.34 KB
Raw
1 // Copyright (C) Microsoft Corporation. All rights reserved.
2 #include "precomp.h"
3 #include "p9readdir.h"
4
5 namespace p9fs {
6
7 // Creates a new directory enumerator.
8 // N.B. If successful, this takes ownership of the specified fd.
9 DirectoryEnumerator::DirectoryEnumerator(int fd) : m_Dir{fdopendir(fd)}
10 {
11 THROW_LAST_ERROR_IF(m_Dir == nullptr);
12 }
13
14 // Destructs the directory enumerator, closing the directory object and fd.
15 DirectoryEnumerator::~DirectoryEnumerator()
16 {
17 if (m_Dir != nullptr)
18 {
19 closedir(m_Dir);
20 }
21 }
22
23 struct dirent* DirectoryEnumerator::Next()
24 {
25 errno = 0;
26 auto result = readdir(m_Dir);
27 if (result == nullptr)
28 {
29 // If errno is still 0, it means EOF is reached which is not an error.
30 THROW_LAST_ERROR_IF(errno != 0);
31 }
32 else
33 {
34 m_LastOffset = result->d_off;
35 }
36
37 return result;
38 }
39
40 void DirectoryEnumerator::Seek(long offset)
41 {
42 // If the offset hasn't changed, continue enumeration and avoid having to
43 // refill the buffer.
44 if (offset != m_LastOffset)
45 {
46 if (offset == 0)
47 {
48 rewinddir(m_Dir);
49 }
50 else
51 {
52 seekdir(m_Dir, offset);
53 }
54
55 m_LastOffset = offset;
56 }
57 }
58
59 int DirectoryEnumerator::Fd()
60 {
61 int fd = dirfd(m_Dir);
62 THROW_LAST_ERROR_IF(fd < 0);
63 return fd;
64 }
65
66 } // namespace p9fs