~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSSys_win.cc

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
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
 
 
30
 
#include <io.h>
31
 
 
32
 
#include "CSGlobal.h"
33
 
#include "CSDefs.h"
34
 
#include "CSStrUtil.h"
35
 
#include "CSSys.h"
36
 
 
37
 
#define CS_MASK         ((S_IRUSR | S_IWUSR) | (S_IRGRP | S_IWGRP) | (S_IROTH))
38
 
//=====================
39
 
// CSSysFile
40
 
//=====================
41
 
static int get_win_error()
42
 
{
43
 
        return (int) GetLastError();
44
 
}
45
 
 
46
 
bool CSSysFile::isDirNotFound(CSException *e) { return e->getErrorCode() == ERROR_PATH_NOT_FOUND; }
47
 
bool CSSysFile::isFileNotFound(CSException *e) { return e->getErrorCode() == ERROR_FILE_NOT_FOUND; }
48
 
bool CSSysFile::isDirExists(CSException *e) { return e->getErrorCode() == ERROR_ALREADY_EXISTS; }
49
 
 
50
 
 
51
 
//--------------
52
 
void CSSysFile::sf_open(const char *path, bool readonly, bool create)
53
 
{
54
 
        SECURITY_ATTRIBUTES     sa = { sizeof(SECURITY_ATTRIBUTES), 0, 0 };
55
 
        DWORD                           flags;
56
 
 
57
 
        flags = (create)?OPEN_ALWAYS:OPEN_EXISTING;
58
 
        
59
 
        if (sf_fh != INVALID_HANDLE_VALUE)
60
 
                sf_close();
61
 
        
62
 
        sf_path = CSString::newString(path);
63
 
        
64
 
        sf_fh = CreateFileA(
65
 
                path,
66
 
                readonly ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
67
 
                FILE_SHARE_READ | FILE_SHARE_WRITE,
68
 
                &sa,
69
 
                flags,
70
 
                FILE_FLAG_RANDOM_ACCESS,
71
 
                NULL);
72
 
                
73
 
        if (sf_fh == INVALID_HANDLE_VALUE) {
74
 
                sf_path->release();
75
 
                sf_path = NULL;
76
 
                CSException::throwFileError(CS_CONTEXT, path, get_win_error());
77
 
        }
78
 
}
79
 
 
80
 
//--------------
81
 
void CSSysFile::sf_close()
82
 
{
83
 
        if (sf_fh != INVALID_HANDLE_VALUE) {
84
 
                CloseHandle(sf_fh);
85
 
                sf_fh = INVALID_HANDLE_VALUE;
86
 
                sf_path->release();
87
 
                sf_path = NULL;
88
 
        }       
89
 
}
90
 
 
91
 
//--------------
92
 
size_t CSSysFile::sf_pread(void *data, size_t size, off64_t offset)
93
 
{
94
 
        LARGE_INTEGER   liDistanceToMove;
95
 
        DWORD                   result;
96
 
 
97
 
        liDistanceToMove.QuadPart = offset;
98
 
        if (!SetFilePointerEx(sf_fh, liDistanceToMove, NULL, FILE_BEGIN))
99
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
100
 
 
101
 
        if (!ReadFile(sf_fh, data, size, &result, NULL))
102
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
103
 
 
104
 
        return (size_t) result;
105
 
}
106
 
 
107
 
//--------------
108
 
void CSSysFile::sf_pwrite(const void *data, size_t size, off64_t offset)
109
 
{
110
 
        LARGE_INTEGER   liDistanceToMove;
111
 
        DWORD                   result;
112
 
        
113
 
        liDistanceToMove.QuadPart = offset;
114
 
        if (!SetFilePointerEx(sf_fh, liDistanceToMove, NULL, FILE_BEGIN))
115
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
116
 
 
117
 
        if (!WriteFile(sf_fh, data, size, &result, NULL))
118
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
119
 
 
120
 
        if (result != size)
121
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), ERROR_HANDLE_EOF);
122
 
        
123
 
}
124
 
 
125
 
//--------------
126
 
void CSSysFile::sf_setEOF(off64_t offset)
127
 
{
128
 
        LARGE_INTEGER liDistanceToMove;
129
 
        
130
 
        liDistanceToMove.QuadPart = offset;
131
 
        if (!SetFilePointerEx(sf_fh, liDistanceToMove, NULL, FILE_BEGIN)) 
132
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
133
 
 
134
 
        if (!SetEndOfFile(sf_fh)) 
135
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
136
 
}
137
 
 
138
 
//--------------
139
 
off64_t CSSysFile::sf_getEOF()
140
 
{
141
 
        DWORD                   result;
142
 
        LARGE_INTEGER   lpFileSize;
143
 
 
144
 
        result = SetFilePointer(sf_fh, 0, NULL, FILE_END);
145
 
        if (result == 0xFFFFFFFF)  
146
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
147
 
 
148
 
        if (!GetFileSizeEx(sf_fh, &lpFileSize))  
149
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
150
 
 
151
 
        return lpFileSize.QuadPart;
152
 
}
153
 
 
154
 
//--------------
155
 
void CSSysFile::sf_sync()
156
 
{
157
 
        if (!FlushFileBuffers(sf_fh))  
158
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
159
 
}
160
 
 
161
 
//--------------
162
 
void CSSysFile::sf_lock(bool shared)
163
 
{
164
 
        OVERLAPPED overlap = {0};
165
 
        
166
 
        if (!LockFileEx(sf_fh, (shared)? 0: LOCKFILE_EXCLUSIVE_LOCK, 0, 512, 0, &overlap))  
167
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
168
 
}
169
 
 
170
 
//--------------
171
 
void CSSysFile::sf_unlock()
172
 
{
173
 
        OVERLAPPED overlap = {0};
174
 
 
175
 
        if (!UnlockFileEx(sf_fh, 0, 512, 0, &overlap))  
176
 
                CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
177
 
}
178
 
 
179
 
//=====================
180
 
// CSSys
181
 
//=====================
182
 
//--------------
183
 
bool CSSys::sys_exists(const char *path)
184
 
{
185
 
         return (access(path, 0) != -1);
186
 
}
187
 
 
188
 
//--------------
189
 
void CSSys::sys_getcwd(char *path, size_t size)
190
 
{
191
 
        DWORD   len;
192
 
 
193
 
        len = GetCurrentDirectoryA(size, path);
194
 
        if (len == 0)
195
 
                CSException::throwFileError(CS_CONTEXT, "GetCurrentDirectory()" , get_win_error());
196
 
        else if (len > (size -1))
197
 
                CSException::throwFileError(CS_CONTEXT, "GetCurrentDirectory()overflow " , len);
198
 
 
199
 
}
200
 
 
201
 
//--------------
202
 
void CSSys::sys_setcwd(const char *path)
203
 
{
204
 
        if (!SetCurrentDirectoryA(path))
205
 
                CSException::throwFileError(CS_CONTEXT, "SetCurrentDirectory()" , get_win_error());
206
 
}
207
 
 
208
 
//--------------
209
 
void CSSys::sys_makeDir(const char *path)
210
 
{
211
 
        SECURITY_ATTRIBUTES     sa = { sizeof(SECURITY_ATTRIBUTES), 0, 0 };
212
 
 
213
 
        if (!CreateDirectoryA(path, &sa))
214
 
                CSException::throwFileError(CS_CONTEXT, path, get_win_error());
215
 
 
216
 
}
217
 
 
218
 
#define FILE_NOT_FOUND(x)               ((x) == ERROR_FILE_NOT_FOUND || (x) == ERROR_PATH_NOT_FOUND)
219
 
//--------------
220
 
void CSSys::sys_removeDir(const char *path)
221
 
{
222
 
        if (!RemoveDirectoryA(path)) {
223
 
                int err = get_win_error();
224
 
 
225
 
                if (!FILE_NOT_FOUND(err)) 
226
 
                        CSException::throwFileError(CS_CONTEXT, path, err);
227
 
        }
228
 
}
229
 
 
230
 
//--------------
231
 
void CSSys::sys_removeFile(const char *path)
232
 
{
233
 
        if (!DeleteFileA(path)) {
234
 
                int err = get_win_error();
235
 
 
236
 
                if (!FILE_NOT_FOUND(err)) 
237
 
                        CSException::throwFileError(CS_CONTEXT, path, err);
238
 
        }
239
 
}
240
 
 
241
 
 
242
 
//--------------
243
 
 
244
 
void CSSys::sys_stat(const char *path, bool *is_dir, off64_t *size, CSTime *mod_time)
245
 
{
246
 
        HANDLE                                          fh;
247
 
        BY_HANDLE_FILE_INFORMATION      info;
248
 
        SECURITY_ATTRIBUTES                     sa = { sizeof(SECURITY_ATTRIBUTES), 0, 0 };
249
 
 
250
 
        fh = CreateFileA(
251
 
                path,
252
 
                0,
253
 
                FILE_SHARE_READ,
254
 
                &sa,
255
 
                OPEN_EXISTING,
256
 
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, // FILE_FLAG_BACKUP_SEMANTICS allows you to open directories.
257
 
                NULL);
258
 
                
259
 
        if (fh == INVALID_HANDLE_VALUE) {
260
 
                CSException::throwFileError(CS_CONTEXT, path, get_win_error());
261
 
        }
262
 
 
263
 
        if (!GetFileInformationByHandle(fh, &info)) {
264
 
                CloseHandle(fh);
265
 
                CSException::throwFileError(CS_CONTEXT, path, get_win_error());
266
 
        }
267
 
 
268
 
        CloseHandle(fh);
269
 
        if (is_dir)
270
 
                *is_dir = ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
271
 
 
272
 
        if (size)
273
 
                *size = (off64_t) info.nFileSizeLow | (((off64_t) info.nFileSizeHigh) << 32);
274
 
                
275
 
        if (mod_time) {
276
 
                SYSTEMTIME st;
277
 
                FileTimeToSystemTime(&info.ftLastWriteTime, &st);
278
 
                mod_time->setUTC(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds * 1000000);
279
 
        }
280
 
 
281
 
}
282
 
 
283
 
//--------------
284
 
bool CSSys::sys_isLink(const char *path)
285
 
{
286
 
        CSException::throwFileError(CS_CONTEXT, "CSSys::sys_isLink() not implimented on windows.", -1);
287
 
        return false;   
288
 
}
289
 
 
290
 
//--------------
291
 
void CSSys::sys_rename(const char *old_path, const char *new_path)
292
 
{
293
 
         if (rename(old_path, new_path) == -1)
294
 
                CSException::throwFileError(CS_CONTEXT, old_path, errno);
295
 
}
296
 
 
297
 
//--------------
298
 
uint32_t CSSys::sys_getpid()
299
 
{
300
 
        return GetCurrentProcessId();
301
 
}
302
 
 
303
 
//--------------
304
 
bool CSSys::sys_isAlive(uint32_t pid)
305
 
{
306
 
        HANDLE h;
307
 
        bool isAlive = false;
308
 
        DWORD code;
309
 
 
310
 
        h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
311
 
        if (h) {
312
 
                if (GetExitCodeProcess(h, &code) && (code == STILL_ACTIVE))
313
 
                        isAlive = true;
314
 
                        
315
 
                CloseHandle(h);
316
 
        } else {
317
 
                int err;
318
 
 
319
 
                err = HRESULT_CODE(GetLastError());
320
 
                if (err != ERROR_INVALID_PARAMETER)
321
 
                        isAlive = true;
322
 
                else
323
 
                        fprintf(stderr, "ERROR CSSys::sys_isAlive(%d):OpenProcess %d\n", pid, err);
324
 
        }
325
 
 
326
 
        return(isAlive);        
327
 
}
328
 
 
329
 
 
330
 
 
331
 
//=====================
332
 
// CSSysDir
333
 
//=====================
334
 
CSSysDir::~CSSysDir()
335
 
{
336
 
        close();
337
 
        if (sd_path)
338
 
                sd_path->release();
339
 
                
340
 
        if (sd_filter)
341
 
                sd_filter->release();
342
 
}
343
 
 
344
 
//--------------
345
 
void CSSysDir::open()
346
 
{
347
 
        enter_();
348
 
 
349
 
        if (! CSSys::sys_exists(sd_path->getCString()))
350
 
                CSException::throwFileError(CS_CONTEXT, sd_path->getCString(), ERROR_PATH_NOT_FOUND);
351
 
 
352
 
        sd_filter = new CSStringBuffer();
353
 
        sd_filter->append(sd_path->getCString());
354
 
 
355
 
        if (IS_DIR_CHAR(*(sd_filter->getBuffer(sd_filter->length()-1))))
356
 
                sd_filter->append("*");
357
 
        else
358
 
                sd_filter->append(CS_DIR_DELIM"*");
359
 
 
360
 
        exit_();
361
 
}
362
 
 
363
 
//--------------
364
 
void CSSysDir::close()
365
 
{
366
 
        if (sd_dir != INVALID_HANDLE_VALUE) {
367
 
                FindClose(sd_dir);
368
 
                sd_dir = INVALID_HANDLE_VALUE;
369
 
        }
370
 
}
371
 
 
372
 
//--------------
373
 
bool CSSysDir::next()
374
 
{
375
 
        int err = 0;
376
 
 
377
 
        while (true) {
378
 
                if (sd_dir == INVALID_HANDLE_VALUE) {
379
 
                        sd_dir = FindFirstFileA(sd_filter->getCString(), &sd_entry);
380
 
                        if (sd_dir == INVALID_HANDLE_VALUE)
381
 
                                err = get_win_error();
382
 
                }
383
 
                else {
384
 
                        if (!FindNextFileA(sd_dir, &sd_entry))
385
 
                                err = get_win_error();
386
 
                }
387
 
 
388
 
                if (err) {
389
 
                        if ((err != ERROR_NO_MORE_FILES) && (err != ERROR_FILE_NOT_FOUND)){
390
 
                                CSException::throwFileError(CS_CONTEXT, sd_path->getCString(), err);
391
 
                        }
392
 
                        return false;
393
 
                }
394
 
 
395
 
                /* Filter out '.' and '..': */
396
 
                if (sd_entry.cFileName[0] == '.') {
397
 
                        if (sd_entry.cFileName[1] == '.') {
398
 
                                if (sd_entry.cFileName[2] == '\0')
399
 
                                        continue;
400
 
                        }
401
 
                        else {
402
 
                                if (sd_entry.cFileName[1] == '\0')
403
 
                                        continue;
404
 
                        }
405
 
                }
406
 
                break;
407
 
        }
408
 
 
409
 
        return true;
410
 
}
411
 
 
412
 
 
413
 
//--------------
414
 
void CSSysDir::getEntryPath(char *path, size_t size)
415
 
{
416
 
        cs_strcpy(size, path, sd_path->getCString());
417
 
        cs_add_dir_char(size, path);
418
 
        cs_strcat(size, path, entryName());
419
 
}
420
 
 
421
 
//--------------
422
 
const char *CSSysDir::entryName()
423
 
{
424
 
        return (const char*) sd_entry.cFileName;
425
 
}
426
 
 
427
 
//--------------
428
 
bool CSSysDir::entryIsFile()
429
 
{
430
 
        if (sd_entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
431
 
                return false;
432
 
        return true;
433
 
}
434
 
 
435
 
///////////////////////////////////////////
436
 
// A windows version of gettimeofday() as taken from:
437
 
// http://www.suacommunity.com/dictionary/gettimeofday-entry.php
438
 
 
439
 
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
440
 
  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
441
 
#else
442
 
  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
443
 
#endif
444
 
 
445
 
struct timezone
446
 
{
447
 
  int  tz_minuteswest; /* minutes W of Greenwich */
448
 
  int  tz_dsttime;     /* type of dst correction */
449
 
};
450
 
 
451
 
// Definition of a gettimeofday function
452
 
 
453
 
int gettimeofday(struct timeval *tv, struct timezone *tz)
454
 
{
455
 
// Define a structure to receive the current Windows filetime
456
 
  FILETIME ft;
457
 
 
458
 
// Initialize the present time to 0 and the timezone to UTC
459
 
  unsigned __int64 tmpres = 0;
460
 
  static int tzflag = 0;
461
 
 
462
 
  if (NULL != tv)
463
 
  {
464
 
    GetSystemTimeAsFileTime(&ft);
465
 
 
466
 
// The GetSystemTimeAsFileTime returns the number of 100 nanosecond 
467
 
// intervals since Jan 1, 1601 in a structure. Copy the high bits to 
468
 
// the 64 bit tmpres, shift it left by 32 then or in the low 32 bits.
469
 
    tmpres |= ft.dwHighDateTime;
470
 
    tmpres <<= 32;
471
 
    tmpres |= ft.dwLowDateTime;
472
 
 
473
 
// Convert to microseconds by dividing by 10
474
 
    tmpres /= 10;
475
 
 
476
 
// The Unix epoch starts on Jan 1 1970.  Need to subtract the difference 
477
 
// in seconds from Jan 1 1601.
478
 
    tmpres -= DELTA_EPOCH_IN_MICROSECS;
479
 
 
480
 
// Finally change microseconds to seconds and place in the seconds value. 
481
 
// The modulus picks up the microseconds.
482
 
    tv->tv_sec = (long)(tmpres / 1000000UL);
483
 
    tv->tv_usec = (long)(tmpres % 1000000UL);
484
 
  }
485
 
 
486
 
  if (NULL != tz)
487
 
  {
488
 
    if (!tzflag)
489
 
    {
490
 
      _tzset();
491
 
      tzflag++;
492
 
    }
493
 
  
494
 
// Adjust for the timezone west of Greenwich
495
 
      tz->tz_minuteswest = _timezone / 60;
496
 
    tz->tz_dsttime = _daylight;
497
 
  }
498
 
 
499
 
  return 0;
500
 
}
501