3
3
* These routines are in part based on the article "Multiplatform .INI Files"
4
4
* by Joseph J. Graf in the March 1994 issue of Dr. Dobb's Journal.
5
5
*
6
- * Copyright (c) CompuPhase, 2008-2017
6
+ * Copyright (c) CompuPhase, 2008-2020
7
7
*
8
8
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
9
9
* use this file except in compliance with the License. You may obtain a copy
@@ -611,8 +611,10 @@ static int close_rename(INI_FILETYPE *rfp, INI_FILETYPE *wfp, const TCHAR *filen
611
611
{
612
612
(void )ini_close (rfp );
613
613
(void )ini_close (wfp );
614
- (void )ini_remove (filename );
615
614
(void )ini_tempname (buffer , filename , INI_BUFFERSIZE );
615
+ #if defined ini_remove || defined INI_REMOVE
616
+ (void )ini_remove (filename );
617
+ #endif
616
618
(void )ini_rename (buffer , filename );
617
619
return 1 ;
618
620
}
@@ -653,7 +655,6 @@ int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const T
653
655
* the INI file.
654
656
*/
655
657
if (Key != NULL && Value != NULL ) {
656
- ini_tell (& rfp , & mark );
657
658
match = getkeystring (& rfp , Section , Key , -1 , -1 , LocalBuffer , sizearray (LocalBuffer ), & head );
658
659
if (match ) {
659
660
/* if the current setting is identical to the one to write, there is
@@ -666,7 +667,7 @@ int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const T
666
667
/* if the new setting has the same length as the current setting, and the
667
668
* glue file permits file read/write access, we can modify in place.
668
669
*/
669
- #if defined ini_openrewrite
670
+ #if defined ini_openrewrite || defined INI_OPENREWRITE
670
671
/* we already have the start of the (raw) line, get the end too */
671
672
ini_tell (& rfp , & tail );
672
673
/* create new buffer (without writing it to file) */
@@ -685,20 +686,37 @@ int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const T
685
686
} /* if */
686
687
#endif
687
688
} /* if */
688
- /* key not found, or different value & length -> proceed (but rewind the
689
- * input file first)
690
- */
691
- (void )ini_seek (& rfp , & mark );
689
+ /* key not found, or different value & length -> proceed */
690
+ } else if (Key != NULL && Value == NULL ) {
691
+ /* Conversely, for a request to delete a setting; if that setting isn't
692
+ present, just return */
693
+ match = getkeystring (& rfp , Section , Key , -1 , -1 , LocalBuffer , sizearray (LocalBuffer ), NULL );
694
+ if (!match ) {
695
+ (void )ini_close (& rfp );
696
+ return 1 ;
697
+ } /* if */
698
+ /* key found -> proceed to delete it */
692
699
} /* if */
693
700
694
701
/* Get a temporary file name to copy to. Use the existing name, but with
695
702
* the last character set to a '~'.
696
703
*/
704
+ (void )ini_close (& rfp );
697
705
ini_tempname (LocalBuffer , Filename , INI_BUFFERSIZE );
698
- if (!ini_openwrite (LocalBuffer , & wfp )) {
699
- (void )ini_close (& rfp );
706
+ if (!ini_openwrite (LocalBuffer , & wfp ))
700
707
return 0 ;
708
+ /* In the case of (advisory) file locks, ini_openwrite() may have been blocked
709
+ * on the open, and after the block is lifted, the original file may have been
710
+ * renamed, which is why the original file was closed and is now reopened */
711
+ if (!ini_openread (Filename , & rfp )) {
712
+ /* If the .ini file doesn't exist any more, make a new file */
713
+ assert (Key != NULL && Value != NULL );
714
+ writesection (LocalBuffer , Section , & wfp );
715
+ writekey (LocalBuffer , Key , Value , & wfp );
716
+ (void )ini_close (& wfp );
717
+ return 1 ;
701
718
} /* if */
719
+
702
720
(void )ini_tell (& rfp , & mark );
703
721
cachelen = 0 ;
704
722
0 commit comments