~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/mongo/util/file.h

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
#pragma once
19
19
 
20
 
#if !defined(_WIN32)
21
 
#include "errno.h"
22
 
#include <sys/mman.h>
23
 
#include <sys/types.h>
24
 
#include <sys/stat.h>
25
 
#include <fcntl.h>
26
 
#include <sys/statvfs.h>
27
 
#endif
28
 
#include "text.h"
 
20
#include <boost/cstdint.hpp>
 
21
#include <string>
 
22
 
 
23
#include "mongo/platform/basic.h"
 
24
#include "mongo/platform/cstdint.h"
29
25
 
30
26
namespace mongo {
31
27
 
32
 
#ifndef __sunos__
33
28
    typedef uint64_t fileofs;
34
 
#else
35
 
    typedef boost::uint64_t fileofs;
36
 
#endif
37
 
 
38
 
    /* NOTE: not thread-safe. (at least the windows implementation isn't. */
39
 
 
40
 
    class FileInterface {
 
29
 
 
30
    // NOTE: not thread-safe. (at least the windows implementation isn't)
 
31
 
 
32
    class File {
 
33
 
41
34
    public:
42
 
        void open(const char *fn) {}
43
 
        void write(fileofs o, const char *data, unsigned len) {}
44
 
        void read(fileofs o, char *data, unsigned len) {}
45
 
        bool bad() {return false;}
46
 
        bool is_open() {return false;}
47
 
        fileofs len() { return 0; }
48
 
        void fsync() { verify(false); }
 
35
        File();
 
36
        ~File();
49
37
 
50
 
        // shrink file to size bytes. No-op if file already smaller.
 
38
        bool bad() const { return _bad; }
 
39
        void fsync() const;
 
40
        bool is_open() const;
 
41
        fileofs len();
 
42
        void open(const char* filename, bool readOnly = false, bool direct = false);
 
43
        void read(fileofs o, char* data, unsigned len);
51
44
        void truncate(fileofs size);
52
 
 
53
 
        /** @return  -1 if error or unavailable */
54
 
        static boost::intmax_t freeSpace(const string &path) { verify(false); return -1; }
55
 
    };
56
 
 
57
 
#if defined(_WIN32)
58
 
#include <io.h>
59
 
 
60
 
    class File : public FileInterface {
61
 
        HANDLE fd;
62
 
        bool _bad;
63
 
        string _name;
64
 
        void err(BOOL b=false) { /* false = error happened */
65
 
            if( !b && !_bad ) {
66
 
                _bad = true;
67
 
                log() << "File " << _name << "I/O error " << GetLastError() << '\n';
68
 
            }
69
 
        }
70
 
    public:
71
 
        File() {
72
 
            fd = INVALID_HANDLE_VALUE;
73
 
            _bad = true;
74
 
        }
75
 
        ~File() {
76
 
            if( is_open() ) CloseHandle(fd);
77
 
            fd = INVALID_HANDLE_VALUE;
78
 
        }
79
 
        void open(const char *filename, bool readOnly=false , bool direct=false) {
80
 
            _name = filename;
81
 
            fd = CreateFile(
82
 
                     toNativeString(filename).c_str(),
83
 
                     ( readOnly ? 0 : GENERIC_WRITE ) | GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ,
84
 
                     NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
85
 
            if( !is_open() ) {
86
 
                DWORD e = GetLastError();
87
 
                log() << "Create/Open File failed " << filename << ' ' << errnoWithDescription(e) << endl;
88
 
            }
89
 
            else
90
 
                _bad = false;
91
 
        }
92
 
        static boost::intmax_t freeSpace(const string &path) {
93
 
            ULARGE_INTEGER avail;
94
 
            if( GetDiskFreeSpaceEx(toNativeString(path.c_str()).c_str(), &avail, NULL, NULL) ) { 
95
 
                return avail.QuadPart;
96
 
            }
97
 
            DWORD e = GetLastError();
98
 
            log() << "GetDiskFreeSpaceEx fails errno: " << e << endl;
99
 
            return -1;
100
 
        }
101
 
        void write(fileofs o, const char *data, unsigned len) {
102
 
            LARGE_INTEGER li;
103
 
            li.QuadPart = o;
104
 
            SetFilePointerEx(fd, li, NULL, FILE_BEGIN);
105
 
            DWORD written;
106
 
            err( WriteFile(fd, data, len, &written, NULL) );
107
 
        }
108
 
        void read(fileofs o, char *data, unsigned len) {
109
 
            DWORD read;
110
 
            LARGE_INTEGER li;
111
 
            li.QuadPart = o;
112
 
            SetFilePointerEx(fd, li, NULL, FILE_BEGIN);
113
 
            int ok = ReadFile(fd, data, len, &read, 0);
114
 
            if( !ok )
115
 
                err(ok);
116
 
            else
117
 
                massert( 10438 , "ReadFile error - truncated file?", read == len);
118
 
        }
119
 
        bool bad() { return _bad; }
120
 
        bool is_open() { return fd != INVALID_HANDLE_VALUE; }
121
 
        fileofs len() {
122
 
            LARGE_INTEGER li;
123
 
            li.LowPart = GetFileSize(fd, (DWORD *) &li.HighPart);
124
 
            if( li.HighPart == 0 && li.LowPart == INVALID_FILE_SIZE ) {
125
 
                err( false );
126
 
                return 0;
127
 
            }
128
 
            return li.QuadPart;
129
 
        }
130
 
        void fsync() { FlushFileBuffers(fd); }
131
 
 
132
 
        void truncate(fileofs size) {
133
 
            if (len() <= size)
134
 
                return;
135
 
 
136
 
            LARGE_INTEGER li;
137
 
            li.QuadPart = size;
138
 
            if (SetFilePointerEx(fd, li, NULL, FILE_BEGIN) == 0){
139
 
                err(false);
140
 
                return; //couldn't seek
141
 
            }
142
 
 
143
 
            err(SetEndOfFile(fd));
144
 
        }
145
 
    };
146
 
 
147
 
#else
148
 
 
149
 
    class File : public FileInterface {
150
 
    public:
151
 
        int fd;
 
45
        void write(fileofs o, const char* data, unsigned len);
 
46
 
 
47
        static boost::intmax_t freeSpace(const std::string& path);
 
48
 
152
49
    private:
153
50
        bool _bad;
154
 
        void err(bool ok) {
155
 
            if( !ok && !_bad ) {
156
 
                _bad = true;
157
 
                log() << "File I/O " << errnoWithDescription() << '\n';
158
 
            }
159
 
        }
160
 
    public:
161
 
        File() {
162
 
            fd = -1;
163
 
            _bad = true;
164
 
        }
165
 
        ~File() {
166
 
            if( is_open() ) ::close(fd);
167
 
            fd = -1;
168
 
        }
169
 
 
170
 
#ifndef O_NOATIME
171
 
#define O_NOATIME 0
172
 
#endif
173
 
 
174
 
        void open(const char *filename, bool readOnly=false , bool direct=false) {
175
 
            fd = ::open(filename,
176
 
                        O_CREAT | ( readOnly ? 0 : ( O_RDWR | O_NOATIME ) ) 
177
 
#if defined(O_DIRECT)
178
 
                        | ( direct ? O_DIRECT : 0 ) 
179
 
#endif
180
 
                        ,
181
 
                        S_IRUSR | S_IWUSR);
182
 
            if ( fd <= 0 ) {
183
 
                out() << "couldn't open " << filename << ' ' << errnoWithDescription() << endl;
184
 
                return;
185
 
            }
186
 
            _bad = false;
187
 
        }
188
 
        void write(fileofs o, const char *data, unsigned len) {
189
 
            err( ::pwrite(fd, data, len, o) == (int) len );
190
 
        }
191
 
        void read(fileofs o, char *data, unsigned len) {
192
 
            ssize_t s = ::pread(fd, data, len, o);
193
 
            if( s == -1 ) {
194
 
                err(false);
195
 
            }
196
 
            else if( s != (int) len ) { 
197
 
                _bad = true;
198
 
                log() << "File error read:" << s << " bytes, wanted:" << len << " ofs:" << o << endl;
199
 
            }
200
 
        }
201
 
        bool bad() { return _bad; }
202
 
        bool is_open() { return fd > 0; }
203
 
        fileofs len() {
204
 
            off_t o = lseek(fd, 0, SEEK_END);
205
 
            if( o != (off_t) -1 )
206
 
                return o;
207
 
            err(false);
208
 
            return 0;
209
 
        }
210
 
        void fsync() { ::fsync(fd); }
211
 
        static boost::intmax_t freeSpace ( const string &path ) {
212
 
            struct statvfs info;
213
 
            verify( !statvfs( path.c_str() , &info ) );
214
 
            return boost::intmax_t( info.f_bavail ) * info.f_frsize;
215
 
        }
216
 
 
217
 
        void truncate(fileofs size) {
218
 
            if (len() <= size)
219
 
                return;
220
 
 
221
 
            err(ftruncate(fd, size) == 0);
222
 
        }
 
51
#ifdef _WIN32
 
52
        HANDLE _handle;
 
53
#else
 
54
        int _fd;
 
55
#endif
 
56
        std::string _name;
 
57
 
223
58
    };
224
59
 
225
 
 
226
 
#endif
227
 
 
228
 
 
229
60
}
230