Fossil SCM

Improved handling of command-line arguments under windows. Possible fix for ticket [c8c0b78c84].

drh 2012-08-31 19:47 trunk merge
Commit 0c7ae64ab519d4836181e4ad86b6af2e5a058c3a
3 files changed +31 -14 +31 -14 +4 -4
+31 -14
--- src/main.c
+++ src/main.c
@@ -24,11 +24,13 @@
2424
#include <time.h>
2525
#include <fcntl.h>
2626
#include <sys/types.h>
2727
#include <sys/stat.h>
2828
#include <stdlib.h> /* atexit() */
29
-#if !defined(_WIN32)
29
+#if defined(_WIN32)
30
+# include <windows.h>
31
+#else
3032
# include <errno.h> /* errno global */
3133
#endif
3234
#if INTERFACE
3335
#ifdef FOSSIL_ENABLE_JSON
3436
# include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */
@@ -329,29 +331,42 @@
329331
db_close(0);
330332
}
331333
}
332334
333335
/*
334
-** Search g.argv for arguments "--args FILENAME". If found, then
336
+** Convert all arguments from mbcs to UTF-8. Then
337
+** search g.argv for arguments "--args FILENAME". If found, then
335338
** (1) remove the two arguments from g.argv
336339
** (2) Read the file FILENAME
337340
** (3) Use the contents of FILE to replace the two removed arguments:
338341
** (a) Ignore blank lines in the file
339342
** (b) Each non-empty line of the file is an argument, except
340343
** (c) If the line begins with "-" and contains a space, it is broken
341344
** into two arguments at the space.
342345
*/
343
-static void expand_args_option(void){
346
+static void expand_args_option(int argc, char **argv){
344347
Blob file = empty_blob; /* Content of the file */
345348
Blob line = empty_blob; /* One line of the file */
346349
unsigned int nLine; /* Number of lines in the file*/
347350
unsigned int i, j, k; /* Loop counters */
348351
int n; /* Number of bytes in one line */
349352
char *z; /* General use string pointer */
350353
char **newArgv; /* New expanded g.argv under construction */
351354
char const * zFileName; /* input file name */
352355
FILE * zInFile; /* input FILE */
356
+ int foundBom = -1; /* -1= not searched yet, 0 = no; 1=yes */
357
+#ifdef _WIN32
358
+ wchar_t buf[MAX_PATH];
359
+#endif
360
+
361
+ g.argc = argc;
362
+ g.argv = argv;
363
+#ifdef _WIN32
364
+ GetModuleFileNameW(NULL, buf, MAX_PATH);
365
+ g.argv[0] = fossil_unicode_to_utf8(buf);
366
+ for(i=1; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
367
+#endif
353368
for(i=1; i<g.argc-1; i++){
354369
z = g.argv[i];
355370
if( z[0]!='-' ) continue;
356371
z++;
357372
if( z[0]=='-' ) z++;
@@ -361,11 +376,11 @@
361376
if( i>=g.argc-1 ) return;
362377
363378
zFileName = g.argv[i+1];
364379
zInFile = (0==strcmp("-",zFileName))
365380
? stdin
366
- : fopen(zFileName,"rb");
381
+ : fossil_fopen(zFileName,"rb");
367382
if(!zInFile){
368383
fossil_panic("Cannot open -args file [%s]", zFileName);
369384
}else{
370385
blob_read_from_channel(&file, zInFile, -1);
371386
if(stdin != zInFile){
@@ -381,14 +396,24 @@
381396
blob_rewind(&file);
382397
while( (n = blob_line(&file, &line))>0 ){
383398
if( n<=1 ) continue;
384399
z = blob_buffer(&line);
385400
z[n-1] = 0;
401
+ if (foundBom == -1) {
402
+ static const char bom[] = { 0xEF, 0xBB, 0xBF };
403
+ foundBom = memcmp(z, bom, 3)==0;
404
+ if( foundBom ) {
405
+ z += 3; n -= 3;
406
+ }
407
+ }
386408
if((n>1) && ('\r'==z[n-2])){
387409
if(n==2) continue /*empty line*/;
388410
z[n-2] = 0;
389411
}
412
+ if (!foundBom) {
413
+ z = fossil_mbcs_to_utf8(z);
414
+ }
390415
newArgv[j++] = z;
391416
if( z[0]=='-' ){
392417
for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
393418
if( z[k] ){
394419
z[k] = 0;
@@ -409,17 +434,14 @@
409434
*/
410435
int main(int argc, char **argv){
411436
const char *zCmdName = "unknown";
412437
int idx;
413438
int rc;
414
- int i;
415439
416440
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
417441
memset(&g, 0, sizeof(g));
418442
g.now = time(0);
419
- g.argc = argc;
420
- g.argv = argv;
421443
#ifdef FOSSIL_ENABLE_JSON
422444
#if defined(NDEBUG)
423445
g.json.errorDetailParanoia = 2 /* FIXME: make configurable
424446
One problem we have here is that this
425447
code is needed before the db is opened,
@@ -429,12 +451,11 @@
429451
#endif
430452
g.json.outOpt = cson_output_opt_empty;
431453
g.json.outOpt.addNewline = 1;
432454
g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
433455
#endif /* FOSSIL_ENABLE_JSON */
434
- expand_args_option();
435
- for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
456
+ expand_args_option(argc, argv);
436457
#ifdef FOSSIL_ENABLE_TCL
437458
g.tcl.argc = g.argc;
438459
g.tcl.argv = g.argv;
439460
g.tcl.interp = 0;
440461
#endif
@@ -514,15 +535,11 @@
514535
515536
/*
516537
** Return the name of the current executable.
517538
*/
518539
const char *fossil_nameofexe(void){
519
-#ifdef _WIN32
520
- return _pgmptr;
521
-#else
522540
return g.argv[0];
523
-#endif
524541
}
525542
526543
/*
527544
** Exit. Take care to close the database first.
528545
*/
@@ -1432,11 +1449,11 @@
14321449
blob_read_from_file(&config, zFile);
14331450
while( blob_line(&config, &line) ){
14341451
if( !blob_token(&line, &key) ) continue;
14351452
if( blob_buffer(&key)[0]=='#' ) continue;
14361453
if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){
1437
- g.fDebug = fopen(blob_str(&value), "a");
1454
+ g.fDebug = fossil_fopen(blob_str(&value), "a");
14381455
blob_reset(&value);
14391456
continue;
14401457
}
14411458
if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
14421459
cgi_setenv("HOME", blob_str(&value));
14431460
--- src/main.c
+++ src/main.c
@@ -24,11 +24,13 @@
24 #include <time.h>
25 #include <fcntl.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdlib.h> /* atexit() */
29 #if !defined(_WIN32)
 
 
30 # include <errno.h> /* errno global */
31 #endif
32 #if INTERFACE
33 #ifdef FOSSIL_ENABLE_JSON
34 # include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */
@@ -329,29 +331,42 @@
329 db_close(0);
330 }
331 }
332
333 /*
334 ** Search g.argv for arguments "--args FILENAME". If found, then
 
335 ** (1) remove the two arguments from g.argv
336 ** (2) Read the file FILENAME
337 ** (3) Use the contents of FILE to replace the two removed arguments:
338 ** (a) Ignore blank lines in the file
339 ** (b) Each non-empty line of the file is an argument, except
340 ** (c) If the line begins with "-" and contains a space, it is broken
341 ** into two arguments at the space.
342 */
343 static void expand_args_option(void){
344 Blob file = empty_blob; /* Content of the file */
345 Blob line = empty_blob; /* One line of the file */
346 unsigned int nLine; /* Number of lines in the file*/
347 unsigned int i, j, k; /* Loop counters */
348 int n; /* Number of bytes in one line */
349 char *z; /* General use string pointer */
350 char **newArgv; /* New expanded g.argv under construction */
351 char const * zFileName; /* input file name */
352 FILE * zInFile; /* input FILE */
 
 
 
 
 
 
 
 
 
 
 
 
353 for(i=1; i<g.argc-1; i++){
354 z = g.argv[i];
355 if( z[0]!='-' ) continue;
356 z++;
357 if( z[0]=='-' ) z++;
@@ -361,11 +376,11 @@
361 if( i>=g.argc-1 ) return;
362
363 zFileName = g.argv[i+1];
364 zInFile = (0==strcmp("-",zFileName))
365 ? stdin
366 : fopen(zFileName,"rb");
367 if(!zInFile){
368 fossil_panic("Cannot open -args file [%s]", zFileName);
369 }else{
370 blob_read_from_channel(&file, zInFile, -1);
371 if(stdin != zInFile){
@@ -381,14 +396,24 @@
381 blob_rewind(&file);
382 while( (n = blob_line(&file, &line))>0 ){
383 if( n<=1 ) continue;
384 z = blob_buffer(&line);
385 z[n-1] = 0;
 
 
 
 
 
 
 
386 if((n>1) && ('\r'==z[n-2])){
387 if(n==2) continue /*empty line*/;
388 z[n-2] = 0;
389 }
 
 
 
390 newArgv[j++] = z;
391 if( z[0]=='-' ){
392 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
393 if( z[k] ){
394 z[k] = 0;
@@ -409,17 +434,14 @@
409 */
410 int main(int argc, char **argv){
411 const char *zCmdName = "unknown";
412 int idx;
413 int rc;
414 int i;
415
416 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
417 memset(&g, 0, sizeof(g));
418 g.now = time(0);
419 g.argc = argc;
420 g.argv = argv;
421 #ifdef FOSSIL_ENABLE_JSON
422 #if defined(NDEBUG)
423 g.json.errorDetailParanoia = 2 /* FIXME: make configurable
424 One problem we have here is that this
425 code is needed before the db is opened,
@@ -429,12 +451,11 @@
429 #endif
430 g.json.outOpt = cson_output_opt_empty;
431 g.json.outOpt.addNewline = 1;
432 g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
433 #endif /* FOSSIL_ENABLE_JSON */
434 expand_args_option();
435 for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
436 #ifdef FOSSIL_ENABLE_TCL
437 g.tcl.argc = g.argc;
438 g.tcl.argv = g.argv;
439 g.tcl.interp = 0;
440 #endif
@@ -514,15 +535,11 @@
514
515 /*
516 ** Return the name of the current executable.
517 */
518 const char *fossil_nameofexe(void){
519 #ifdef _WIN32
520 return _pgmptr;
521 #else
522 return g.argv[0];
523 #endif
524 }
525
526 /*
527 ** Exit. Take care to close the database first.
528 */
@@ -1432,11 +1449,11 @@
1432 blob_read_from_file(&config, zFile);
1433 while( blob_line(&config, &line) ){
1434 if( !blob_token(&line, &key) ) continue;
1435 if( blob_buffer(&key)[0]=='#' ) continue;
1436 if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){
1437 g.fDebug = fopen(blob_str(&value), "a");
1438 blob_reset(&value);
1439 continue;
1440 }
1441 if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
1442 cgi_setenv("HOME", blob_str(&value));
1443
--- src/main.c
+++ src/main.c
@@ -24,11 +24,13 @@
24 #include <time.h>
25 #include <fcntl.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdlib.h> /* atexit() */
29 #if defined(_WIN32)
30 # include <windows.h>
31 #else
32 # include <errno.h> /* errno global */
33 #endif
34 #if INTERFACE
35 #ifdef FOSSIL_ENABLE_JSON
36 # include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */
@@ -329,29 +331,42 @@
331 db_close(0);
332 }
333 }
334
335 /*
336 ** Convert all arguments from mbcs to UTF-8. Then
337 ** search g.argv for arguments "--args FILENAME". If found, then
338 ** (1) remove the two arguments from g.argv
339 ** (2) Read the file FILENAME
340 ** (3) Use the contents of FILE to replace the two removed arguments:
341 ** (a) Ignore blank lines in the file
342 ** (b) Each non-empty line of the file is an argument, except
343 ** (c) If the line begins with "-" and contains a space, it is broken
344 ** into two arguments at the space.
345 */
346 static void expand_args_option(int argc, char **argv){
347 Blob file = empty_blob; /* Content of the file */
348 Blob line = empty_blob; /* One line of the file */
349 unsigned int nLine; /* Number of lines in the file*/
350 unsigned int i, j, k; /* Loop counters */
351 int n; /* Number of bytes in one line */
352 char *z; /* General use string pointer */
353 char **newArgv; /* New expanded g.argv under construction */
354 char const * zFileName; /* input file name */
355 FILE * zInFile; /* input FILE */
356 int foundBom = -1; /* -1= not searched yet, 0 = no; 1=yes */
357 #ifdef _WIN32
358 wchar_t buf[MAX_PATH];
359 #endif
360
361 g.argc = argc;
362 g.argv = argv;
363 #ifdef _WIN32
364 GetModuleFileNameW(NULL, buf, MAX_PATH);
365 g.argv[0] = fossil_unicode_to_utf8(buf);
366 for(i=1; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
367 #endif
368 for(i=1; i<g.argc-1; i++){
369 z = g.argv[i];
370 if( z[0]!='-' ) continue;
371 z++;
372 if( z[0]=='-' ) z++;
@@ -361,11 +376,11 @@
376 if( i>=g.argc-1 ) return;
377
378 zFileName = g.argv[i+1];
379 zInFile = (0==strcmp("-",zFileName))
380 ? stdin
381 : fossil_fopen(zFileName,"rb");
382 if(!zInFile){
383 fossil_panic("Cannot open -args file [%s]", zFileName);
384 }else{
385 blob_read_from_channel(&file, zInFile, -1);
386 if(stdin != zInFile){
@@ -381,14 +396,24 @@
396 blob_rewind(&file);
397 while( (n = blob_line(&file, &line))>0 ){
398 if( n<=1 ) continue;
399 z = blob_buffer(&line);
400 z[n-1] = 0;
401 if (foundBom == -1) {
402 static const char bom[] = { 0xEF, 0xBB, 0xBF };
403 foundBom = memcmp(z, bom, 3)==0;
404 if( foundBom ) {
405 z += 3; n -= 3;
406 }
407 }
408 if((n>1) && ('\r'==z[n-2])){
409 if(n==2) continue /*empty line*/;
410 z[n-2] = 0;
411 }
412 if (!foundBom) {
413 z = fossil_mbcs_to_utf8(z);
414 }
415 newArgv[j++] = z;
416 if( z[0]=='-' ){
417 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
418 if( z[k] ){
419 z[k] = 0;
@@ -409,17 +434,14 @@
434 */
435 int main(int argc, char **argv){
436 const char *zCmdName = "unknown";
437 int idx;
438 int rc;
 
439
440 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
441 memset(&g, 0, sizeof(g));
442 g.now = time(0);
 
 
443 #ifdef FOSSIL_ENABLE_JSON
444 #if defined(NDEBUG)
445 g.json.errorDetailParanoia = 2 /* FIXME: make configurable
446 One problem we have here is that this
447 code is needed before the db is opened,
@@ -429,12 +451,11 @@
451 #endif
452 g.json.outOpt = cson_output_opt_empty;
453 g.json.outOpt.addNewline = 1;
454 g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
455 #endif /* FOSSIL_ENABLE_JSON */
456 expand_args_option(argc, argv);
 
457 #ifdef FOSSIL_ENABLE_TCL
458 g.tcl.argc = g.argc;
459 g.tcl.argv = g.argv;
460 g.tcl.interp = 0;
461 #endif
@@ -514,15 +535,11 @@
535
536 /*
537 ** Return the name of the current executable.
538 */
539 const char *fossil_nameofexe(void){
 
 
 
540 return g.argv[0];
 
541 }
542
543 /*
544 ** Exit. Take care to close the database first.
545 */
@@ -1432,11 +1449,11 @@
1449 blob_read_from_file(&config, zFile);
1450 while( blob_line(&config, &line) ){
1451 if( !blob_token(&line, &key) ) continue;
1452 if( blob_buffer(&key)[0]=='#' ) continue;
1453 if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){
1454 g.fDebug = fossil_fopen(blob_str(&value), "a");
1455 blob_reset(&value);
1456 continue;
1457 }
1458 if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
1459 cgi_setenv("HOME", blob_str(&value));
1460
+31 -14
--- src/main.c
+++ src/main.c
@@ -24,11 +24,13 @@
2424
#include <time.h>
2525
#include <fcntl.h>
2626
#include <sys/types.h>
2727
#include <sys/stat.h>
2828
#include <stdlib.h> /* atexit() */
29
-#if !defined(_WIN32)
29
+#if defined(_WIN32)
30
+# include <windows.h>
31
+#else
3032
# include <errno.h> /* errno global */
3133
#endif
3234
#if INTERFACE
3335
#ifdef FOSSIL_ENABLE_JSON
3436
# include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */
@@ -329,29 +331,42 @@
329331
db_close(0);
330332
}
331333
}
332334
333335
/*
334
-** Search g.argv for arguments "--args FILENAME". If found, then
336
+** Convert all arguments from mbcs to UTF-8. Then
337
+** search g.argv for arguments "--args FILENAME". If found, then
335338
** (1) remove the two arguments from g.argv
336339
** (2) Read the file FILENAME
337340
** (3) Use the contents of FILE to replace the two removed arguments:
338341
** (a) Ignore blank lines in the file
339342
** (b) Each non-empty line of the file is an argument, except
340343
** (c) If the line begins with "-" and contains a space, it is broken
341344
** into two arguments at the space.
342345
*/
343
-static void expand_args_option(void){
346
+static void expand_args_option(int argc, char **argv){
344347
Blob file = empty_blob; /* Content of the file */
345348
Blob line = empty_blob; /* One line of the file */
346349
unsigned int nLine; /* Number of lines in the file*/
347350
unsigned int i, j, k; /* Loop counters */
348351
int n; /* Number of bytes in one line */
349352
char *z; /* General use string pointer */
350353
char **newArgv; /* New expanded g.argv under construction */
351354
char const * zFileName; /* input file name */
352355
FILE * zInFile; /* input FILE */
356
+ int foundBom = -1; /* -1= not searched yet, 0 = no; 1=yes */
357
+#ifdef _WIN32
358
+ wchar_t buf[MAX_PATH];
359
+#endif
360
+
361
+ g.argc = argc;
362
+ g.argv = argv;
363
+#ifdef _WIN32
364
+ GetModuleFileNameW(NULL, buf, MAX_PATH);
365
+ g.argv[0] = fossil_unicode_to_utf8(buf);
366
+ for(i=1; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
367
+#endif
353368
for(i=1; i<g.argc-1; i++){
354369
z = g.argv[i];
355370
if( z[0]!='-' ) continue;
356371
z++;
357372
if( z[0]=='-' ) z++;
@@ -361,11 +376,11 @@
361376
if( i>=g.argc-1 ) return;
362377
363378
zFileName = g.argv[i+1];
364379
zInFile = (0==strcmp("-",zFileName))
365380
? stdin
366
- : fopen(zFileName,"rb");
381
+ : fossil_fopen(zFileName,"rb");
367382
if(!zInFile){
368383
fossil_panic("Cannot open -args file [%s]", zFileName);
369384
}else{
370385
blob_read_from_channel(&file, zInFile, -1);
371386
if(stdin != zInFile){
@@ -381,14 +396,24 @@
381396
blob_rewind(&file);
382397
while( (n = blob_line(&file, &line))>0 ){
383398
if( n<=1 ) continue;
384399
z = blob_buffer(&line);
385400
z[n-1] = 0;
401
+ if (foundBom == -1) {
402
+ static const char bom[] = { 0xEF, 0xBB, 0xBF };
403
+ foundBom = memcmp(z, bom, 3)==0;
404
+ if( foundBom ) {
405
+ z += 3; n -= 3;
406
+ }
407
+ }
386408
if((n>1) && ('\r'==z[n-2])){
387409
if(n==2) continue /*empty line*/;
388410
z[n-2] = 0;
389411
}
412
+ if (!foundBom) {
413
+ z = fossil_mbcs_to_utf8(z);
414
+ }
390415
newArgv[j++] = z;
391416
if( z[0]=='-' ){
392417
for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
393418
if( z[k] ){
394419
z[k] = 0;
@@ -409,17 +434,14 @@
409434
*/
410435
int main(int argc, char **argv){
411436
const char *zCmdName = "unknown";
412437
int idx;
413438
int rc;
414
- int i;
415439
416440
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
417441
memset(&g, 0, sizeof(g));
418442
g.now = time(0);
419
- g.argc = argc;
420
- g.argv = argv;
421443
#ifdef FOSSIL_ENABLE_JSON
422444
#if defined(NDEBUG)
423445
g.json.errorDetailParanoia = 2 /* FIXME: make configurable
424446
One problem we have here is that this
425447
code is needed before the db is opened,
@@ -429,12 +451,11 @@
429451
#endif
430452
g.json.outOpt = cson_output_opt_empty;
431453
g.json.outOpt.addNewline = 1;
432454
g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
433455
#endif /* FOSSIL_ENABLE_JSON */
434
- expand_args_option();
435
- for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
456
+ expand_args_option(argc, argv);
436457
#ifdef FOSSIL_ENABLE_TCL
437458
g.tcl.argc = g.argc;
438459
g.tcl.argv = g.argv;
439460
g.tcl.interp = 0;
440461
#endif
@@ -514,15 +535,11 @@
514535
515536
/*
516537
** Return the name of the current executable.
517538
*/
518539
const char *fossil_nameofexe(void){
519
-#ifdef _WIN32
520
- return _pgmptr;
521
-#else
522540
return g.argv[0];
523
-#endif
524541
}
525542
526543
/*
527544
** Exit. Take care to close the database first.
528545
*/
@@ -1432,11 +1449,11 @@
14321449
blob_read_from_file(&config, zFile);
14331450
while( blob_line(&config, &line) ){
14341451
if( !blob_token(&line, &key) ) continue;
14351452
if( blob_buffer(&key)[0]=='#' ) continue;
14361453
if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){
1437
- g.fDebug = fopen(blob_str(&value), "a");
1454
+ g.fDebug = fossil_fopen(blob_str(&value), "a");
14381455
blob_reset(&value);
14391456
continue;
14401457
}
14411458
if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
14421459
cgi_setenv("HOME", blob_str(&value));
14431460
--- src/main.c
+++ src/main.c
@@ -24,11 +24,13 @@
24 #include <time.h>
25 #include <fcntl.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdlib.h> /* atexit() */
29 #if !defined(_WIN32)
 
 
30 # include <errno.h> /* errno global */
31 #endif
32 #if INTERFACE
33 #ifdef FOSSIL_ENABLE_JSON
34 # include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */
@@ -329,29 +331,42 @@
329 db_close(0);
330 }
331 }
332
333 /*
334 ** Search g.argv for arguments "--args FILENAME". If found, then
 
335 ** (1) remove the two arguments from g.argv
336 ** (2) Read the file FILENAME
337 ** (3) Use the contents of FILE to replace the two removed arguments:
338 ** (a) Ignore blank lines in the file
339 ** (b) Each non-empty line of the file is an argument, except
340 ** (c) If the line begins with "-" and contains a space, it is broken
341 ** into two arguments at the space.
342 */
343 static void expand_args_option(void){
344 Blob file = empty_blob; /* Content of the file */
345 Blob line = empty_blob; /* One line of the file */
346 unsigned int nLine; /* Number of lines in the file*/
347 unsigned int i, j, k; /* Loop counters */
348 int n; /* Number of bytes in one line */
349 char *z; /* General use string pointer */
350 char **newArgv; /* New expanded g.argv under construction */
351 char const * zFileName; /* input file name */
352 FILE * zInFile; /* input FILE */
 
 
 
 
 
 
 
 
 
 
 
 
353 for(i=1; i<g.argc-1; i++){
354 z = g.argv[i];
355 if( z[0]!='-' ) continue;
356 z++;
357 if( z[0]=='-' ) z++;
@@ -361,11 +376,11 @@
361 if( i>=g.argc-1 ) return;
362
363 zFileName = g.argv[i+1];
364 zInFile = (0==strcmp("-",zFileName))
365 ? stdin
366 : fopen(zFileName,"rb");
367 if(!zInFile){
368 fossil_panic("Cannot open -args file [%s]", zFileName);
369 }else{
370 blob_read_from_channel(&file, zInFile, -1);
371 if(stdin != zInFile){
@@ -381,14 +396,24 @@
381 blob_rewind(&file);
382 while( (n = blob_line(&file, &line))>0 ){
383 if( n<=1 ) continue;
384 z = blob_buffer(&line);
385 z[n-1] = 0;
 
 
 
 
 
 
 
386 if((n>1) && ('\r'==z[n-2])){
387 if(n==2) continue /*empty line*/;
388 z[n-2] = 0;
389 }
 
 
 
390 newArgv[j++] = z;
391 if( z[0]=='-' ){
392 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
393 if( z[k] ){
394 z[k] = 0;
@@ -409,17 +434,14 @@
409 */
410 int main(int argc, char **argv){
411 const char *zCmdName = "unknown";
412 int idx;
413 int rc;
414 int i;
415
416 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
417 memset(&g, 0, sizeof(g));
418 g.now = time(0);
419 g.argc = argc;
420 g.argv = argv;
421 #ifdef FOSSIL_ENABLE_JSON
422 #if defined(NDEBUG)
423 g.json.errorDetailParanoia = 2 /* FIXME: make configurable
424 One problem we have here is that this
425 code is needed before the db is opened,
@@ -429,12 +451,11 @@
429 #endif
430 g.json.outOpt = cson_output_opt_empty;
431 g.json.outOpt.addNewline = 1;
432 g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
433 #endif /* FOSSIL_ENABLE_JSON */
434 expand_args_option();
435 for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
436 #ifdef FOSSIL_ENABLE_TCL
437 g.tcl.argc = g.argc;
438 g.tcl.argv = g.argv;
439 g.tcl.interp = 0;
440 #endif
@@ -514,15 +535,11 @@
514
515 /*
516 ** Return the name of the current executable.
517 */
518 const char *fossil_nameofexe(void){
519 #ifdef _WIN32
520 return _pgmptr;
521 #else
522 return g.argv[0];
523 #endif
524 }
525
526 /*
527 ** Exit. Take care to close the database first.
528 */
@@ -1432,11 +1449,11 @@
1432 blob_read_from_file(&config, zFile);
1433 while( blob_line(&config, &line) ){
1434 if( !blob_token(&line, &key) ) continue;
1435 if( blob_buffer(&key)[0]=='#' ) continue;
1436 if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){
1437 g.fDebug = fopen(blob_str(&value), "a");
1438 blob_reset(&value);
1439 continue;
1440 }
1441 if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
1442 cgi_setenv("HOME", blob_str(&value));
1443
--- src/main.c
+++ src/main.c
@@ -24,11 +24,13 @@
24 #include <time.h>
25 #include <fcntl.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdlib.h> /* atexit() */
29 #if defined(_WIN32)
30 # include <windows.h>
31 #else
32 # include <errno.h> /* errno global */
33 #endif
34 #if INTERFACE
35 #ifdef FOSSIL_ENABLE_JSON
36 # include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */
@@ -329,29 +331,42 @@
331 db_close(0);
332 }
333 }
334
335 /*
336 ** Convert all arguments from mbcs to UTF-8. Then
337 ** search g.argv for arguments "--args FILENAME". If found, then
338 ** (1) remove the two arguments from g.argv
339 ** (2) Read the file FILENAME
340 ** (3) Use the contents of FILE to replace the two removed arguments:
341 ** (a) Ignore blank lines in the file
342 ** (b) Each non-empty line of the file is an argument, except
343 ** (c) If the line begins with "-" and contains a space, it is broken
344 ** into two arguments at the space.
345 */
346 static void expand_args_option(int argc, char **argv){
347 Blob file = empty_blob; /* Content of the file */
348 Blob line = empty_blob; /* One line of the file */
349 unsigned int nLine; /* Number of lines in the file*/
350 unsigned int i, j, k; /* Loop counters */
351 int n; /* Number of bytes in one line */
352 char *z; /* General use string pointer */
353 char **newArgv; /* New expanded g.argv under construction */
354 char const * zFileName; /* input file name */
355 FILE * zInFile; /* input FILE */
356 int foundBom = -1; /* -1= not searched yet, 0 = no; 1=yes */
357 #ifdef _WIN32
358 wchar_t buf[MAX_PATH];
359 #endif
360
361 g.argc = argc;
362 g.argv = argv;
363 #ifdef _WIN32
364 GetModuleFileNameW(NULL, buf, MAX_PATH);
365 g.argv[0] = fossil_unicode_to_utf8(buf);
366 for(i=1; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
367 #endif
368 for(i=1; i<g.argc-1; i++){
369 z = g.argv[i];
370 if( z[0]!='-' ) continue;
371 z++;
372 if( z[0]=='-' ) z++;
@@ -361,11 +376,11 @@
376 if( i>=g.argc-1 ) return;
377
378 zFileName = g.argv[i+1];
379 zInFile = (0==strcmp("-",zFileName))
380 ? stdin
381 : fossil_fopen(zFileName,"rb");
382 if(!zInFile){
383 fossil_panic("Cannot open -args file [%s]", zFileName);
384 }else{
385 blob_read_from_channel(&file, zInFile, -1);
386 if(stdin != zInFile){
@@ -381,14 +396,24 @@
396 blob_rewind(&file);
397 while( (n = blob_line(&file, &line))>0 ){
398 if( n<=1 ) continue;
399 z = blob_buffer(&line);
400 z[n-1] = 0;
401 if (foundBom == -1) {
402 static const char bom[] = { 0xEF, 0xBB, 0xBF };
403 foundBom = memcmp(z, bom, 3)==0;
404 if( foundBom ) {
405 z += 3; n -= 3;
406 }
407 }
408 if((n>1) && ('\r'==z[n-2])){
409 if(n==2) continue /*empty line*/;
410 z[n-2] = 0;
411 }
412 if (!foundBom) {
413 z = fossil_mbcs_to_utf8(z);
414 }
415 newArgv[j++] = z;
416 if( z[0]=='-' ){
417 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
418 if( z[k] ){
419 z[k] = 0;
@@ -409,17 +434,14 @@
434 */
435 int main(int argc, char **argv){
436 const char *zCmdName = "unknown";
437 int idx;
438 int rc;
 
439
440 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
441 memset(&g, 0, sizeof(g));
442 g.now = time(0);
 
 
443 #ifdef FOSSIL_ENABLE_JSON
444 #if defined(NDEBUG)
445 g.json.errorDetailParanoia = 2 /* FIXME: make configurable
446 One problem we have here is that this
447 code is needed before the db is opened,
@@ -429,12 +451,11 @@
451 #endif
452 g.json.outOpt = cson_output_opt_empty;
453 g.json.outOpt.addNewline = 1;
454 g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */;
455 #endif /* FOSSIL_ENABLE_JSON */
456 expand_args_option(argc, argv);
 
457 #ifdef FOSSIL_ENABLE_TCL
458 g.tcl.argc = g.argc;
459 g.tcl.argv = g.argv;
460 g.tcl.interp = 0;
461 #endif
@@ -514,15 +535,11 @@
535
536 /*
537 ** Return the name of the current executable.
538 */
539 const char *fossil_nameofexe(void){
 
 
 
540 return g.argv[0];
 
541 }
542
543 /*
544 ** Exit. Take care to close the database first.
545 */
@@ -1432,11 +1449,11 @@
1449 blob_read_from_file(&config, zFile);
1450 while( blob_line(&config, &line) ){
1451 if( !blob_token(&line, &key) ) continue;
1452 if( blob_buffer(&key)[0]=='#' ) continue;
1453 if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){
1454 g.fDebug = fossil_fopen(blob_str(&value), "a");
1455 blob_reset(&value);
1456 continue;
1457 }
1458 if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
1459 cgi_setenv("HOME", blob_str(&value));
1460
+4 -4
--- src/popen.c
+++ src/popen.c
@@ -65,17 +65,17 @@
6565
** and stderr channels for that process to use.
6666
**
6767
** Return the number of errors.
6868
*/
6969
static int win32_create_child_process(
70
- char *zCmd, /* The command that the child process will run */
70
+ wchar_t *zCmd, /* The command that the child process will run */
7171
HANDLE hIn, /* Standard input */
7272
HANDLE hOut, /* Standard output */
7373
HANDLE hErr, /* Standard error */
7474
DWORD *pChildPid /* OUT: Child process handle */
7575
){
76
- STARTUPINFO si;
76
+ STARTUPINFOW si;
7777
PROCESS_INFORMATION pi;
7878
BOOL rc;
7979
8080
memset(&si, 0, sizeof(si));
8181
si.cb = sizeof(si);
@@ -84,11 +84,11 @@
8484
si.hStdInput = hIn;
8585
SetHandleInformation(hOut, HANDLE_FLAG_INHERIT, TRUE);
8686
si.hStdOutput = hOut;
8787
SetHandleInformation(hErr, HANDLE_FLAG_INHERIT, TRUE);
8888
si.hStdError = hErr;
89
- rc = CreateProcess(
89
+ rc = CreateProcessW(
9090
NULL, /* Application Name */
9191
zCmd, /* Command-line */
9292
NULL, /* Process attributes */
9393
NULL, /* Thread attributes */
9494
TRUE, /* Inherit Handles */
@@ -139,11 +139,11 @@
139139
if( !CreatePipe(&hStdinRd, &hStdinWr, &saAttr, 4096) ){
140140
win32_fatal_error("cannot create pipe for stdin");
141141
}
142142
SetHandleInformation( hStdinWr, HANDLE_FLAG_INHERIT, FALSE);
143143
144
- win32_create_child_process((char*)zCmd,
144
+ win32_create_child_process(fossil_utf8_to_unicode(zCmd),
145145
hStdinRd, hStdoutWr, hStderr,&childPid);
146146
*pChildPid = childPid;
147147
*pfdIn = _open_osfhandle(PTR_TO_INT(hStdoutRd), 0);
148148
fd = _open_osfhandle(PTR_TO_INT(hStdinWr), 0);
149149
*ppOut = _fdopen(fd, "w");
150150
--- src/popen.c
+++ src/popen.c
@@ -65,17 +65,17 @@
65 ** and stderr channels for that process to use.
66 **
67 ** Return the number of errors.
68 */
69 static int win32_create_child_process(
70 char *zCmd, /* The command that the child process will run */
71 HANDLE hIn, /* Standard input */
72 HANDLE hOut, /* Standard output */
73 HANDLE hErr, /* Standard error */
74 DWORD *pChildPid /* OUT: Child process handle */
75 ){
76 STARTUPINFO si;
77 PROCESS_INFORMATION pi;
78 BOOL rc;
79
80 memset(&si, 0, sizeof(si));
81 si.cb = sizeof(si);
@@ -84,11 +84,11 @@
84 si.hStdInput = hIn;
85 SetHandleInformation(hOut, HANDLE_FLAG_INHERIT, TRUE);
86 si.hStdOutput = hOut;
87 SetHandleInformation(hErr, HANDLE_FLAG_INHERIT, TRUE);
88 si.hStdError = hErr;
89 rc = CreateProcess(
90 NULL, /* Application Name */
91 zCmd, /* Command-line */
92 NULL, /* Process attributes */
93 NULL, /* Thread attributes */
94 TRUE, /* Inherit Handles */
@@ -139,11 +139,11 @@
139 if( !CreatePipe(&hStdinRd, &hStdinWr, &saAttr, 4096) ){
140 win32_fatal_error("cannot create pipe for stdin");
141 }
142 SetHandleInformation( hStdinWr, HANDLE_FLAG_INHERIT, FALSE);
143
144 win32_create_child_process((char*)zCmd,
145 hStdinRd, hStdoutWr, hStderr,&childPid);
146 *pChildPid = childPid;
147 *pfdIn = _open_osfhandle(PTR_TO_INT(hStdoutRd), 0);
148 fd = _open_osfhandle(PTR_TO_INT(hStdinWr), 0);
149 *ppOut = _fdopen(fd, "w");
150
--- src/popen.c
+++ src/popen.c
@@ -65,17 +65,17 @@
65 ** and stderr channels for that process to use.
66 **
67 ** Return the number of errors.
68 */
69 static int win32_create_child_process(
70 wchar_t *zCmd, /* The command that the child process will run */
71 HANDLE hIn, /* Standard input */
72 HANDLE hOut, /* Standard output */
73 HANDLE hErr, /* Standard error */
74 DWORD *pChildPid /* OUT: Child process handle */
75 ){
76 STARTUPINFOW si;
77 PROCESS_INFORMATION pi;
78 BOOL rc;
79
80 memset(&si, 0, sizeof(si));
81 si.cb = sizeof(si);
@@ -84,11 +84,11 @@
84 si.hStdInput = hIn;
85 SetHandleInformation(hOut, HANDLE_FLAG_INHERIT, TRUE);
86 si.hStdOutput = hOut;
87 SetHandleInformation(hErr, HANDLE_FLAG_INHERIT, TRUE);
88 si.hStdError = hErr;
89 rc = CreateProcessW(
90 NULL, /* Application Name */
91 zCmd, /* Command-line */
92 NULL, /* Process attributes */
93 NULL, /* Thread attributes */
94 TRUE, /* Inherit Handles */
@@ -139,11 +139,11 @@
139 if( !CreatePipe(&hStdinRd, &hStdinWr, &saAttr, 4096) ){
140 win32_fatal_error("cannot create pipe for stdin");
141 }
142 SetHandleInformation( hStdinWr, HANDLE_FLAG_INHERIT, FALSE);
143
144 win32_create_child_process(fossil_utf8_to_unicode(zCmd),
145 hStdinRd, hStdoutWr, hStderr,&childPid);
146 *pChildPid = childPid;
147 *pfdIn = _open_osfhandle(PTR_TO_INT(hStdoutRd), 0);
148 fd = _open_osfhandle(PTR_TO_INT(hStdinWr), 0);
149 *ppOut = _fdopen(fd, "w");
150

Keyboard Shortcuts

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