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); |