From 4e239759708481bb9c9b6e5540fc04e86b2b6ce5 Mon Sep 17 00:00:00 2001 From: siemargl Date: Mon, 6 Feb 2017 12:35:58 +0000 Subject: [PATCH] better cp, 64-bit fileops git-svn-id: svn://kolibrios.org@6857 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/system/shell/History.txt | 5 + programs/system/shell/cmd/cmd_cp.c | 127 +++++++----------- programs/system/shell/cmd/cmd_ls.c | 18 ++- programs/system/shell/cmd/cmd_mkdir.c | 2 +- programs/system/shell/cmd/cmd_more.c | 10 +- programs/system/shell/cmd/cmd_rm.c | 2 +- programs/system/shell/cmd/cmd_rmdir.c | 2 +- programs/system/shell/cmd/cmd_touch.c | 2 +- programs/system/shell/globals.h | 2 +- .../system/shell/modules/module_command.c | 2 +- .../system/shell/modules/module_program.c | 3 +- programs/system/shell/modules/module_script.c | 15 ++- programs/system/shell/prototypes.h | 2 +- programs/system/shell/shell.c | 11 +- programs/system/shell/system/kolibri.h | 5 +- programs/system/shell/system/stdlib.c | 2 +- programs/system/shell/system/string.c | 1 + 17 files changed, 107 insertions(+), 104 deletions(-) diff --git a/programs/system/shell/History.txt b/programs/system/shell/History.txt index 507651c77d..3454eac2d6 100644 --- a/programs/system/shell/History.txt +++ b/programs/system/shell/History.txt @@ -1,3 +1,8 @@ +Shell 0.7.6 // 06.02.2017 // Siemargl +* Файловые операции используют 64-bit размеры файлов. + cp теперь понимает, если - каталог + cp использует буфер 1Мб, или не более половины свободной памяти + Shell 0.7.5 // 06.01.2017 // Siemargl * Мелкие багфиксы, изменена логика обработки стрелок вверх/вниз, чтобы как у всех Добавлена команда waitfor и вариант ps с параметром diff --git a/programs/system/shell/cmd/cmd_cp.c b/programs/system/shell/cmd/cmd_cp.c index 3e6d896698..da8e1206ef 100644 --- a/programs/system/shell/cmd/cmd_cp.c +++ b/programs/system/shell/cmd/cmd_cp.c @@ -3,19 +3,18 @@ int cmd_cp(char param[]) { char* argv[100]; -int i; int argc; -char *filename_in; -char *filename_out; -char *buffer; +char *filename_in = NULL; +char *filename_out = NULL; +char *buffer = NULL; kol_struct70 k70_in; kol_struct70 k70_out; kol_struct_BDVK bdvk; -unsigned filesize, result; -unsigned n; // количество раз копирования по 4 кбайта +unsigned long long filesize; +unsigned result, buf_size; argc = parameters_prepare(param, argv); @@ -58,110 +57,88 @@ if (argv[1][0] != '/') { strcpy(filename_out, argv[1]); } + +// add ability to use directory as destination +if ( dir_check(filename_out) ) + { + char *fname = strrchr(filename_in, '/') + 1; // always exist, as we add curdir + if (filename_out[strlen(filename_out)-1] != '/') + strcat(filename_out, "/"); // add slash + strcat(filename_out, fname); + } k70_in.p00 = 5; -k70_in.p04 = k70_in.p08 = k70_in.p12 = 0; +k70_in.p04 = 0LL; +k70_in.p12 = 0; k70_in.p16 = (unsigned) &bdvk; k70_in.p20 = 0; k70_in.p21 = filename_in; result = kol_file_70(&k70_in); // получаем информацию о файле if ( 0 != result ) - { - parameters_free(argc, argv); - free(filename_in); - free(filename_out); - return TRUE; - } + goto lbl_exit; -filesize = bdvk.p32[0]; // получаем размер файла (ограничение - 4 Гбайта) -n = filesize / 4096; +// count buffer size up to 1Mb, but no more than 1/2 of free memory +buf_size = 1 << 20; // 1Mb +while( ((buf_size >> 10) > kol_system_memfree()) && (buf_size > 4096) ) + buf_size /= 2; -buffer = (char*) malloc(4096); +filesize = bdvk.p32; // получаем размер файла(ограничение - 4 Гбайта только для FAT) +if (buf_size > filesize) + buf_size = (unsigned)filesize; // may be zero! +if (buf_size == 0) buf_size = 4096; // ... + +buffer = (char*) malloc(buf_size); +if (!buffer) + { + result = E_NOMEM; + goto lbl_exit; + } k70_in.p00 = 0; -k70_in.p08 = 0; -k70_in.p12 = 4096; +//k70_in.p08 = 0; +k70_in.p12 = buf_size; k70_in.p16 = (unsigned) buffer; k70_in.p20 = 0; k70_in.p21 = filename_in; k70_out.p00 = 2; -k70_out.p08 = 0; -k70_out.p12 = 4096; +//k70_out.p08 = 0; +k70_out.p12 = buf_size; k70_out.p16 = (unsigned) buffer; k70_out.p20 = 0; k70_out.p21 = filename_out; -i = 0; // для того, чтобы копировать файлы с размером меньше 4 кБайт -for ( i = 0; i < n; i++) - { - - k70_in.p04 = i*4096; +unsigned long long offset = 0; +do { + k70_in.p04 = offset; + if (offset + buf_size > filesize) // last chunk + { + k70_in.p12 = k70_out.p12 = (unsigned)(filesize - offset); // filesize % buf_size; + } + result = kol_file_70(&k70_in); // чтение if (result != 0) - { - parameters_free(argc, argv); - free(filename_in); - free(filename_out); - free(buffer); - return FALSE; - } + goto lbl_exit; - k70_out.p04 = i*4096; + k70_out.p04 = offset; result = kol_file_70(&k70_out); // запись if (result != 0) - { - parameters_free(argc, argv); - free(filename_in); - free(filename_out); - free(buffer); - return FALSE; - } + goto lbl_exit; - if (i == 0) + if (k70_out.p00 == 2) k70_out.p00 = 3; // меняем функцию с создания (2) на дозапись (3) + offset += buf_size; +} while (offset < filesize); - } - -if ( (filesize%4096) != 0 ) // если размер файла не кратен 4 кБайтам - { - - k70_in.p12 = filesize%4096; - k70_out.p12 = filesize%4096; - - k70_in.p04 = i*4096; // в i должно быть правильное смещение - result = kol_file_70(&k70_in); // чтение - if (result != 0) - { - parameters_free(argc, argv); - free(filename_in); - free(filename_out); - free(buffer); - return FALSE; - } - - k70_out.p04 = i*4096; - result = kol_file_70(&k70_out); // запись - if (result != 0) - { - parameters_free(argc, argv); - free(filename_in); - free(filename_out); - free(buffer); - return FALSE; - } - - } - +lbl_exit: parameters_free(argc, argv); free(filename_in); free(filename_out); free(buffer); - -return TRUE; +return (result == 0); } diff --git a/programs/system/shell/cmd/cmd_ls.c b/programs/system/shell/cmd/cmd_ls.c index 599a0dbff5..18de3b3dac 100644 --- a/programs/system/shell/cmd/cmd_ls.c +++ b/programs/system/shell/cmd/cmd_ls.c @@ -12,8 +12,8 @@ int i, result; k70.p00 = 1; k70.p04 = 0; -k70.p08 = 0; -k70.p12 = 10000; +//k70.p08 = 0; +k70.p12 = 2; // just for test exist & read number of entries k70.p16 = (unsigned) malloc(32+k70.p12*560); k70.p20 = 0; @@ -34,6 +34,20 @@ if ( !((result==0) || (result==6)) ) // n = (unsigned*) (k70.p16+8); num_of_file = *n; // число файлов в каталоге +// now read full directory +k70.p12 = num_of_file; +free( (void*) k70.p16); +k70.p16 = (unsigned) malloc(32+k70.p12*560); +if ( !k70.p16 ) + return FALSE; + +result = kol_file_70(&k70); +if ( !((result==0) || (result==6)) ) + { + free( (void*) k70.p16); + return FALSE; + } + for (i = 0; i < num_of_file; i++) { printf (" %s", k70.p16+32+40+(264+40)*i); diff --git a/programs/system/shell/cmd/cmd_mkdir.c b/programs/system/shell/cmd/cmd_mkdir.c index 366528e318..676a8aea95 100644 --- a/programs/system/shell/cmd/cmd_mkdir.c +++ b/programs/system/shell/cmd/cmd_mkdir.c @@ -24,7 +24,7 @@ if ( 0 == strcmp(dir, ".") || ( 0 == strcmp(dir, "..") ) || ( 0 == strcmp(cur_di k70.p00 = 9; k70.p04 = 0; -k70.p08 = 0; +//k70.p08 = 0; k70.p12 = 0; k70.p16 = 0; k70.p20 = 0; diff --git a/programs/system/shell/cmd/cmd_more.c b/programs/system/shell/cmd/cmd_more.c index f1cf36d24b..38704e342b 100644 --- a/programs/system/shell/cmd/cmd_more.c +++ b/programs/system/shell/cmd/cmd_more.c @@ -4,7 +4,8 @@ int cmd_more(char file[]) kol_struct70 k70; kol_struct_BDVK bdvk; -unsigned result, filesize, pos, i; +unsigned result, i; +unsigned long long filesize, pos; char buf[81]; //буфер char temp[FILENAME_MAX]; unsigned flags; @@ -44,7 +45,8 @@ else } k70.p00 = 5; -k70.p04 = k70.p08 = k70.p12 = 0; +k70.p04 = k70.p12 = 0; +//k70.p08 = 0; k70.p16 = (unsigned) &bdvk; k70.p20 = 0; k70.p21 = temp; @@ -53,7 +55,7 @@ result = kol_file_70(&k70); // if ( 0 != result ) return FALSE; -filesize = bdvk.p32[0]; // получаем размер файла +filesize = bdvk.p32; // получаем размер файла buf[80]=0; flags = con_get_flags(); @@ -65,7 +67,7 @@ for (pos=0;pos