aboutsummaryrefslogtreecommitdiff
path: root/scripts/kconfig/mconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kconfig/mconf.c')
-rw-r--r--scripts/kconfig/mconf.c242
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];
270static const char filename[] = ".config"; 278static const char filename[] = ".config";
271static char *args[1024], **argptr = args; 279static char *args[1024], **argptr = args;
272static int indent; 280static int indent;
281#ifndef __MINGW32__
273static struct termios ios_org; 282static struct termios ios_org;
283#endif
274static int rows = 0, cols = 0; 284static int rows = 0, cols = 0;
275static struct menu *current_menu; 285static struct menu *current_menu;
276static int child_count; 286static int child_count;
287#ifndef __MINGW32__
277static int do_resize; 288static int do_resize;
289#endif
278static int single_menu_mode; 290static int single_menu_mode;
279 291
280static void conf(struct menu *menu); 292static void conf(struct menu *menu);
@@ -292,12 +304,45 @@ static int cprint1(const char *fmt, ...);
292static void cprint_done(void); 304static void cprint_done(void);
293static int cprint(const char *fmt, ...); 305static int cprint(const char *fmt, ...);
294 306
307#ifdef __MINGW32__
308struct winsize {
309 unsigned short ws_row, ws_col;
310 unsigned short ws_xpixel, ws_ypixel;
311};
312
313static 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
295static void init_wsize(void) 336static 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__
508static char *
509quote_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
601static 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
462static int exec_conf(void) 619static 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
540static void search_conf(void) 776static 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
1052static void conf_cleanup(void) 1288static 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);