Fossil SCM

Fix the empty-dirs property so that creates the complete path of directories, not just leaves, and so that it does not leak memory.

drh 2015-05-18 13:56 trunk merge
Commit 702331e057f6ec35d93ec0c12d9f4721d5b6d74c
+1 -1
--- src/blob.c
+++ src/blob.c
@@ -838,11 +838,11 @@
838838
#if defined(_WIN32)
839839
fflush(stdout);
840840
_setmode(_fileno(stdout), _O_TEXT);
841841
#endif
842842
}else{
843
- file_mkfolder(zFilename, 1);
843
+ file_mkfolder(zFilename, 1, 0);
844844
out = fossil_fopen(zFilename, "wb");
845845
if( out==0 ){
846846
fossil_fatal_recursive("unable to open file \"%s\" for writing",
847847
zFilename);
848848
return 0;
849849
--- src/blob.c
+++ src/blob.c
@@ -838,11 +838,11 @@
838 #if defined(_WIN32)
839 fflush(stdout);
840 _setmode(_fileno(stdout), _O_TEXT);
841 #endif
842 }else{
843 file_mkfolder(zFilename, 1);
844 out = fossil_fopen(zFilename, "wb");
845 if( out==0 ){
846 fossil_fatal_recursive("unable to open file \"%s\" for writing",
847 zFilename);
848 return 0;
849
--- src/blob.c
+++ src/blob.c
@@ -838,11 +838,11 @@
838 #if defined(_WIN32)
839 fflush(stdout);
840 _setmode(_fileno(stdout), _O_TEXT);
841 #endif
842 }else{
843 file_mkfolder(zFilename, 1, 0);
844 out = fossil_fopen(zFilename, "wb");
845 if( out==0 ){
846 fossil_fatal_recursive("unable to open file \"%s\" for writing",
847 zFilename);
848 return 0;
849
+1 -1
--- src/blob.c
+++ src/blob.c
@@ -838,11 +838,11 @@
838838
#if defined(_WIN32)
839839
fflush(stdout);
840840
_setmode(_fileno(stdout), _O_TEXT);
841841
#endif
842842
}else{
843
- file_mkfolder(zFilename, 1);
843
+ file_mkfolder(zFilename, 1, 0);
844844
out = fossil_fopen(zFilename, "wb");
845845
if( out==0 ){
846846
fossil_fatal_recursive("unable to open file \"%s\" for writing",
847847
zFilename);
848848
return 0;
849849
--- src/blob.c
+++ src/blob.c
@@ -838,11 +838,11 @@
838 #if defined(_WIN32)
839 fflush(stdout);
840 _setmode(_fileno(stdout), _O_TEXT);
841 #endif
842 }else{
843 file_mkfolder(zFilename, 1);
844 out = fossil_fopen(zFilename, "wb");
845 if( out==0 ){
846 fossil_fatal_recursive("unable to open file \"%s\" for writing",
847 zFilename);
848 return 0;
849
--- src/blob.c
+++ src/blob.c
@@ -838,11 +838,11 @@
838 #if defined(_WIN32)
839 fflush(stdout);
840 _setmode(_fileno(stdout), _O_TEXT);
841 #endif
842 }else{
843 file_mkfolder(zFilename, 1, 0);
844 out = fossil_fopen(zFilename, "wb");
845 if( out==0 ){
846 fossil_fatal_recursive("unable to open file \"%s\" for writing",
847 zFilename);
848 return 0;
849
+12 -5
--- src/file.c
+++ src/file.c
@@ -386,11 +386,11 @@
386386
FILE *in, *out;
387387
int got;
388388
char zBuf[8192];
389389
in = fossil_fopen(zFrom, "rb");
390390
if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom);
391
- file_mkfolder(zTo, 0);
391
+ file_mkfolder(zTo, 0, 0);
392392
out = fossil_fopen(zTo, "wb");
393393
if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo);
394394
while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){
395395
fwrite(zBuf, 1, got, out);
396396
}
@@ -530,13 +530,16 @@
530530
}
531531
532532
/*
533533
** Create the tree of directories in which zFilename belongs, if that sequence
534534
** of directories does not already exist.
535
+**
536
+** On success, return zero. On error, return errorReturn if positive, otherwise
537
+** print an error message and abort.
535538
*/
536
-void file_mkfolder(const char *zFilename, int forceFlag){
537
- int i, nName;
539
+int file_mkfolder(const char *zFilename, int forceFlag, int errorReturn){
540
+ int i, nName, rc = 0;
538541
char *zName;
539542
540543
nName = strlen(zFilename);
541544
zName = mprintf("%s", zFilename);
542545
nName = file_simplify_name(zName, nName, 0);
@@ -550,20 +553,24 @@
550553
** C: in this example.
551554
*/
552555
if( !(i==2 && zName[1]==':') ){
553556
#endif
554557
if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
555
- fossil_fatal_recursive("unable to create directory %s", zName);
556
- return;
558
+ if (errorReturn <= 0) {
559
+ fossil_fatal_recursive("unable to create directory %s", zName);
560
+ }
561
+ rc = errorReturn;
562
+ break;
557563
}
558564
#if defined(_WIN32) || defined(__CYGWIN__)
559565
}
560566
#endif
561567
zName[i] = '/';
562568
}
563569
}
564570
free(zName);
571
+ return rc;
565572
}
566573
567574
/*
568575
** Removes the directory named in the argument, if it exists. The directory
569576
** must be empty and cannot be the current directory or the root directory.
570577
--- src/file.c
+++ src/file.c
@@ -386,11 +386,11 @@
386 FILE *in, *out;
387 int got;
388 char zBuf[8192];
389 in = fossil_fopen(zFrom, "rb");
390 if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom);
391 file_mkfolder(zTo, 0);
392 out = fossil_fopen(zTo, "wb");
393 if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo);
394 while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){
395 fwrite(zBuf, 1, got, out);
396 }
@@ -530,13 +530,16 @@
530 }
531
532 /*
533 ** Create the tree of directories in which zFilename belongs, if that sequence
534 ** of directories does not already exist.
 
 
 
535 */
536 void file_mkfolder(const char *zFilename, int forceFlag){
537 int i, nName;
538 char *zName;
539
540 nName = strlen(zFilename);
541 zName = mprintf("%s", zFilename);
542 nName = file_simplify_name(zName, nName, 0);
@@ -550,20 +553,24 @@
550 ** C: in this example.
551 */
552 if( !(i==2 && zName[1]==':') ){
553 #endif
554 if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
555 fossil_fatal_recursive("unable to create directory %s", zName);
556 return;
 
 
 
557 }
558 #if defined(_WIN32) || defined(__CYGWIN__)
559 }
560 #endif
561 zName[i] = '/';
562 }
563 }
564 free(zName);
 
565 }
566
567 /*
568 ** Removes the directory named in the argument, if it exists. The directory
569 ** must be empty and cannot be the current directory or the root directory.
570
--- src/file.c
+++ src/file.c
@@ -386,11 +386,11 @@
386 FILE *in, *out;
387 int got;
388 char zBuf[8192];
389 in = fossil_fopen(zFrom, "rb");
390 if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom);
391 file_mkfolder(zTo, 0, 0);
392 out = fossil_fopen(zTo, "wb");
393 if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo);
394 while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){
395 fwrite(zBuf, 1, got, out);
396 }
@@ -530,13 +530,16 @@
530 }
531
532 /*
533 ** Create the tree of directories in which zFilename belongs, if that sequence
534 ** of directories does not already exist.
535 **
536 ** On success, return zero. On error, return errorReturn if positive, otherwise
537 ** print an error message and abort.
538 */
539 int file_mkfolder(const char *zFilename, int forceFlag, int errorReturn){
540 int i, nName, rc = 0;
541 char *zName;
542
543 nName = strlen(zFilename);
544 zName = mprintf("%s", zFilename);
545 nName = file_simplify_name(zName, nName, 0);
@@ -550,20 +553,24 @@
553 ** C: in this example.
554 */
555 if( !(i==2 && zName[1]==':') ){
556 #endif
557 if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
558 if (errorReturn <= 0) {
559 fossil_fatal_recursive("unable to create directory %s", zName);
560 }
561 rc = errorReturn;
562 break;
563 }
564 #if defined(_WIN32) || defined(__CYGWIN__)
565 }
566 #endif
567 zName[i] = '/';
568 }
569 }
570 free(zName);
571 return rc;
572 }
573
574 /*
575 ** Removes the directory named in the argument, if it exists. The directory
576 ** must be empty and cannot be the current directory or the root directory.
577
+15 -22
--- src/update.c
+++ src/update.c
@@ -586,43 +586,33 @@
586586
db_end_transaction(0);
587587
}
588588
}
589589
590590
/*
591
-** Make sure empty directories are created
591
+** Create empty directories specified by the empty-dirs setting.
592592
*/
593593
void ensure_empty_dirs_created(void){
594
- /* Make empty directories? */
595594
char *zEmptyDirs = db_get("empty-dirs", 0);
596595
if( zEmptyDirs!=0 ){
596
+ int i;
597597
char *bc;
598598
Blob dirName;
599599
Blob dirsList;
600600
601
- blob_zero(&dirsList);
602
- blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs));
603
- /* Replace commas by spaces */
604
- bc = blob_str(&dirsList);
605
- while( (*bc)!='\0' ){
606
- if( (*bc)==',' ) { *bc = ' '; }
607
- ++bc;
608
- }
609
- /* Make directories */
610
- blob_zero(&dirName);
601
+ zEmptyDirs = fossil_strdup(zEmptyDirs);
602
+ for(i=0; zEmptyDirs[i]; i++){
603
+ if( zEmptyDirs[i]==',' ) zEmptyDirs[i] = ' ';
604
+ }
605
+ blob_init(&dirsList, zEmptyDirs, -1);
611606
while( blob_token(&dirsList, &dirName) ){
612607
const char *zDir = blob_str(&dirName);
613
- /* Make full pathname of the directory */
614
- Blob path;
615
- const char *zPath;
616
-
617
- blob_zero(&path);
618
- blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir);
619
- zPath = blob_str(&path);
620
- /* Handle various cases of existence of the directory */
608
+ const char *zPath = mprintf("%s/%s", g.zLocalRoot, zDir);
621609
switch( file_wd_isdir(zPath) ){
622610
case 0: { /* doesn't exist */
623
- if( file_mkdir(zPath, 0)!=0 ) {
611
+ fossil_free(zPath);
612
+ zPath = mprintf("%s/%s/x", g.zLocalRoot, zDir);
613
+ if( file_mkfolder(zPath, 0, 1)!=0 ) {
624614
fossil_warning("couldn't create directory %s as "
625615
"required by empty-dirs setting", zDir);
626616
}
627617
break;
628618
}
@@ -633,12 +623,15 @@
633623
case 2: { /* exists, but isn't a directory */
634624
fossil_warning("file %s found, but a directory is required "
635625
"by empty-dirs setting", zDir);
636626
}
637627
}
638
- blob_reset(&path);
628
+ fossil_free(zPath);
629
+ blob_reset(&dirName);
639630
}
631
+ blob_reset(&dirsList);
632
+ fossil_free(zEmptyDirs);
640633
}
641634
}
642635
643636
644637
/*
645638
--- src/update.c
+++ src/update.c
@@ -586,43 +586,33 @@
586 db_end_transaction(0);
587 }
588 }
589
590 /*
591 ** Make sure empty directories are created
592 */
593 void ensure_empty_dirs_created(void){
594 /* Make empty directories? */
595 char *zEmptyDirs = db_get("empty-dirs", 0);
596 if( zEmptyDirs!=0 ){
 
597 char *bc;
598 Blob dirName;
599 Blob dirsList;
600
601 blob_zero(&dirsList);
602 blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs));
603 /* Replace commas by spaces */
604 bc = blob_str(&dirsList);
605 while( (*bc)!='\0' ){
606 if( (*bc)==',' ) { *bc = ' '; }
607 ++bc;
608 }
609 /* Make directories */
610 blob_zero(&dirName);
611 while( blob_token(&dirsList, &dirName) ){
612 const char *zDir = blob_str(&dirName);
613 /* Make full pathname of the directory */
614 Blob path;
615 const char *zPath;
616
617 blob_zero(&path);
618 blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir);
619 zPath = blob_str(&path);
620 /* Handle various cases of existence of the directory */
621 switch( file_wd_isdir(zPath) ){
622 case 0: { /* doesn't exist */
623 if( file_mkdir(zPath, 0)!=0 ) {
 
 
624 fossil_warning("couldn't create directory %s as "
625 "required by empty-dirs setting", zDir);
626 }
627 break;
628 }
@@ -633,12 +623,15 @@
633 case 2: { /* exists, but isn't a directory */
634 fossil_warning("file %s found, but a directory is required "
635 "by empty-dirs setting", zDir);
636 }
637 }
638 blob_reset(&path);
 
639 }
 
 
640 }
641 }
642
643
644 /*
645
--- src/update.c
+++ src/update.c
@@ -586,43 +586,33 @@
586 db_end_transaction(0);
587 }
588 }
589
590 /*
591 ** Create empty directories specified by the empty-dirs setting.
592 */
593 void ensure_empty_dirs_created(void){
 
594 char *zEmptyDirs = db_get("empty-dirs", 0);
595 if( zEmptyDirs!=0 ){
596 int i;
597 char *bc;
598 Blob dirName;
599 Blob dirsList;
600
601 zEmptyDirs = fossil_strdup(zEmptyDirs);
602 for(i=0; zEmptyDirs[i]; i++){
603 if( zEmptyDirs[i]==',' ) zEmptyDirs[i] = ' ';
604 }
605 blob_init(&dirsList, zEmptyDirs, -1);
 
 
 
 
 
606 while( blob_token(&dirsList, &dirName) ){
607 const char *zDir = blob_str(&dirName);
608 const char *zPath = mprintf("%s/%s", g.zLocalRoot, zDir);
 
 
 
 
 
 
 
609 switch( file_wd_isdir(zPath) ){
610 case 0: { /* doesn't exist */
611 fossil_free(zPath);
612 zPath = mprintf("%s/%s/x", g.zLocalRoot, zDir);
613 if( file_mkfolder(zPath, 0, 1)!=0 ) {
614 fossil_warning("couldn't create directory %s as "
615 "required by empty-dirs setting", zDir);
616 }
617 break;
618 }
@@ -633,12 +623,15 @@
623 case 2: { /* exists, but isn't a directory */
624 fossil_warning("file %s found, but a directory is required "
625 "by empty-dirs setting", zDir);
626 }
627 }
628 fossil_free(zPath);
629 blob_reset(&dirName);
630 }
631 blob_reset(&dirsList);
632 fossil_free(zEmptyDirs);
633 }
634 }
635
636
637 /*
638
+15 -22
--- src/update.c
+++ src/update.c
@@ -586,43 +586,33 @@
586586
db_end_transaction(0);
587587
}
588588
}
589589
590590
/*
591
-** Make sure empty directories are created
591
+** Create empty directories specified by the empty-dirs setting.
592592
*/
593593
void ensure_empty_dirs_created(void){
594
- /* Make empty directories? */
595594
char *zEmptyDirs = db_get("empty-dirs", 0);
596595
if( zEmptyDirs!=0 ){
596
+ int i;
597597
char *bc;
598598
Blob dirName;
599599
Blob dirsList;
600600
601
- blob_zero(&dirsList);
602
- blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs));
603
- /* Replace commas by spaces */
604
- bc = blob_str(&dirsList);
605
- while( (*bc)!='\0' ){
606
- if( (*bc)==',' ) { *bc = ' '; }
607
- ++bc;
608
- }
609
- /* Make directories */
610
- blob_zero(&dirName);
601
+ zEmptyDirs = fossil_strdup(zEmptyDirs);
602
+ for(i=0; zEmptyDirs[i]; i++){
603
+ if( zEmptyDirs[i]==',' ) zEmptyDirs[i] = ' ';
604
+ }
605
+ blob_init(&dirsList, zEmptyDirs, -1);
611606
while( blob_token(&dirsList, &dirName) ){
612607
const char *zDir = blob_str(&dirName);
613
- /* Make full pathname of the directory */
614
- Blob path;
615
- const char *zPath;
616
-
617
- blob_zero(&path);
618
- blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir);
619
- zPath = blob_str(&path);
620
- /* Handle various cases of existence of the directory */
608
+ const char *zPath = mprintf("%s/%s", g.zLocalRoot, zDir);
621609
switch( file_wd_isdir(zPath) ){
622610
case 0: { /* doesn't exist */
623
- if( file_mkdir(zPath, 0)!=0 ) {
611
+ fossil_free(zPath);
612
+ zPath = mprintf("%s/%s/x", g.zLocalRoot, zDir);
613
+ if( file_mkfolder(zPath, 0, 1)!=0 ) {
624614
fossil_warning("couldn't create directory %s as "
625615
"required by empty-dirs setting", zDir);
626616
}
627617
break;
628618
}
@@ -633,12 +623,15 @@
633623
case 2: { /* exists, but isn't a directory */
634624
fossil_warning("file %s found, but a directory is required "
635625
"by empty-dirs setting", zDir);
636626
}
637627
}
638
- blob_reset(&path);
628
+ fossil_free(zPath);
629
+ blob_reset(&dirName);
639630
}
631
+ blob_reset(&dirsList);
632
+ fossil_free(zEmptyDirs);
640633
}
641634
}
642635
643636
644637
/*
645638
--- src/update.c
+++ src/update.c
@@ -586,43 +586,33 @@
586 db_end_transaction(0);
587 }
588 }
589
590 /*
591 ** Make sure empty directories are created
592 */
593 void ensure_empty_dirs_created(void){
594 /* Make empty directories? */
595 char *zEmptyDirs = db_get("empty-dirs", 0);
596 if( zEmptyDirs!=0 ){
 
597 char *bc;
598 Blob dirName;
599 Blob dirsList;
600
601 blob_zero(&dirsList);
602 blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs));
603 /* Replace commas by spaces */
604 bc = blob_str(&dirsList);
605 while( (*bc)!='\0' ){
606 if( (*bc)==',' ) { *bc = ' '; }
607 ++bc;
608 }
609 /* Make directories */
610 blob_zero(&dirName);
611 while( blob_token(&dirsList, &dirName) ){
612 const char *zDir = blob_str(&dirName);
613 /* Make full pathname of the directory */
614 Blob path;
615 const char *zPath;
616
617 blob_zero(&path);
618 blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir);
619 zPath = blob_str(&path);
620 /* Handle various cases of existence of the directory */
621 switch( file_wd_isdir(zPath) ){
622 case 0: { /* doesn't exist */
623 if( file_mkdir(zPath, 0)!=0 ) {
 
 
624 fossil_warning("couldn't create directory %s as "
625 "required by empty-dirs setting", zDir);
626 }
627 break;
628 }
@@ -633,12 +623,15 @@
633 case 2: { /* exists, but isn't a directory */
634 fossil_warning("file %s found, but a directory is required "
635 "by empty-dirs setting", zDir);
636 }
637 }
638 blob_reset(&path);
 
639 }
 
 
640 }
641 }
642
643
644 /*
645
--- src/update.c
+++ src/update.c
@@ -586,43 +586,33 @@
586 db_end_transaction(0);
587 }
588 }
589
590 /*
591 ** Create empty directories specified by the empty-dirs setting.
592 */
593 void ensure_empty_dirs_created(void){
 
594 char *zEmptyDirs = db_get("empty-dirs", 0);
595 if( zEmptyDirs!=0 ){
596 int i;
597 char *bc;
598 Blob dirName;
599 Blob dirsList;
600
601 zEmptyDirs = fossil_strdup(zEmptyDirs);
602 for(i=0; zEmptyDirs[i]; i++){
603 if( zEmptyDirs[i]==',' ) zEmptyDirs[i] = ' ';
604 }
605 blob_init(&dirsList, zEmptyDirs, -1);
 
 
 
 
 
606 while( blob_token(&dirsList, &dirName) ){
607 const char *zDir = blob_str(&dirName);
608 const char *zPath = mprintf("%s/%s", g.zLocalRoot, zDir);
 
 
 
 
 
 
 
609 switch( file_wd_isdir(zPath) ){
610 case 0: { /* doesn't exist */
611 fossil_free(zPath);
612 zPath = mprintf("%s/%s/x", g.zLocalRoot, zDir);
613 if( file_mkfolder(zPath, 0, 1)!=0 ) {
614 fossil_warning("couldn't create directory %s as "
615 "required by empty-dirs setting", zDir);
616 }
617 break;
618 }
@@ -633,12 +623,15 @@
623 case 2: { /* exists, but isn't a directory */
624 fossil_warning("file %s found, but a directory is required "
625 "by empty-dirs setting", zDir);
626 }
627 }
628 fossil_free(zPath);
629 blob_reset(&dirName);
630 }
631 blob_reset(&dirsList);
632 fossil_free(zEmptyDirs);
633 }
634 }
635
636
637 /*
638
--- www/changes.wiki
+++ www/changes.wiki
@@ -40,10 +40,12 @@
4040
symlink. Additionally show the UUID for files whose types have changed
4141
without changing contents or symlink target.
4242
* Have [/help?cmd=changes|fossil changes] and
4343
[/help?cmd=status|fossil status] report when executable or symlink status
4444
changes on otherwise unmodified files.
45
+ * Create parent directories of [/help?cmd=settings|empty-dirs] if they don't
46
+ already exist.
4547
4648
<h2>Changes for Version 1.32 (2015-03-14)</h2>
4749
* When creating a new repository using [/help?cmd=init|fossil init], ensure
4850
that the new repository is fully compatible with historical versions of
4951
Fossil by having a valid manifest as RID 1.
5052
--- www/changes.wiki
+++ www/changes.wiki
@@ -40,10 +40,12 @@
40 symlink. Additionally show the UUID for files whose types have changed
41 without changing contents or symlink target.
42 * Have [/help?cmd=changes|fossil changes] and
43 [/help?cmd=status|fossil status] report when executable or symlink status
44 changes on otherwise unmodified files.
 
 
45
46 <h2>Changes for Version 1.32 (2015-03-14)</h2>
47 * When creating a new repository using [/help?cmd=init|fossil init], ensure
48 that the new repository is fully compatible with historical versions of
49 Fossil by having a valid manifest as RID 1.
50
--- www/changes.wiki
+++ www/changes.wiki
@@ -40,10 +40,12 @@
40 symlink. Additionally show the UUID for files whose types have changed
41 without changing contents or symlink target.
42 * Have [/help?cmd=changes|fossil changes] and
43 [/help?cmd=status|fossil status] report when executable or symlink status
44 changes on otherwise unmodified files.
45 * Create parent directories of [/help?cmd=settings|empty-dirs] if they don't
46 already exist.
47
48 <h2>Changes for Version 1.32 (2015-03-14)</h2>
49 * When creating a new repository using [/help?cmd=init|fossil init], ensure
50 that the new repository is fully compatible with historical versions of
51 Fossil by having a valid manifest as RID 1.
52

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button