@@ -402,47 +402,35 @@ add_stringlist_item(_stringlist **listhead, const char *str)
402
402
}
403
403
404
404
/*
405
- * Make a copy of the array of lines, with token replaced by replacement
405
+ * Modify the array of lines, replacing " token" by " replacement"
406
406
* the first time it occurs on each line.
407
407
*
408
- * The original data structure is not changed, but we share any unchanged
409
- * strings with it. (This definition lends itself to memory leaks, but
410
- * we don't care too much about leaks in this program.)
408
+ * The array must be a malloc'd array of individually malloc'd strings.
409
+ * We free any discarded strings.
411
410
*
412
411
* This does most of what sed was used for in the shell script, but
413
412
* doesn't need any regexp stuff.
414
413
*/
415
414
static char * *
416
415
replace_token (char * * lines , const char * token , const char * replacement )
417
416
{
418
- int numlines = 1 ;
419
- int i ;
420
- char * * result ;
421
417
int toklen ,
422
418
replen ,
423
419
diff ;
424
420
425
- for (i = 0 ; lines [i ]; i ++ )
426
- numlines ++ ;
427
-
428
- result = (char * * ) pg_malloc (numlines * sizeof (char * ));
429
-
430
421
toklen = strlen (token );
431
422
replen = strlen (replacement );
432
423
diff = replen - toklen ;
433
424
434
- for (i = 0 ; i < numlines ; i ++ )
425
+ for (int i = 0 ; lines [ i ] ; i ++ )
435
426
{
436
427
char * where ;
437
428
char * newline ;
438
429
int pre ;
439
430
440
- /* just copy pointer if NULL or no change needed */
441
- if (lines [i ] == NULL || (where = strstr (lines [i ], token )) == NULL )
442
- {
443
- result [i ] = lines [i ];
431
+ /* nothing to do if no change needed */
432
+ if ((where = strstr (lines [i ], token )) == NULL )
444
433
continue ;
445
- }
446
434
447
435
/* if we get here a change is needed - set up new line */
448
436
@@ -456,14 +444,15 @@ replace_token(char **lines, const char *token, const char *replacement)
456
444
457
445
strcpy (newline + pre + replen , lines [i ] + pre + toklen );
458
446
459
- result [i ] = newline ;
447
+ free (lines [i ]);
448
+ lines [i ] = newline ;
460
449
}
461
450
462
- return result ;
451
+ return lines ;
463
452
}
464
453
465
454
/*
466
- * Make a copy of the array of lines, replacing the possibly-commented-out
455
+ * Modify the array of lines, replacing the possibly-commented-out
467
456
* assignment of parameter guc_name with a live assignment of guc_value.
468
457
* The value will be suitably quoted.
469
458
*
@@ -474,18 +463,15 @@ replace_token(char **lines, const char *token, const char *replacement)
474
463
* We assume there's at most one matching assignment. If we find no match,
475
464
* append a new line with the desired assignment.
476
465
*
477
- * The original data structure is not changed, but we share any unchanged
478
- * strings with it. (This definition lends itself to memory leaks, but
479
- * we don't care too much about leaks in this program.)
466
+ * The array must be a malloc'd array of individually malloc'd strings.
467
+ * We free any discarded strings.
480
468
*/
481
469
static char * *
482
470
replace_guc_value (char * * lines , const char * guc_name , const char * guc_value ,
483
471
bool mark_as_comment )
484
472
{
485
- char * * result ;
486
473
int namelen = strlen (guc_name );
487
474
PQExpBuffer newline = createPQExpBuffer ();
488
- int numlines = 0 ;
489
475
int i ;
490
476
491
477
/* prepare the replacement line, except for possible comment and newline */
@@ -497,17 +483,7 @@ replace_guc_value(char **lines, const char *guc_name, const char *guc_value,
497
483
else
498
484
appendPQExpBufferStr (newline , guc_value );
499
485
500
- /* create the new pointer array */
501
486
for (i = 0 ; lines [i ]; i ++ )
502
- numlines ++ ;
503
-
504
- /* leave room for one extra string in case we need to append */
505
- result = (char * * ) pg_malloc ((numlines + 2 ) * sizeof (char * ));
506
-
507
- /* initialize result with all the same strings */
508
- memcpy (result , lines , (numlines + 1 ) * sizeof (char * ));
509
-
510
- for (i = 0 ; i < numlines ; i ++ )
511
487
{
512
488
const char * where ;
513
489
@@ -517,7 +493,7 @@ replace_guc_value(char **lines, const char *guc_name, const char *guc_value,
517
493
* overrides a previous assignment. We allow leading whitespace too,
518
494
* although normally there wouldn't be any.
519
495
*/
520
- where = result [i ];
496
+ where = lines [i ];
521
497
while (* where == '#' || isspace ((unsigned char ) * where ))
522
498
where ++ ;
523
499
if (strncmp (where , guc_name , namelen ) != 0 )
@@ -540,7 +516,7 @@ replace_guc_value(char **lines, const char *guc_name, const char *guc_value,
540
516
int oldindent = 0 ;
541
517
int newindent ;
542
518
543
- for (ptr = result [i ]; ptr < where ; ptr ++ )
519
+ for (ptr = lines [i ]; ptr < where ; ptr ++ )
544
520
{
545
521
if (* ptr == '\t' )
546
522
oldindent += 8 - (oldindent % 8 );
@@ -573,23 +549,27 @@ replace_guc_value(char **lines, const char *guc_name, const char *guc_value,
573
549
else
574
550
appendPQExpBufferChar (newline , '\n' );
575
551
576
- result [i ] = newline -> data ;
552
+ free (lines [i ]);
553
+ lines [i ] = newline -> data ;
577
554
578
555
break ; /* assume there's only one match */
579
556
}
580
557
581
- if (i >= numlines )
558
+ if (lines [ i ] == NULL )
582
559
{
583
560
/*
584
561
* No match, so append a new entry. (We rely on the bootstrap server
585
562
* to complain if it's not a valid GUC name.)
586
563
*/
587
564
appendPQExpBufferChar (newline , '\n' );
588
- result [numlines ++ ] = newline -> data ;
589
- result [numlines ] = NULL ; /* keep the array null-terminated */
565
+ lines = pg_realloc_array (lines , char * , i + 2 );
566
+ lines [i ++ ] = newline -> data ;
567
+ lines [i ] = NULL ; /* keep the array null-terminated */
590
568
}
591
569
592
- return result ;
570
+ free (newline ); /* but don't free newline->data */
571
+
572
+ return lines ;
593
573
}
594
574
595
575
/*
@@ -626,6 +606,8 @@ guc_value_requires_quotes(const char *guc_value)
626
606
627
607
/*
628
608
* get the lines from a text file
609
+ *
610
+ * The result is a malloc'd array of individually malloc'd strings.
629
611
*/
630
612
static char * *
631
613
readfile (const char * path )
@@ -668,6 +650,9 @@ readfile(const char *path)
668
650
/*
669
651
* write an array of lines to a file
670
652
*
653
+ * "lines" must be a malloc'd array of individually malloc'd strings.
654
+ * All that data is freed here.
655
+ *
671
656
* This is only used to write text files. Use fopen "w" not PG_BINARY_W
672
657
* so that the resulting configuration files are nicely editable on Windows.
673
658
*/
@@ -687,6 +672,7 @@ writefile(char *path, char **lines)
687
672
}
688
673
if (fclose (out_file ))
689
674
pg_fatal ("could not close file \"%s\": %m" , path );
675
+ free (lines );
690
676
}
691
677
692
678
/*
@@ -1218,7 +1204,6 @@ setup_config(void)
1218
1204
char * * conflines ;
1219
1205
char repltok [MAXPGPATH ];
1220
1206
char path [MAXPGPATH ];
1221
- char * autoconflines [3 ];
1222
1207
_stringlist * gnames ,
1223
1208
* gvalues ;
1224
1209
@@ -1384,18 +1369,17 @@ setup_config(void)
1384
1369
if (chmod (path , pg_file_create_mode ) != 0 )
1385
1370
pg_fatal ("could not change permissions of \"%s\": %m" , path );
1386
1371
1387
- free (conflines );
1388
-
1389
1372
1390
1373
/* postgresql.auto.conf */
1391
1374
1392
- autoconflines [0 ] = pg_strdup ("# Do not edit this file manually!\n" );
1393
- autoconflines [1 ] = pg_strdup ("# It will be overwritten by the ALTER SYSTEM command.\n" );
1394
- autoconflines [2 ] = NULL ;
1375
+ conflines = pg_malloc_array (char * , 3 );
1376
+ conflines [0 ] = pg_strdup ("# Do not edit this file manually!\n" );
1377
+ conflines [1 ] = pg_strdup ("# It will be overwritten by the ALTER SYSTEM command.\n" );
1378
+ conflines [2 ] = NULL ;
1395
1379
1396
1380
sprintf (path , "%s/postgresql.auto.conf" , pg_data );
1397
1381
1398
- writefile (path , autoconflines );
1382
+ writefile (path , conflines );
1399
1383
if (chmod (path , pg_file_create_mode ) != 0 )
1400
1384
pg_fatal ("could not change permissions of \"%s\": %m" , path );
1401
1385
@@ -1466,7 +1450,6 @@ setup_config(void)
1466
1450
if (chmod (path , pg_file_create_mode ) != 0 )
1467
1451
pg_fatal ("could not change permissions of \"%s\": %m" , path );
1468
1452
1469
- free (conflines );
1470
1453
1471
1454
/* pg_ident.conf */
1472
1455
@@ -1478,8 +1461,6 @@ setup_config(void)
1478
1461
if (chmod (path , pg_file_create_mode ) != 0 )
1479
1462
pg_fatal ("could not change permissions of \"%s\": %m" , path );
1480
1463
1481
- free (conflines );
1482
-
1483
1464
check_ok ();
1484
1465
}
1485
1466
0 commit comments