diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/kconfig/mconf.c | 229 |
1 files changed, 223 insertions, 6 deletions
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 55afeb763..1112daa56 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #ifndef __MINGW32__ | 15 | #ifndef __MINGW32__ |
| 16 | #include <sys/ioctl.h> | 16 | #include <sys/ioctl.h> |
| 17 | #include <sys/wait.h> | 17 | #include <sys/wait.h> |
| 18 | #else | ||
| 19 | #include <windows.h> | ||
| 18 | #endif | 20 | #endif |
| 19 | #include <ctype.h> | 21 | #include <ctype.h> |
| 20 | #include <errno.h> | 22 | #include <errno.h> |
| @@ -302,15 +304,45 @@ static int cprint1(const char *fmt, ...); | |||
| 302 | static void cprint_done(void); | 304 | static void cprint_done(void); |
| 303 | static int cprint(const char *fmt, ...); | 305 | static int cprint(const char *fmt, ...); |
| 304 | 306 | ||
| 307 | #ifdef __MINGW32__ | ||
| 308 | struct winsize { | ||
| 309 | unsigned short ws_row, ws_col; | ||
| 310 | unsigned short ws_xpixel, ws_ypixel; | ||
| 311 | }; | ||
| 312 | |||
| 313 | static int mingw_get_terminal_width_height(struct winsize *win) | ||
| 314 | { | ||
| 315 | int fd; | ||
| 316 | HANDLE handle; | ||
| 317 | CONSOLE_SCREEN_BUFFER_INFO sbi; | ||
| 318 | |||
| 319 | win->ws_row = 0; | ||
| 320 | win->ws_col = 0; | ||
| 321 | |||
| 322 | for (fd=STDOUT_FILENO; fd<=STDERR_FILENO; ++fd) { | ||
| 323 | handle = (HANDLE)_get_osfhandle(fd); | ||
| 324 | if (handle != INVALID_HANDLE_VALUE && | ||
| 325 | GetConsoleScreenBufferInfo(handle, &sbi) != 0) { | ||
| 326 | win->ws_row = sbi.srWindow.Bottom - sbi.srWindow.Top + 1; | ||
| 327 | win->ws_col = sbi.srWindow.Right - sbi.srWindow.Left + 1; | ||
| 328 | return 0; | ||
| 329 | } | ||
| 330 | } | ||
| 331 | |||
| 332 | return -1; | ||
| 333 | } | ||
| 334 | #endif | ||
| 335 | |||
| 305 | static void init_wsize(void) | 336 | static void init_wsize(void) |
| 306 | { | 337 | { |
| 307 | #ifdef __MINGW32__ | ||
| 308 | fprintf(stderr, "Skipping attempt to change window size\n"); | ||
| 309 | #else | ||
| 310 | struct winsize ws; | 338 | struct winsize ws; |
| 311 | char *env; | 339 | char *env; |
| 312 | 340 | ||
| 341 | #ifndef __MINGW32__ | ||
| 313 | if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) { | 342 | if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) { |
| 343 | #else | ||
| 344 | if (mingw_get_terminal_width_height(&ws) == 0) { | ||
| 345 | #endif | ||
| 314 | rows = ws.ws_row; | 346 | rows = ws.ws_row; |
| 315 | cols = ws.ws_col; | 347 | cols = ws.ws_col; |
| 316 | } | 348 | } |
| @@ -338,7 +370,6 @@ static void init_wsize(void) | |||
| 338 | 370 | ||
| 339 | rows -= 4; | 371 | rows -= 4; |
| 340 | cols -= 5; | 372 | cols -= 5; |
| 341 | #endif | ||
| 342 | } | 373 | } |
| 343 | 374 | ||
| 344 | static void cprint_init(void) | 375 | static void cprint_init(void) |
| @@ -473,11 +504,197 @@ static void winch_handler(int sig) | |||
| 473 | } | 504 | } |
| 474 | #endif | 505 | #endif |
| 475 | 506 | ||
| 507 | #ifdef __MINGW32__ | ||
| 508 | static char * | ||
| 509 | quote_arg(const char *arg) | ||
| 510 | { | ||
| 511 | int len = 0, n = 0; | ||
| 512 | int force_quotes = 0; | ||
| 513 | char *q, *d; | ||
| 514 | const char *p = arg; | ||
| 515 | |||
| 516 | /* empty arguments must be quoted */ | ||
| 517 | if (!*p) { | ||
| 518 | force_quotes = 1; | ||
| 519 | } | ||
| 520 | |||
| 521 | while (*p) { | ||
| 522 | if (isspace(*p)) { | ||
| 523 | /* arguments containing whitespace must be quoted */ | ||
| 524 | force_quotes = 1; | ||
| 525 | } | ||
| 526 | else if (*p == '"') { | ||
| 527 | /* double quotes in arguments need to be escaped */ | ||
| 528 | n++; | ||
| 529 | } | ||
| 530 | else if (*p == '\\') { | ||
| 531 | /* count contiguous backslashes */ | ||
| 532 | int count = 0; | ||
| 533 | while (*p == '\\') { | ||
| 534 | count++; | ||
| 535 | p++; | ||
| 536 | len++; | ||
| 537 | } | ||
| 538 | |||
| 539 | /* | ||
| 540 | * Only escape backslashes before explicit double quotes or | ||
| 541 | * or where the backslashes are at the end of an argument | ||
| 542 | * that is scheduled to be quoted. | ||
| 543 | */ | ||
| 544 | if (*p == '"' || (force_quotes && *p == '\0')) { | ||
| 545 | n += count*2 + 1; | ||
| 546 | } | ||
| 547 | |||
| 548 | if (*p == '\0') { | ||
| 549 | break; | ||
| 550 | } | ||
| 551 | continue; | ||
| 552 | } | ||
| 553 | len++; | ||
| 554 | p++; | ||
| 555 | } | ||
| 556 | |||
| 557 | if (!force_quotes && n == 0) { | ||
| 558 | return (char*)strdup(arg); | ||
| 559 | } | ||
| 560 | |||
| 561 | /* insert double quotes and backslashes where necessary */ | ||
| 562 | d = q = malloc(len+n+3); | ||
| 563 | if (q == NULL) | ||
| 564 | return NULL; | ||
| 565 | if (force_quotes) { | ||
| 566 | *d++ = '"'; | ||
| 567 | } | ||
| 568 | |||
| 569 | while (*arg) { | ||
| 570 | if (*arg == '"') { | ||
| 571 | *d++ = '\\'; | ||
| 572 | } | ||
| 573 | else if (*arg == '\\') { | ||
| 574 | int count = 0; | ||
| 575 | while (*arg == '\\') { | ||
| 576 | count++; | ||
| 577 | *d++ = *arg++; | ||
| 578 | } | ||
| 579 | |||
| 580 | if (*arg == '"' || (force_quotes && *arg == '\0')) { | ||
| 581 | while (count-- > 0) { | ||
| 582 | *d++ = '\\'; | ||
| 583 | } | ||
| 584 | if (*arg == '"') { | ||
| 585 | *d++ = '\\'; | ||
| 586 | } | ||
| 587 | } | ||
| 588 | } | ||
| 589 | if (*arg != '\0') { | ||
| 590 | *d++ = *arg++; | ||
| 591 | } | ||
| 592 | } | ||
| 593 | if (force_quotes) { | ||
| 594 | *d++ = '"'; | ||
| 595 | } | ||
| 596 | *d = '\0'; | ||
| 597 | |||
| 598 | return q; | ||
| 599 | } | ||
| 600 | |||
| 601 | static int mingw_pipe(HANDLE *pipe) | ||
| 602 | { | ||
| 603 | SECURITY_ATTRIBUTES sa; | ||
| 604 | |||
| 605 | sa.nLength = sizeof(sa); /* Length in bytes */ | ||
| 606 | sa.bInheritHandle = 1; /* the child must inherit these handles */ | ||
| 607 | sa.lpSecurityDescriptor = NULL; | ||
| 608 | |||
| 609 | /* pipe[0] is the read handle, pipe[i] the write handle */ | ||
| 610 | if ( !CreatePipe (&pipe[0], &pipe[1], &sa, 1 << 13) ) { | ||
| 611 | return -1; | ||
| 612 | } | ||
| 613 | |||
| 614 | return (pipe[0] == INVALID_HANDLE_VALUE || | ||
| 615 | pipe[1] == INVALID_HANDLE_VALUE) ? -1 : 0; | ||
| 616 | } | ||
| 617 | #endif | ||
| 618 | |||
| 476 | static int exec_conf(void) | 619 | static int exec_conf(void) |
| 477 | { | 620 | { |
| 478 | #ifdef __MINGW32__ | 621 | #ifdef __MINGW32__ |
| 479 | fprintf(stderr, "exec_conf not implemented\n"); | 622 | char **a, *cmd; |
| 480 | exit(1); | 623 | int fd, size, len = 0; |
| 624 | STARTUPINFO siStartInfo; | ||
| 625 | PROCESS_INFORMATION piProcInfo; | ||
| 626 | HANDLE hPipe[2]; | ||
| 627 | DWORD stat = 0; | ||
| 628 | |||
| 629 | // Quote each argument if necessary | ||
| 630 | *argptr++ = NULL; | ||
| 631 | for (a = args; *a; a++) { | ||
| 632 | *a = quote_arg(*a); | ||
| 633 | if (*a == NULL) | ||
| 634 | _exit(EXIT_FAILURE); | ||
| 635 | len += strlen(*a) + 1; | ||
| 636 | } | ||
| 637 | |||
| 638 | // Make a command line from the arguments | ||
| 639 | cmd = malloc(len + 1); | ||
| 640 | if (cmd == NULL) | ||
| 641 | _exit(EXIT_FAILURE); | ||
| 642 | for (a = args; *a; a++) { | ||
| 643 | if (a == args) { | ||
| 644 | strcpy(cmd, *a); | ||
| 645 | } else { | ||
| 646 | strcat(cmd, " "); | ||
| 647 | strcat(cmd, *a); | ||
| 648 | } | ||
| 649 | free(*a); | ||
| 650 | } | ||
| 651 | |||
| 652 | // Create a pipe to communicate with the dialog | ||
| 653 | if (mingw_pipe(hPipe) == -1) | ||
| 654 | _exit(EXIT_FAILURE); | ||
| 655 | |||
| 656 | // Make the parent end of the pipe non-inheritable | ||
| 657 | SetHandleInformation(hPipe[0], HANDLE_FLAG_INHERIT, 0); | ||
| 658 | |||
| 659 | ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); | ||
| 660 | siStartInfo.cb = sizeof(STARTUPINFO); | ||
| 661 | siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); | ||
| 662 | siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); | ||
| 663 | siStartInfo.hStdError = hPipe[1]; | ||
| 664 | siStartInfo.dwFlags = STARTF_USESTDHANDLES; | ||
| 665 | CreateProcess(NULL, (LPSTR)cmd, NULL, NULL, TRUE, 0, NULL, NULL, | ||
| 666 | &siStartInfo, &piProcInfo); | ||
| 667 | free(cmd); | ||
| 668 | |||
| 669 | // Close child end of pipe | ||
| 670 | CloseHandle(hPipe[1]); | ||
| 671 | hPipe[1] = INVALID_HANDLE_VALUE; | ||
| 672 | |||
| 673 | fd = _open_osfhandle((intptr_t)hPipe[0], _O_RDONLY | _O_BINARY); | ||
| 674 | if (fd == -1) | ||
| 675 | _exit(EXIT_FAILURE); | ||
| 676 | |||
| 677 | bufptr = input_buf; | ||
| 678 | while (1) { | ||
| 679 | size = input_buf + sizeof(input_buf) - bufptr; | ||
| 680 | size = _read(fd, bufptr, size); | ||
| 681 | if (size <= 0) { | ||
| 682 | if (size < 0) { | ||
| 683 | if (errno == EINTR || errno == EAGAIN) | ||
| 684 | continue; | ||
| 685 | perror("read"); | ||
| 686 | } | ||
| 687 | break; | ||
| 688 | } | ||
| 689 | bufptr += size; | ||
| 690 | } | ||
| 691 | *bufptr++ = 0; | ||
| 692 | close(fd); | ||
| 693 | |||
| 694 | WaitForSingleObject(piProcInfo.hProcess, INFINITE); | ||
| 695 | GetExitCodeProcess(piProcInfo.hProcess, &stat); | ||
| 696 | |||
| 697 | return (int)stat; | ||
| 481 | #else | 698 | #else |
| 482 | int pipefd[2], stat, size; | 699 | int pipefd[2], stat, size; |
| 483 | sigset_t sset, osset; | 700 | sigset_t sset, osset; |
