~drizzle-trunk/drizzle/development

1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
1
/* Copyright (c) 2010 PrimeBase Technologies GmbH, Germany
2
 *
3
 * PrimeBase Media Stream for MySQL
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
1841.1.6 by Barry.Leslie at PrimeBase
Updating PBMS code to match pbms revision 244
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
18
 *
19
 * Author: Barry Leslie
20
 *
21
 * 2010-02-05
22
 *
23
 * CORE SYSTEM:
24
 * Basic UNIX specific file I/O classes.
25
 *
26
 */
27
28
#include "CSConfig.h"
29
#include <sys/stat.h>
30
#include <fcntl.h>
31
#include <errno.h>
32
#include <string.h>
33
#include <sys/file.h>
34
#include <unistd.h>
35
#include <signal.h>
36
37
#include "CSGlobal.h"
38
#include "CSDefs.h"
39
#include "CSStrUtil.h"
40
#include "CSSys.h"
41
42
#define CS_MASK		((S_IRUSR | S_IWUSR) | (S_IRGRP | S_IWGRP) | (S_IROTH))
43
//=====================
44
// CSSysFile
45
//=====================
46
bool CSSysFile::isDirNotFound(CSException *e) { return e->getErrorCode() == ENOENT; }
47
bool CSSysFile::isFileNotFound(CSException *e) { return e->getErrorCode() == ENOENT; }
48
bool CSSysFile::isDirExists(CSException *e) { return e->getErrorCode() == EEXIST; }
49
50
//--------------
51
void CSSysFile::sf_open(const char *path, bool readonly, bool create)
52
{
53
	int flags;
54
	
55
	flags = (readonly)?O_RDONLY:O_RDWR;
56
	
57
	if (create)
58
		flags |= O_CREAT;
59
		
60
	if (sf_fh != -1)
61
		sf_close();
62
	
63
	sf_path = CSString::newString(path);
64
	
65
	sf_fh = open(path, flags, CS_MASK);
66
	if (sf_fh == -1) {
67
		sf_path->release();
68
		sf_path = NULL;
69
		CSException::throwFileError(CS_CONTEXT, path, errno);
70
	}
71
}
72
73
//--------------
74
void CSSysFile::sf_close()
75
{
76
	if (sf_fh != -1) {
77
		close(sf_fh);
78
		sf_fh = -1;
79
		sf_path->release();
80
		sf_path = NULL;
81
	}	
82
}
83
84
//--------------
85
size_t CSSysFile::sf_pread(void *data, size_t size, off64_t offset)
86
{
87
	ssize_t read_size;
88
	
89
	read_size = pread(sf_fh, data, size, offset);
90
	if (read_size ==  -1)
91
		CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), errno);
92
93
	return read_size;
94
}
95
96
//--------------
97
void CSSysFile::sf_pwrite(const void *data, size_t size, off64_t offset)
98
{
99
	size_t write_size;
100
	
101
	write_size = pwrite(sf_fh, data, size, offset);
102
	if (write_size != size)
103
		CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), errno);
104
105
}
106
107
//--------------
108
void CSSysFile::sf_setEOF(off64_t offset)
109
{
110
	if (ftruncate(sf_fh, offset) == -1)
111
		CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), errno);
112
}
113
114
//--------------
115
off64_t CSSysFile::sf_getEOF()
116
{
117
	off64_t eof;
118
119
	if ((eof = lseek(sf_fh, 0, SEEK_END)) == ((off64_t)-1))
120
		CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), errno);
121
122
     return eof;
123
}
124
125
//--------------
126
void CSSysFile::sf_sync()
127
{
128
	fsync(sf_fh);
129
}
130
131
//--------------
132
void CSSysFile::sf_lock(bool shared)
133
{
134
	if (flock(sf_fh, (shared)?LOCK_SH:LOCK_EX) == -1)
135
		CSException::throwOSError(CS_CONTEXT, errno);
136
}
137
138
//--------------
139
void CSSysFile::sf_unlock()
140
{
141
	if (flock(sf_fh, LOCK_UN) == -1)
142
		CSException::throwOSError(CS_CONTEXT, errno);
143
}
144
145
//=====================
146
// CSSys
147
//=====================
148
//--------------
149
bool CSSys::sys_exists(const char *path)
150
{
151
	 return (access(path, F_OK) != -1);
152
}
153
154
//--------------
155
void CSSys::sys_makeDir(const char *path)
156
{
157
	char		super_path[PATH_MAX];
158
	struct stat	stats;
159
	char		*ptr;
160
161
	if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) == -1)
162
		CSException::throwFileError(CS_CONTEXT, path, errno);
163
164
	// Set the access privileges.
165
	ptr = cs_last_name_of_path(path);
166
	if (ptr == path) 
167
		strcpy(super_path, ".");
168
	else {
169
		cs_strcpy(PATH_MAX, super_path, path);
170
171
		if ((ptr = cs_last_name_of_path(super_path)))
172
			*ptr = 0;
173
	}
174
	
175
	if (stat(super_path, &stats) == -1)
176
		CSException::throwFileError(CS_CONTEXT, path, errno);
177
178
	if (chmod(path, stats.st_mode) == -1)
179
		CSException::throwFileError(CS_CONTEXT, path, errno);
180
181
}
182
183
//--------------
184
void CSSys::sys_removeDir(const char *path)
185
{
186
	if (rmdir(path) == -1) {
187
		int err = errno;
188
189
		if (err != ENOENT)
190
			CSException::throwFileError(CS_CONTEXT, path, err);
191
	}
192
}
193
194
//--------------
195
void CSSys::sys_removeFile(const char *path)
196
{
197
	if (unlink(path) == -1) {
198
		int err = errno;
199
200
		if (err != ENOENT)
201
			CSException::throwFileError(CS_CONTEXT, path, err);
202
	}
203
}
204
205
206
//--------------
207
208
void CSSys::sys_stat(const char *path, bool *is_dir, off64_t *size, CSTime *mod_time)
209
{
210
	struct stat sb;
211
212
	if (stat(path, &sb) == -1)
213
		CSException::throwFileError(CS_CONTEXT, path, errno);
214
	if (is_dir)
215
		*is_dir = sb.st_mode & S_IFDIR;
216
	if (size)
217
		*size = sb.st_size;
218
	if (mod_time)
219
#ifdef __USE_MISC
220
		/* This is the Linux version: */
221
		mod_time->setUTC1970(sb.st_mtim.tv_sec, sb.st_mtim.tv_nsec);
222
#else
223
		/* This is the Mac OS X version: */
224
		mod_time->setUTC1970(sb.st_mtimespec.tv_sec, sb.st_mtimespec.tv_nsec);
225
#endif
226
}
227
228
//--------------
229
bool CSSys::sys_isLink(const char *path)
230
{
231
	struct stat sb;
232
233
	if (lstat(path, &sb) == -1)
234
		CSException::throwFileError(CS_CONTEXT, path, errno);
235
		
236
	return S_ISLNK(sb.st_mode);
237
}
238
239
//--------------
240
void CSSys::sys_rename(const char *old_path, const char *new_path)
241
{
242
	 if (rename(old_path, new_path) == -1)
243
		CSException::throwFileError(CS_CONTEXT, old_path, errno);
244
}
245
246
//--------------
247
void CSSys::sys_getcwd(char *path, size_t size)
248
{
249
	if (getcwd(path, size) == NULL)
250
		CSException::throwOSError(CS_CONTEXT, errno);
251
}
252
253
//--------------
254
void CSSys::sys_setcwd(const char *path)
255
{
256
	if (chdir(path) == -1)
257
		CSException::throwFileError(CS_CONTEXT, path, errno);
258
}
259
260
//--------------
261
uint32_t CSSys::sys_getpid()
262
{
263
	return getpid();
264
}
265
266
//--------------
267
bool CSSys::sys_isAlive(uint32_t pid)
268
{
269
	return (kill(pid, 0) == 0);
270
}
271
272
//=====================
273
// CSSysDir
274
//=====================
275
CSSysDir::~CSSysDir()
276
{
277
	close();
278
	if (sd_path)
279
		sd_path->release();
280
		
281
	if (sd_filter)
282
		sd_filter->release();
283
}
284
285
//--------------
286
void CSSysDir::open()
287
{
288
	enter_();
289
	if (!(sd_dir = opendir(sd_path->getCString())))
290
		CSException::throwFileError(CS_CONTEXT, sd_path->getCString(), errno);
291
	exit_();
292
}
293
294
//--------------
295
void CSSysDir::close()
296
{
297
	enter_();
298
	if (sd_dir) {
299
		closedir(sd_dir);
300
		sd_dir = NULL;
301
	}
302
	exit_();
303
}
304
305
//--------------
306
bool CSSysDir::next()
307
{
308
	int				err;
309
	struct dirent	*result;
310
311
	enter_();
312
	for (;;) {
313
		err = readdir_r(sd_dir, &sd_entry, &result);
314
		self->interrupted();
315
		if (err)
316
			CSException::throwFileError(CS_CONTEXT, sd_path->getCString(), err);
317
		if (!result)
318
			break;
319
		/* Filter out '.' and '..': */
320
		if (sd_entry.d_name[0] == '.') {
321
			if (sd_entry.d_name[1] == '.') {
322
				if (sd_entry.d_name[2] == '\0')
323
					continue;
324
			}
325
			else {
326
				if (sd_entry.d_name[1] == '\0')
327
					continue;
328
			}
329
		}
330
		break;
331
	}
332
	return_(result ? true : false);
333
}
334
335
336
//--------------
337
void CSSysDir::getEntryPath(char *path, size_t size)
338
{
339
	cs_strcpy(size, path, sd_path->getCString());
340
	cs_add_dir_char(size, path);
341
	cs_strcat(size, path, sd_entry.d_name);
342
}
343
344
//--------------
345
const char *CSSysDir::entryName()
346
{
347
	return sd_entry.d_name;
348
}
349
350
//--------------
351
bool CSSysDir::entryIsFile()
352
{
353
	if (sd_entry.d_type & DT_DIR)
354
		return false;
355
	return true;
356
}
357
358
//--------------
1841.1.5 by barry-leslie
Fixed some compiler complaints with PBMS build.
359
extern void unix_close(int h);
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
360
void unix_close(int h) {close(h);}
361