~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-10-20 20:26:18 UTC
  • mfrom: (1859.2.13 refactor)
  • Revision ID: brian@tangent.org-20101020202618-9222n39lm329urv5
Merge for Brian 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
 
1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
2
2
 *
3
3
 * PrimeBase Media Stream for MySQL
4
4
 *
28
28
 
29
29
#include "CSConfig.h"
30
30
 
 
31
#include <unistd.h>
 
32
#include <sys/stat.h>
 
33
#include <sys/param.h>
31
34
#include <string.h>
32
35
#include <stdio.h>
33
36
 
 
37
static int unix_file_rename(const char *from, const char *to)
 
38
{
 
39
        return rename(from, to);
 
40
}
 
41
 
34
42
#include "CSStrUtil.h"
35
 
#include "CSSys.h"
36
43
#include "CSFile.h"
37
44
#include "CSDirectory.h"
38
45
#include "CSPath.h"
42
49
 * ---------------------------------------------------------------
43
50
 * CORE SYSTEM PATH
44
51
 */
45
 
CSLock  CSPath::iRename_lock;
46
52
 
47
53
CSPath *CSPath::iCWD = NULL;
48
54
 
52
58
                iPath->release();
53
59
}
54
60
 
55
 
CSFile *CSPath::try_CreateAndOpen(CSThread *self, int mode, bool retry)
56
 
{
57
 
        try_(a) {
58
 
                return openFile(mode | CSFile::CREATE); // success, do not try again.
59
 
        }
60
 
        catch_(a) {
61
 
                if (retry || !CSFile::isDirNotFound(&self->myException))
62
 
                        throw_();
63
 
 
64
 
                /* Make sure the parent directory exists: */
65
 
                CSPath  *dir = CSPath::newPath(RETAIN(this), "..");
66
 
                push_(dir);
67
 
                dir->makePath();
68
 
                release_(dir);
69
 
 
70
 
        }
71
 
        cont_(a);
72
 
        return NULL; 
73
 
}
74
 
 
75
61
CSFile *CSPath::createFile(int mode)
76
62
{
77
 
        CSFile  *file = NULL;
 
63
        CSFile  *file;
 
64
        CSPath  *dir;
78
65
        bool    retry = false;
79
66
 
 
67
        CLOBBER_PROTECT(retry);
 
68
 
80
69
        enter_();
81
 
        while (file == NULL) {
82
 
                file = try_CreateAndOpen(self, mode, retry);
83
 
                retry = true;
 
70
        /* Create and open the file: */
 
71
        do {
 
72
                try_(a) {
 
73
                        file = openFile(mode | CSFile::CREATE);
 
74
                        retry = false;
 
75
                }
 
76
                catch_(a) {
 
77
                        if (retry || !CSFile::isDirNotFound(&self->myException))
 
78
                                throw_();
 
79
 
 
80
                        /* Make sure the parent directory exists: */
 
81
                        dir = CSPath::newPath(RETAIN(this), "..");
 
82
                        try_(b) {
 
83
                                dir->makePath();
 
84
                        }
 
85
                        finally_(b) {
 
86
                                dir->release();
 
87
                        }
 
88
                        finally_end_block(b);
 
89
 
 
90
                        retry = true;
 
91
                }
 
92
                cont_(a);
84
93
        }
 
94
        while (retry);
85
95
        return_(file);
86
96
}
87
97
 
147
157
        }
148
158
 
149
159
        path = CSPath::newPath(RETAIN(this), "..");
150
 
        push_(path);
151
 
        
152
 
        path->makePath();
153
 
        makeDir();
154
 
        
155
 
        release_(path);
156
 
 
 
160
        try_(a) {
 
161
                path->makePath();
 
162
                makeDir();
 
163
        }
 
164
        finally_(a) {
 
165
                path->release();
 
166
        }
 
167
        finally_end_block(a);
157
168
        exit_();
158
169
}
159
170
 
216
227
 
217
228
bool CSPath::isLink()
218
229
{
219
 
        bool link;
 
230
        struct stat sb;
220
231
        enter_();
221
232
 
222
 
        link = sys_isLink(iPath->getCString());
223
 
        
224
 
        return_(link);
 
233
        if (lstat(iPath->getCString(), &sb) == -1)
 
234
                CSException::throwFileError(CS_CONTEXT, iPath, errno);
 
235
                
 
236
        return_(S_ISLNK(sb.st_mode));
225
237
}
226
238
 
227
239
bool CSPath::isEmpty()
237
249
                return_(false);
238
250
 
239
251
        dir = openDirectory();
240
 
        push_(dir);
241
 
        
242
 
        if (dir->next())
243
 
                result = false;
244
 
 
245
 
        release_(dir);
 
252
        try_(a) {
 
253
                if (dir->next())
 
254
                        result = false;
 
255
        }
 
256
        finally_(a) {
 
257
                dir->release(); 
 
258
        }
 
259
        finally_end_block(a);
246
260
        return_(result);
247
261
}
248
262
 
260
274
                CSException::throwFileError(CS_CONTEXT, iPath, ENOTDIR);
261
275
 
262
276
        dir = openDirectory();
263
 
        push_(dir);
264
 
 
265
 
        while (dir->next()) {
266
 
                path = CSPath::newPath(RETAIN(this), dir->name());
267
 
                push_(path);
268
 
                if (dir->isFile())
269
 
                        path->remove();
270
 
                else
271
 
                        path->removeDir();
272
 
                release_(path);
273
 
        }
274
 
 
275
 
        release_(dir);
276
 
        exit_();
277
 
}
278
 
 
279
 
void CSPath::emptyPath()
280
 
{
281
 
        CSDirectory *dir;
282
 
        CSPath          *path = NULL;
283
 
        bool            is_dir;
284
 
 
285
 
        enter_();
286
 
        if (!exists(&is_dir))
287
 
                exit_();
288
 
 
289
 
        if (!is_dir)
290
 
                CSException::throwFileError(CS_CONTEXT, iPath, ENOTDIR);
291
 
 
292
 
        dir = openDirectory();
293
 
        push_(dir);
294
 
 
295
 
        while (dir->next()) {
296
 
                path = CSPath::newPath(RETAIN(this), dir->name());
297
 
                push_(path);
298
 
                if (dir->isFile())
299
 
                        path->remove();
300
 
                else
301
 
                        path->emptyPath();
302
 
                release_(path);
303
 
        }
304
 
 
305
 
        release_(dir);
 
277
        try_(a) {
 
278
                while (dir->next()) {
 
279
                        path = CSPath::newPath(RETAIN(this), dir->name());
 
280
                        if (dir->isFile())
 
281
                                path->remove();
 
282
                        else
 
283
                                path->removeDir();
 
284
                        path->release();
 
285
                        path = NULL;
 
286
                }
 
287
        }
 
288
        finally_(a) {
 
289
                if (path)
 
290
                        path->release();
 
291
                dir->release(); 
 
292
        }
 
293
        finally_end_block(a);
306
294
        exit_();
307
295
}
308
296
 
329
317
 
330
318
void CSPath::moveTo(CSPath *in_to_path)
331
319
{
332
 
        CSPath  *to_path = NULL;
 
320
        CSPath  *to_path = in_to_path;
333
321
        bool    is_dir;
334
322
 
335
323
        enter_();
336
 
        push_(in_to_path);
337
 
        
338
324
        if (!exists(NULL))
339
325
                CSException::throwFileError(CS_CONTEXT, iPath, ENOENT);
340
326
 
341
 
        if (in_to_path->exists(&is_dir)) {
342
 
                if (is_dir) {
343
 
                        to_path = CSPath::newPath(RETAIN(in_to_path), getNameCString());
344
 
                        push_(to_path);
345
 
                        if (to_path->exists(NULL))
346
 
                                CSException::throwFileError(CS_CONTEXT, to_path->getCString(), EEXIST);
347
 
                        pop_(to_path);
 
327
        try_(a) {
 
328
                if (to_path->exists(&is_dir)) {
 
329
                        if (is_dir) {
 
330
                                to_path = CSPath::newPath(RETAIN(in_to_path), getNameCString());
 
331
                                if (to_path->exists(NULL))
 
332
                                        CSException::throwFileError(CS_CONTEXT, to_path->getCString(), EEXIST);
 
333
                        }
 
334
                        else
 
335
                                CSException::throwFileError(CS_CONTEXT, to_path->getCString(), ENOTDIR);
348
336
                }
349
 
                else
350
 
                        CSException::throwFileError(CS_CONTEXT, to_path->getCString(), ENOTDIR);
351
 
        } else
352
 
                to_path = RETAIN(in_to_path);
353
 
                
354
 
        move(to_path);
 
337
                move(to_path);
 
338
        }
 
339
        finally_(a) {
 
340
                if (to_path != in_to_path)
 
341
                        to_path->release();
 
342
        }
 
343
        finally_end_block(a);
355
344
 
356
 
        release_(in_to_path);
357
345
        exit_();
358
346
}
359
347
 
402
390
        return cs_last_name_of_path(str);
403
391
}
404
392
 
405
 
off64_t CSPath::getSize(const char *path)
406
 
{
407
 
        off64_t size;
408
 
 
409
 
        info(path, NULL, &size, NULL);
410
 
        return size;
411
 
}
412
 
 
413
393
off64_t CSPath::getSize()
414
394
{
415
395
        off64_t size;
426
406
        return is_dir;
427
407
}
428
408
 
 
409
/*
 
410
 * ---------------------------------------------------------------
 
411
 * A UNIX PATH
 
412
 */
 
413
 
429
414
bool CSPath::exists(bool *is_dir)
430
415
{
431
 
        if (!sys_exists(iPath->getCString()))
 
416
        int err;
 
417
 
 
418
        err = access(iPath->getCString(), F_OK);
 
419
        if (err == -1)
432
420
                return false;
433
 
                
434
421
        if (is_dir)
435
422
                *is_dir = isDir();
436
423
        return true;
437
424
}
438
425
 
439
 
void CSPath::info(const char *path, bool *is_dir, off64_t *size, CSTime *mod_time)
440
 
{
441
 
        sys_stat(path, is_dir, size, mod_time);
442
 
        
443
 
}
444
 
 
445
426
void CSPath::info(bool *is_dir, off64_t *size, CSTime *mod_time)
446
427
{
447
 
        info(iPath->getCString(), is_dir, size, mod_time);
 
428
        struct stat sb;
 
429
 
 
430
        if (stat(iPath->getCString(), &sb) == -1)
 
431
                CSException::throwFileError(CS_CONTEXT, iPath, errno);
 
432
        if (is_dir)
 
433
                *is_dir = sb.st_mode & S_IFDIR;
 
434
        if (size)
 
435
                *size = sb.st_size;
 
436
        if (mod_time)
 
437
#ifdef __USE_MISC
 
438
                /* This is the Linux version: */
 
439
                mod_time->setUTC1970(sb.st_mtim.tv_sec, sb.st_mtim.tv_nsec);
 
440
#else
 
441
                mod_time->setUTC1970(sb.st_mtime, 0);
 
442
#endif
448
443
}
449
444
 
450
445
CSFile *CSPath::openFile(int mode)
461
456
 
462
457
void CSPath::removeFile()
463
458
{
464
 
        sys_removeFile(iPath->getCString());
 
459
        if (unlink(iPath->getCString()) == -1) {
 
460
                int err = errno;
 
461
 
 
462
                if (err != ENOENT)
 
463
                        CSException::throwFileError(CS_CONTEXT, iPath, err);
 
464
        }
 
465
}
 
466
 
 
467
static void cs_set_stats(char *path)
 
468
{
 
469
        char            super_path[PATH_MAX];
 
470
        struct stat     stats;
 
471
        char            *ptr;
 
472
 
 
473
        ptr = cs_last_name_of_path(path);
 
474
        if (ptr == path) 
 
475
                strcpy(super_path, ".");
 
476
        else {
 
477
                cs_strcpy(PATH_MAX, super_path, path);
 
478
 
 
479
                if ((ptr = cs_last_name_of_path(super_path)))
 
480
                        *ptr = 0;
 
481
        }
 
482
        if (stat(super_path, &stats) == -1)
 
483
                CSException::throwFileError(CS_CONTEXT, path, errno);
 
484
 
 
485
        if (chmod(path, stats.st_mode) == -1)
 
486
                CSException::throwFileError(CS_CONTEXT, path, errno);
 
487
 
 
488
        /*chown(path, stats.st_uid, stats.st_gid);*/
465
489
}
466
490
 
467
491
void CSPath::makeDir()
471
495
        cs_strcpy(PATH_MAX, path, iPath->getCString());
472
496
        cs_remove_dir_char(path);
473
497
 
474
 
        sys_makeDir(path);
 
498
        if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) == -1)
 
499
                CSException::throwFileError(CS_CONTEXT, iPath, errno);
 
500
 
 
501
        cs_set_stats(path);
475
502
}
476
503
 
477
504
CSDirectory *CSPath::openDirectory()
489
516
void CSPath::removeDir()
490
517
{                       
491
518
        emptyDir();
492
 
        sys_removeDir(iPath->getCString());
 
519
        if (rmdir(iPath->getCString()) == -1) {
 
520
                int err = errno;
 
521
 
 
522
                if (err != ENOENT)
 
523
                        CSException::throwFileError(CS_CONTEXT, iPath, err);
 
524
        }
493
525
}
494
526
 
495
527
void CSPath::rename(const char *name)
504
536
        cs_add_dir_char(PATH_MAX, new_path);
505
537
        cs_strcat(PATH_MAX, new_path, name);
506
538
        
507
 
        lock_(&iRename_lock); // protect against race condition when testing if the new name exists yet or not. 
508
 
        if (sys_exists(new_path))
509
 
                CSException::throwFileError(CS_CONTEXT, new_path, EEXIST);
510
 
        
511
539
        tmp_path = CSString::newString(new_path);
512
540
        push_(tmp_path);
513
541
        
514
 
        sys_rename(iPath->getCString(), new_path);
 
542
        if (unix_file_rename(iPath->getCString(), new_path) == -1)
 
543
                CSException::throwFileError(CS_CONTEXT, iPath, errno);
515
544
                
516
545
        pop_(tmp_path);
517
 
        unlock_(&iRename_lock);
518
 
        
519
546
        old_path = iPath;
520
547
        iPath = tmp_path;
521
548
        
525
552
 
526
553
void CSPath::move(CSPath *to_path)
527
554
{
528
 
        enter_();
529
 
        lock_(&iRename_lock); // protect against race condition when testing if the new name exists yet or not. 
530
 
        if (to_path->exists())
531
 
                CSException::throwFileError(CS_CONTEXT, to_path->getCString(), EEXIST);
532
 
                
533
555
        /* Cannot move from TD to non-TD: */
534
 
        sys_rename(iPath->getCString(), to_path->getCString());
535
 
        unlock_(&iRename_lock);
536
 
        exit_();
 
556
        if (unix_file_rename(iPath->getCString(), to_path->getCString()) == -1)
 
557
                CSException::throwFileError(CS_CONTEXT, iPath, errno);
537
558
}
538
559
 
539
560
CSPath *CSPath::getCWD()
540
561
{
541
 
        char path[PATH_MAX];
542
 
 
543
 
        sys_getcwd(path, PATH_MAX);
 
562
        char path[MAXPATHLEN];
 
563
 
 
564
        if (!getcwd(path, MAXPATHLEN))
 
565
                CSException::throwOSError(CS_CONTEXT, errno);
 
566
 
544
567
        return newPath(path);
545
568
}
546
569