From 762c577e6a5debcf9a296e781241acc857d12031 Mon Sep 17 00:00:00 2001 From: Albom Date: Fri, 23 Mar 2012 18:53:16 +0000 Subject: [PATCH] shell 0.5 could run console apps git-svn-id: svn://kolibrios.org@2502 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/system/shell/Docs_rus.txt | 23 ++++ programs/system/shell/History.txt | 20 ++++ programs/system/shell/all.h | 1 + programs/system/shell/cmd/cmd_ps.c | 8 +- programs/system/shell/compile_rus.bat | 2 +- programs/system/shell/compile_test.bat | 14 +++ programs/system/shell/globals.h | 2 +- .../system/shell/modules/module_executable.c | 14 ++- .../shell/modules/module_program_console.c | 95 +++++++++++++++ programs/system/shell/program_console.h | 8 ++ programs/system/shell/system/kolibri.c | 30 +++-- programs/system/shell/system/kolibri.h | 16 ++- programs/system/shell/system/string.c | 16 +++ programs/system/shell/system/string.h | 1 + programs/system/shell/test.c | 109 ++++++++++++++++++ 15 files changed, 336 insertions(+), 23 deletions(-) create mode 100644 programs/system/shell/Docs_rus.txt create mode 100644 programs/system/shell/compile_test.bat create mode 100644 programs/system/shell/modules/module_program_console.c create mode 100644 programs/system/shell/program_console.h create mode 100644 programs/system/shell/test.c diff --git a/programs/system/shell/Docs_rus.txt b/programs/system/shell/Docs_rus.txt new file mode 100644 index 0000000000..e2ad4ea51e --- /dev/null +++ b/programs/system/shell/Docs_rus.txt @@ -0,0 +1,23 @@ +Shell 0.5 // 23.03.2012 // Albom +======================================= +* Добавлена поддержка консольных приложений, которые общаются с шеллом через именованную область + +Консольное приложение может быть написано на любом языке программирования - это обыкновенная программа для КолибриОС. + +1) Консольное приложение после своего запуска В ПЕРВУЮ ОЧЕРЕДЬ должно создать именованную область с именем pid-SHELL, где pid - идентификатор процесса с заглавными нулями, +например: 42 -> 0042 (т.е. сейчас ограничение до 9999). ++ нужно сделать, чтобы программа корректно завершалась, если запущена не из шелла (СЕЙЧАС НЕ РЕАЛИЗОВАНО!!!) + +2) Первый байт области - команда (т.е. максимум 255 команд), далее - данные (могут отсутствовать). +Список команд для версии 0.5: +SC_OK 0 ничего не делать +SC_EXIT 1 выход +SC_PUTC 2 вывести на экран символ +SC_PUTS 3 вывести на экран строку +SC_GETC 4 считать с клавиатуры символ +SC_GETS 5 считать с клавиатуры строку +SC_CLS 6 очистить экран + +3) Программа должна САМА заботиться о рациональном использовании процессорного времени. + +4) Программа должна САМА заботиться о закрытии именованной области. diff --git a/programs/system/shell/History.txt b/programs/system/shell/History.txt index 44a76709de..85534ae202 100644 --- a/programs/system/shell/History.txt +++ b/programs/system/shell/History.txt @@ -1,22 +1,32 @@ +Shell 0.5 // 23.03.2012 // Albom +======================================= +* Добавлена поддержка консольных приложений, которые общаются с шеллом через именованную область + + Shell 0.4.6 // 30.01.2011 // Albom +======================================= * Временно удалены команды killall и ccpuid (чтобы вернуть, необходимо раскомментировать 2 строчки) * Исправления в текстовых строках + Shell 0.4.52 // 25.10.2010 // Pterox ======================================= * Добавлена команда "killall" - убивает все процессы кроме OS/IDLE. * Фиксы + Shell 0.4.51 // 21.10.2010 // Pterox ======================================= * Команда "turnoff" переименована в "shutdown", "kerver" удалена - теперь её заменяет "ver kernel"; фиксы. + Shell 0.4.5 // 19.10.2010 // Pterox ======================================= Программа теперь многоязыковая (английский, и русский язык). Программа полностью русифицированна. * Команда "free" переименована в "memory" - для точности. * Добавлены команды turnoff (выключить компьютер), kerver (версия ядра KoOS), uptime; reboot теперь может перезагружать ядро ("reboot kernel") + Shell 0.4.4 // 20.08.2010 // Albom ======================================= 1) шелл корректно завершается при закрытии окна @@ -29,19 +39,23 @@ Shell 0.4.4 // 20.08.2010 // Albom 1) добавить переменную (одну!), в которую будет результат в текстовой форме (не то что возвращает ф-ция) записываться. с ней можно будет работать из командной строки. 2) внедрить простую стековую машину для вычислений с вещественными числами. + Shell 0.4.3 // 20.08.2010 // Albom ======================================= * Смесь версий 0.4.1 и 0.4.2. Теперь в архиве все исходные файлы, необходимые для компиляции (раньше использовались объектники с моими обёртками, исходники я с шеллом не выкладывал) + Shell 0.4.2 // 28.08.2009 // diamond ======================================= * Добавил корректное завершение работы при закрытии окна консоли, работает только начиная с последней на данный момент версией библиотеки (лежит на svn, включена в ночную сборку). Перекомпилировал в VS2008 с LTCG, ещё пошаманил с оптимизацией по размеру. + Shell 0.4.1 // 16.03.2009 // Albom ======================================= * версия с исправленными ошибками. * работает команда alias, добавлена команда clear. + Shell 0.4 // 12.08.2008 // Albom ======================================= 1) Работает схема псевдонимов (до 256 команд) @@ -68,6 +82,7 @@ shell /sys/somescript - просмотр текстовых и бинарных файлов (вроде бы задача простая, но пришлось повозиться с управляющими символами) - очень не рекомендуется просматривать большие файлы + Shell 0.3 // 07.08.2008 // Albom ======================================= 1) Возможность запуска скриптов. @@ -84,20 +99,24 @@ Shell 0.3 // 07.08.2008 // Albom * до 256 (можно изменить при компиляции) синонимов * пока работает только добавление и просмотр синонимов, а отработка пока не реализована. + Shell 0.2 // 04.08.2008 // Albom ======================================= * добавил новые функции * написал собственную процедуру ввода команды + Shell 0.11 // 01.08.2008 // Albom ======================================= * Добавил команды free и reboot, внёс некоторые изменения, исправил найденные ошибки. + Shell 0.1 // 29.07.2008 // Albom ======================================= * Реализованы (не полностью) команды: about, cd, date, echo, exit, help, kill, ls, ps, pwd, ver * При запуске программы (если не указан полный путь) она ищется в каталоге /rd/1 и текущем каталоге. + Shell 0.02 // 27.07.2008 // Albom ======================================= * Реализовал команды: @@ -108,6 +127,7 @@ Shell 0.02 // 27.07.2008 // Albom kill - завершить процесс по PID help (с параметром и без) - помощь + Shell 0.01 // 27.07.2008 // Albom ======================================= * Решил написать функциональный шелл на Си с использованием console.obj. diff --git a/programs/system/shell/all.h b/programs/system/shell/all.h index 880156e236..53a3c96ca5 100644 --- a/programs/system/shell/all.h +++ b/programs/system/shell/all.h @@ -44,6 +44,7 @@ #include "cmd/cmd_killall.c" #include "modules/module_command.c" +#include "modules/module_program_console.c" #include "modules/module_program.c" #include "modules/module_script.c" #include "modules/module_executable.c" diff --git a/programs/system/shell/cmd/cmd_ps.c b/programs/system/shell/cmd/cmd_ps.c index a35cd997e6..18fbf9af5b 100644 --- a/programs/system/shell/cmd/cmd_ps.c +++ b/programs/system/shell/cmd/cmd_ps.c @@ -5,8 +5,6 @@ int cmd_ps(char param[]) int i, n; char *buf1k; unsigned PID; -unsigned *p; -short *s; short STATE; buf1k = malloc(1024); @@ -16,10 +14,8 @@ if (NULL == buf1k) for (i = 1;;i++) { n = kol_process_info(i, buf1k); - p = buf1k+30; - PID = *p; - s = buf1k+50; - STATE = *s; + PID = *(buf1k+30); + STATE = *(buf1k+50); if ( 9 != STATE) printf (" %7d %s\n\r", PID, buf1k+10); if (i == n) diff --git a/programs/system/shell/compile_rus.bat b/programs/system/shell/compile_rus.bat index cf5caa6cbe..d6105bad05 100644 --- a/programs/system/shell/compile_rus.bat +++ b/programs/system/shell/compile_rus.bat @@ -9,7 +9,7 @@ gcc -c system/string.c gcc -c system/ctype.c ld -nostdlib -T kolibri.ld -o shell start.o kolibri.o stdlib.o string.o ctype.o shell.o objcopy shell -O binary -erase lang.h start.o shell.o kolibri.o stdlib.o string.o +erase lang.h start.o shell.o kolibri.o stdlib.o string.o ctype.o kpack shell move shell bin\rus\ copy locale\rus\.shell bin\rus\ diff --git a/programs/system/shell/compile_test.bat b/programs/system/shell/compile_test.bat new file mode 100644 index 0000000000..09a6191913 --- /dev/null +++ b/programs/system/shell/compile_test.bat @@ -0,0 +1,14 @@ +@echo off +fasm start.asm start.o +gcc -c test.c +gcc -c system/kolibri.c +gcc -c system/stdlib.c +gcc -c system/string.c +gcc -c system/ctype.c +ld -nostdlib -T kolibri.ld -o test start.o kolibri.o stdlib.o string.o ctype.o test.o +objcopy test -O binary +erase start.o kolibri.o stdlib.o string.o ctype.o test.o +kpack test +copy test bin\eng\ +move test bin\rus\ +pause \ No newline at end of file diff --git a/programs/system/shell/globals.h b/programs/system/shell/globals.h index 23160f3d59..c405d85f11 100644 --- a/programs/system/shell/globals.h +++ b/programs/system/shell/globals.h @@ -1,5 +1,5 @@ -#define SHELL_VERSION "0.4.91" +#define SHELL_VERSION "0.5" extern char PATH[256]; extern char PARAM[256]; diff --git a/programs/system/shell/modules/module_executable.c b/programs/system/shell/modules/module_executable.c index f39b563075..ed92869038 100644 --- a/programs/system/shell/modules/module_executable.c +++ b/programs/system/shell/modules/module_executable.c @@ -49,11 +49,15 @@ if ( script_check(exec) ) result = program_run(exec, args); if (result > 0) { - #if LANG_ENG - printf (" '%s' started. PID = %d\n\r", cmd, result); - #elif LANG_RUS - printf (" '%s' § Їг饭. PID = %d\n\r", cmd, result); - #endif + + if ( !program_console(result) ) + { + #if LANG_ENG + printf (" '%s' started. PID = %d\n\r", cmd, result); + #elif LANG_RUS + printf (" '%s' § Їг饭. PID = %d\n\r", cmd, result); + #endif + } return TRUE; } else diff --git a/programs/system/shell/modules/module_program_console.c b/programs/system/shell/modules/module_program_console.c new file mode 100644 index 0000000000..e0ca4dd363 --- /dev/null +++ b/programs/system/shell/modules/module_program_console.c @@ -0,0 +1,95 @@ + +#include "../program_console.h" + + +int program_console(int pid) +{ + +char name[32]; +char *buffer; +int result; +int i; +char command; +int size; +int is_end; + +_itoa(pid, name); +strcat(name, "-SHELL"); + +buffer = NULL; + + +for (i = 0; i < 30; i++) + { + result = kol_buffer_open(name, SHM_OPEN | SHM_WRITE, 0, &buffer); + if (buffer != NULL) + break; + + kol_sleep(2); + } + + if (buffer == NULL) + return 0; + else + size = result; + + is_end = 0; + for (;;) + { + + command = *(buffer); + + switch (command) + { + + case SC_EXIT: + *buffer = SC_OK; + is_end = 1; + break; + + case SC_OK: + kol_sleep(5); + break; + + case SC_CLS: + con_cls(); + *buffer = SC_OK; + break; + + case SC_PUTC: + printf("%c", *(buffer+1)); + *buffer = SC_OK; + break; + + case SC_PUTS: + printf("%s", buffer+1 ); + *buffer = SC_OK; + break; + + case SC_GETC: + *(buffer+1) = (char) getch() ; + *buffer = SC_OK; + break; + + case SC_GETS: + gets(buffer+1, size-2); + *buffer = SC_OK; + break; + + default: + #if LANG_ENG + printf (" Error in console application.\n\r"); + #elif LANG_RUS + printf (" Ошибка в консольном приложении.\n\r"); + #endif + return 0; + }; + if (is_end) + { + printf("\n\r"); + return 1; + } + } + +return 9; +} \ No newline at end of file diff --git a/programs/system/shell/program_console.h b/programs/system/shell/program_console.h new file mode 100644 index 0000000000..84973855a8 --- /dev/null +++ b/programs/system/shell/program_console.h @@ -0,0 +1,8 @@ + +#define SC_OK 0 +#define SC_EXIT 1 +#define SC_PUTC 2 +#define SC_PUTS 3 +#define SC_GETC 4 +#define SC_GETS 5 +#define SC_CLS 6 diff --git a/programs/system/shell/system/kolibri.c b/programs/system/shell/system/kolibri.c index 53b61d357b..c77835e960 100644 --- a/programs/system/shell/system/kolibri.c +++ b/programs/system/shell/system/kolibri.c @@ -215,14 +215,13 @@ while (*(s+i)) void kol_board_puti(int n) { char c; -int i = 0; -do - { - c = n % 10 + '0'; - asm ("int $0x40"::"a"(63), "b"(1), "c"(c)); - i++; - } - while ((n /= 10) > 0); + +if ( n > 1 ) + kol_board_puti(n / 10); + +c = n % 10 + '0'; +asm ("int $0x40"::"a"(63), "b"(1), "c"(c)); + } @@ -419,4 +418,17 @@ asm ("int $0x40"::"a"(18), "b"(2), "c"(process)); void kol_get_kernel_ver(char buff16b[]) { asm ("int $0x40"::"a"(18), "b"(13), "c"(buff16b)); -} \ No newline at end of file +} + +int kol_buffer_open(char name[], int mode, int size, char **buf) +{ +int error; +asm ("movl %0, %%esi"::"r"(mode)); +asm ("int $0x40":"=a"(*buf), "=d"(error):"a"(68), "b"(22), "c"(name), "d"(size)); +return error; +} + +void kol_buffer_close(char name[]) +{ +asm ("int $0x40"::"a"(68), "b"(23), "c"(name)); +} diff --git a/programs/system/shell/system/kolibri.h b/programs/system/shell/system/kolibri.h index 284a3934dd..d9595a2bc7 100644 --- a/programs/system/shell/system/kolibri.h +++ b/programs/system/shell/system/kolibri.h @@ -1,6 +1,18 @@ #define NULL ((void*)0) +#define SHM_OPEN 0 +#define SHM_OPEN_ALWAYS 0x04 +#define SHM_CREATE 0x08 +#define SHM_READ 0x00 +#define SHM_WRITE 0x01 + +#define E_NOTFOUND 5 +#define E_ACCESS 10 +#define E_NOMEM 30 +#define E_PARAM 33 + + typedef struct { unsigned p00 __attribute__((packed)); @@ -89,4 +101,6 @@ unsigned kol_sound_speaker(char data[]); unsigned kol_process_info(unsigned slot, char buf1k[]); int kol_process_kill_pid(unsigned process); void kol_get_kernel_ver(char buff16b[]); -int kol_kill_process(unsigned process); \ No newline at end of file +int kol_kill_process(unsigned process); +int kol_buffer_open(char name[], int mode, int size, char **buf); +void kol_buffer_close(char name[]); diff --git a/programs/system/shell/system/string.c b/programs/system/shell/system/string.c index 145b47686c..79ccd3d8fd 100644 --- a/programs/system/shell/system/string.c +++ b/programs/system/shell/system/string.c @@ -122,3 +122,19 @@ char* strchr(const char* string, int c) return (char*)0; } + + +void _itoa(int i, char *s) +{ +int a, b, c, d; +a = (i - i%1000)/1000; +b = (i - i%100)/100 - a*10; +c = (i - i%10)/10 - a*100 - b*10; +d = i%10; +s[0] = a + '0'; +s[1] = b + '0'; +s[2] = c + '0'; +s[3] = d + '0'; +s[4] = 0; +} + diff --git a/programs/system/shell/system/string.h b/programs/system/shell/system/string.h index 1ce28e29e9..9f471524df 100644 --- a/programs/system/shell/system/string.h +++ b/programs/system/shell/system/string.h @@ -13,3 +13,4 @@ void strcpy(char strDest[], const char strSource[]); char* strncpy(char *strDest, const char *strSource, unsigned n); int strlen(const char* string); char *strchr(const char* string, int c); +void _itoa(int i, char *s); diff --git a/programs/system/shell/test.c b/programs/system/shell/test.c new file mode 100644 index 0000000000..0f19c68b57 --- /dev/null +++ b/programs/system/shell/test.c @@ -0,0 +1,109 @@ + +#include "system/kolibri.h" +#include "system/string.h" + +#include "program_console.h" + +char *buffer; // используется только одна именованная область, поэтому можно сделать её глобальной переменной +char name[32]; // имя нужно как для создания области, так и для удаления, поэтому можно сделать её глобальной переменной + +int sc_init() // инициализация - создание именованной области +{ + +char *buf1k; +unsigned PID; +int result; + + +buf1k = malloc(1024); +if (NULL == buf1k) + return -1; + +kol_process_info(-1, buf1k); // получаем СВОЙ (-1) идентификатор процесса +PID = *(buf1k+30); +free(buf1k); + +_itoa(PID, name); // формируем из номера процесса строку с заглавными нулями 42 -> 0042 (т.е. до 9999) +strcat(name, "-SHELL"); + +*buffer = NULL; +result = kol_buffer_open(name, SHM_OPEN_ALWAYS | SHM_WRITE, 1024*16, &buffer); // создаём область (16 кил) + +return result; +} + + + +void sc_puts(char *str) +{ +*buffer = SC_PUTS; +strcpy(buffer+1, str); +while (*buffer) kol_sleep(5); +} + + +void sc_exit() +{ +*buffer = SC_EXIT; +while (*buffer) kol_sleep(5); +kol_buffer_close(name); +} + + +void sc_gets(char *str) +{ +*buffer = SC_GETS; +while (*buffer) kol_sleep(5); +strcpy(str, buffer+1); +} + + +char sc_getc() +{ +*buffer = SC_GETC; +while (*buffer) kol_sleep(5); +return *(buffer+1); +} + + +void sc_putc(char c) +{ +*buffer = SC_PUTC; +*(buffer+1) = c; +while (*buffer) kol_sleep(5); +} + + + +void sc_cls() +{ +*buffer = SC_CLS; +while (*buffer) kol_sleep(5); +} + + + + +void kol_main() +{ + +char string[256]; + +sc_init(); + +sc_cls(); +sc_puts("This is a test console application for Shell\n\r"); +sc_puts("Type a string (255 symbols max): "); +sc_gets(string); +sc_puts("You typed:\n\r"); +sc_puts(string); +sc_puts("Press any key: "); +string[0] = sc_getc(); +sc_puts("\n\rYou pressed: "); +sc_putc(string[0]); + +sc_exit(); + + + +}