diff options
-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; |