diff options
Diffstat (limited to 'scripts/kconfig/mconf.c')
| -rw-r--r-- | scripts/kconfig/mconf.c | 242 |
1 files changed, 241 insertions, 1 deletions
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index aaf82820e..62baa82b0 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c | |||
| @@ -12,8 +12,12 @@ | |||
| 12 | /* On Darwin, this may be needed to get SIGWINCH: */ | 12 | /* On Darwin, this may be needed to get SIGWINCH: */ |
| 13 | #define _DARWIN_C_SOURCE 1 | 13 | #define _DARWIN_C_SOURCE 1 |
| 14 | 14 | ||
| 15 | #ifndef __MINGW32__ | ||
| 15 | #include <sys/ioctl.h> | 16 | #include <sys/ioctl.h> |
| 16 | #include <sys/wait.h> | 17 | #include <sys/wait.h> |
| 18 | #else | ||
| 19 | #include <windows.h> | ||
| 20 | #endif | ||
| 17 | #include <ctype.h> | 21 | #include <ctype.h> |
| 18 | #include <errno.h> | 22 | #include <errno.h> |
| 19 | #include <fcntl.h> | 23 | #include <fcntl.h> |
| @@ -23,13 +27,17 @@ | |||
| 23 | #include <stdlib.h> | 27 | #include <stdlib.h> |
| 24 | #include <string.h> | 28 | #include <string.h> |
| 25 | #include <strings.h> /* for strcasecmp */ | 29 | #include <strings.h> /* for strcasecmp */ |
| 30 | #ifndef __MINGW32__ | ||
| 26 | #include <termios.h> | 31 | #include <termios.h> |
| 32 | #endif | ||
| 27 | #include <unistd.h> | 33 | #include <unistd.h> |
| 28 | #include <locale.h> | 34 | #include <locale.h> |
| 29 | 35 | ||
| 36 | #ifndef __MINGW32__ | ||
| 30 | #ifndef SIGWINCH | 37 | #ifndef SIGWINCH |
| 31 | #define SIGWINCH 28 | 38 | #define SIGWINCH 28 |
| 32 | #endif | 39 | #endif |
| 40 | #endif | ||
| 33 | 41 | ||
| 34 | #define LKC_DIRECT_LINK | 42 | #define LKC_DIRECT_LINK |
| 35 | #include "lkc.h" | 43 | #include "lkc.h" |
| @@ -270,11 +278,15 @@ static char input_buf[4096]; | |||
| 270 | static const char filename[] = ".config"; | 278 | static const char filename[] = ".config"; |
| 271 | static char *args[1024], **argptr = args; | 279 | static char *args[1024], **argptr = args; |
| 272 | static int indent; | 280 | static int indent; |
| 281 | #ifndef __MINGW32__ | ||
| 273 | static struct termios ios_org; | 282 | static struct termios ios_org; |
| 283 | #endif | ||
| 274 | static int rows = 0, cols = 0; | 284 | static int rows = 0, cols = 0; |
| 275 | static struct menu *current_menu; | 285 | static struct menu *current_menu; |
| 276 | static int child_count; | 286 | static int child_count; |
| 287 | #ifndef __MINGW32__ | ||
| 277 | static int do_resize; | 288 | static int do_resize; |
| 289 | #endif | ||
| 278 | static int single_menu_mode; | 290 | static int single_menu_mode; |
| 279 | 291 | ||
| 280 | static void conf(struct menu *menu); | 292 | static void conf(struct menu *menu); |
| @@ -292,12 +304,45 @@ static int cprint1(const char *fmt, ...); | |||
| 292 | static void cprint_done(void); | 304 | static void cprint_done(void); |
| 293 | static int cprint(const char *fmt, ...); | 305 | static int cprint(const char *fmt, ...); |
| 294 | 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 | |||
| 295 | static void init_wsize(void) | 336 | static void init_wsize(void) |
| 296 | { | 337 | { |
| 297 | struct winsize ws; | 338 | struct winsize ws; |
| 298 | char *env; | 339 | char *env; |
| 299 | 340 | ||
| 341 | #ifndef __MINGW32__ | ||
| 300 | 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 | ||
| 301 | rows = ws.ws_row; | 346 | rows = ws.ws_row; |
| 302 | cols = ws.ws_col; | 347 | cols = ws.ws_col; |
| 303 | } | 348 | } |
| @@ -459,8 +504,198 @@ static void winch_handler(int sig) | |||
| 459 | } | 504 | } |
| 460 | #endif | 505 | #endif |
| 461 | 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 | |||
| 462 | static int exec_conf(void) | 619 | static int exec_conf(void) |
| 463 | { | 620 | { |
| 621 | #ifdef __MINGW32__ | ||
| 622 | char **a, *cmd; | ||
| 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 &0xff); | ||
| 698 | #else | ||
| 464 | int pipefd[2], stat, size; | 699 | int pipefd[2], stat, size; |
| 465 | sigset_t sset, osset; | 700 | sigset_t sset, osset; |
| 466 | 701 | ||
| @@ -535,6 +770,7 @@ static int exec_conf(void) | |||
| 535 | sigprocmask(SIG_SETMASK, &osset, NULL); | 770 | sigprocmask(SIG_SETMASK, &osset, NULL); |
| 536 | 771 | ||
| 537 | return WEXITSTATUS(stat); | 772 | return WEXITSTATUS(stat); |
| 773 | #endif | ||
| 538 | } | 774 | } |
| 539 | 775 | ||
| 540 | static void search_conf(void) | 776 | static void search_conf(void) |
| @@ -788,7 +1024,7 @@ static void conf(struct menu *menu) | |||
| 788 | switch (type) { | 1024 | switch (type) { |
| 789 | case 'm': | 1025 | case 'm': |
| 790 | if (single_menu_mode) | 1026 | if (single_menu_mode) |
| 791 | submenu->data = (void *) (long) !submenu->data; | 1027 | submenu->data = (void *) (intptr_t) !submenu->data; |
| 792 | else | 1028 | else |
| 793 | conf(submenu); | 1029 | conf(submenu); |
| 794 | break; | 1030 | break; |
| @@ -1051,7 +1287,9 @@ static void conf_save(void) | |||
| 1051 | 1287 | ||
| 1052 | static void conf_cleanup(void) | 1288 | static void conf_cleanup(void) |
| 1053 | { | 1289 | { |
| 1290 | #ifndef __MINGW32__ | ||
| 1054 | tcsetattr(1, TCSAFLUSH, &ios_org); | 1291 | tcsetattr(1, TCSAFLUSH, &ios_org); |
| 1292 | #endif | ||
| 1055 | unlink(".help.tmp"); | 1293 | unlink(".help.tmp"); |
| 1056 | unlink("lxdialog.scrltmp"); | 1294 | unlink("lxdialog.scrltmp"); |
| 1057 | } | 1295 | } |
| @@ -1080,7 +1318,9 @@ int main(int ac, char **av) | |||
| 1080 | single_menu_mode = 1; | 1318 | single_menu_mode = 1; |
| 1081 | } | 1319 | } |
| 1082 | 1320 | ||
| 1321 | #ifndef __MINGW32__ | ||
| 1083 | tcgetattr(1, &ios_org); | 1322 | tcgetattr(1, &ios_org); |
| 1323 | #endif | ||
| 1084 | atexit(conf_cleanup); | 1324 | atexit(conf_cleanup); |
| 1085 | init_wsize(); | 1325 | init_wsize(); |
| 1086 | conf(&rootmenu); | 1326 | conf(&rootmenu); |
