1 /* Copyright (C) 2019 MariaDB Corporation
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; version 2 of
6 the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 MA 02110-1301, USA. */
17
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include "SMFileFactory.h"
21 #include "SMDataFile.h"
22 #include "SMComm.h"
23 #include "BufferedFile.h"
24 #include "IDBDataFile.h"
25
26 using namespace std;
27
28
29 namespace idbdatafile {
30
open(const char * filename,const char * mode,unsigned opts,unsigned colWidth)31 IDBDataFile* SMFileFactory::open(const char *filename, const char *mode, unsigned opts, unsigned colWidth)
32 {
33 // TODO, test whether this breaks anything.
34 //if (opts & IDBDataFile::USE_TMPFILE)
35 // return new BufferedFile(filename, mode, opts);
36
37 bool _read = false;
38 bool _write = false;
39 bool create = false;
40 bool truncate = false;
41 bool append = false;
42
43 // strip 'b' chars from mode
44 char newmode[8] = {'\0'}; // there'd better not be 7 chars in the mode string
45 int i = 0;
46 for (const char *c = mode; *c != '\0' && i < 8; c++)
47 if (*c != 'b')
48 newmode[i++] = *c;
49 if (i == 8) {
50 errno = EINVAL;
51 return NULL;
52 }
53
54 // parse the new mode string
55 if (newmode[0] == 'r')
56 {
57 _read = true;
58 if (newmode[1] == '+')
59 _write = true;
60 }
61 else if (newmode[0] == 'w')
62 {
63 _write = true;
64 truncate = true;
65 create = true;
66 if (newmode[1] == '+')
67 _read = true;
68 }
69 else if (newmode[0] == 'a')
70 {
71 _write = true;
72 create = true;
73 append = true;
74 if (newmode[1] == '+')
75 _read = true;
76 }
77 else
78 {
79 errno = EINVAL;
80 return NULL;
81 }
82
83 // turn newmode into posix flags
84 uint posix_flags = 0;
85 if (_read && _write)
86 posix_flags |= O_RDWR;
87 else if (_read)
88 posix_flags |= O_RDONLY;
89 else if (_write)
90 posix_flags |= O_WRONLY;
91
92 posix_flags |= (create ? O_CREAT : 0);
93 posix_flags |= (truncate ? O_TRUNC : 0);
94 posix_flags |= (append ? O_APPEND : 0);
95
96 SMComm *comm = SMComm::get();
97 struct stat _stat;
98 int err = comm->open(filename, posix_flags, &_stat);
99 if (err)
100 return NULL;
101
102 SMDataFile *ret = new SMDataFile(filename, posix_flags, _stat);
103 return ret;
104 }
105
106
107 }
108