Board.KolibriOS.org

Official KolibriOS board
It is currently Thu Jul 18, 2019 4:24 pm

All times are UTC+03:00




Post new topic  Reply to topic  [ 226 posts ]  Go to page Previous 112 13 14 15 16 Next
Author Message
 Post subject: Re: Newlib
PostPosted: Fri Mar 11, 2016 2:41 pm 
Offline

Joined: Tue Mar 08, 2016 11:00 pm
Posts: 436
1. Ошибочка в файловом в/в

При записи на tmp0/1 при окончании места на диске, код ошибки не возвращается
Spoiler: Show
Code:
void create_file(const char* filename, int size) {
   FILE* file = fopen(filename, "rb");
   if (file != NULL) {
      // Файл уже есть
      printf("Use file %s\n", filename);
      fclose(file);
      return;
   }
   printf("Create file %s size %d ...\n", filename, size);
   file = fopen(filename, "wb");
   int rc = 0;
   if (file != NULL) {
      for (int i = 0; i < size; i++) {
         rc = fprintf(file, "%d\n", rand());
         if (rc < 0) perror("Error:");
      }
      rc = fclose(file);
      if (rc) perror("Error:");
   }
   else
     perror("Error:");

   printf("errno on exit=%d", errno);
}


Серг пофиксил. Кроме того см. примечание по gcc и stderr viewtopic.php?p=64691#p64691


2. clock() не работает
можно заменить на
Code:
#include "kos32sys.h"
#define CLOCKS_PER_SEC (100)
uint32_t clock1()
{
   return get_tick_count();
}


Top
   
 Post subject: Re: Newlib
PostPosted: Tue Apr 05, 2016 3:38 pm 
Offline

Joined: Tue Apr 12, 2011 11:19 pm
Posts: 1150
Правильно ли я понимаю, что строковые функции из newlib не работают с ассемблерными строками? Т.е. я немогу скопировать путь возвращаемый OpenDialog например, и для этого придется писать свой вариант функции? Или же это все таки ошибка в реализации функции?

_________________
я лишь учусь


Top
   
 Post subject: Re: Newlib
PostPosted: Wed Apr 06, 2016 10:03 pm 
Offline
Mentor
User avatar

Joined: Tue Jan 15, 2008 11:27 am
Posts: 752
Судя по исходникам rtfread (файл rtfread.asm, строки 116-124, 848-855), OpenDialog возвращает имя файла в виде ASCIIZ - т.е. с завершающим нулевым символом. Т.е. функции стандартной библиотеки Си для работы со строками должны результат обработать. Код newlib смотрел давно, но не верится, что там ошибка. Скорее всего что-то не так в коде "прослойки Си-ассемблер" (возможно, в выравнивании полей структуры OpenDialog).


Top
   
 Post subject: Re: Newlib
PostPosted: Thu Apr 07, 2016 7:59 am 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
punk_joker
C opendial должны работать. Посмотри http://websvn.kolibrios.org/filedetails ... endial.asm


Top
   
 Post subject: Re: Newlib
PostPosted: Thu Jun 09, 2016 10:01 pm 
Offline
User avatar

Joined: Mon Nov 19, 2012 5:22 pm
Posts: 455
Ситуация такая. Код CMM, запуская, прога отрабатывает, корректно завершается, но остаётся висеть один процесс cmm. Причём грузит проц на 100%. Вычислил, что такое происходит, если вызвать fopen-fclose. Причём даже просто писал в main:
Spoiler: Show
FILE* inih = fopen("/rd/1/settings/c--.ini","rb");
fclose(inih);
return 0;

При этом, я пишу такой код в Hello, и всё как положено работает. Но в CMM обязательно зависнет какой-то поток, если был вызов fopen. Не представляю, в какую сторону искать.

_________________
Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!


Top
   
 Post subject: Re: Newlib
PostPosted: Tue Nov 15, 2016 11:23 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Сделал конверсию из UTF16 в однобайтные кодировки. Для русского языка
Code:
int main(int argc, char *argv[])
{
    setlocale(LC_CTYPE,"C.CP866");
    wprintf(L"%S",L"Привет, Мир!\n");
    return 0;
}
Поддерживаются CP437, CP720, CP737, CP775, CP850, CP852, CP855, CP857, CP858, CP862, CP866, CP874, CP1125, CP1250, CP1251, CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, CP1258,
CP20866, CP21866, CP101 (GEORGIAN-PS), CP102 (PT154 Kazakhstan)
Spoiler: Show
Attachment:
1.png
1.png [ 63.09 KiB | Viewed 3027 times ]


Top
   
 Post subject: Re: Newlib
PostPosted: Mon Feb 06, 2017 7:48 pm 
Offline

Joined: Thu Mar 31, 2016 10:18 am
Posts: 11
Serge, хотелось бы нормальной работы функции stat, для аргументов ".","/fd2/1","/hd0/1","/sys" и т.д.
Вроде как в некоторых случаях эта функция возвращает -1 .
Я написал свою реализацию lstat, которая исправляет эти нюансы, но опирается на вашу реализацию stat( из dll-ки ). Можно еще сделать заполнения полей st_dev, st_ino, хотя бы случайными значениями, можно st_ino заполнять хэш суммой канонического имени файла в нижнем регистре. А то моя сборка busybox глючит. Я приведу код, будет понятно почему из-за незаполненого st_ino возникает ошибка :
Code:
  
   /* It is a bad idea to store the archive we are in the process of creating,
    * so check the device and inode to be sure that this particular file isn't
    * the new tarball */
   if (tbInfo->statBuf.st_dev == statbuf->st_dev &&
         tbInfo->statBuf.st_ino == statbuf->st_ino) {
      error_msg("%s: file is the archive; skipping", fileName);
      return( TRUE);
   }

Получается совпадения s_ino для записываемого архива tar и помещаемого в него файла.
Еще есть предложения по crt, сделать скрытые параметры, которые не доходят до main, но обрабатываются при запуске приложения. Например, --stdout-to=<file>, --stdin-from=<file>, --stderr-to=<file>. Для перенаправления стандартных потоков в файлы.
Еще хотелось бы реализации функции pipe, dup2, еще бы и fork.
И функции типа (что бы была видна из dll) :
__io_handle* get_global_io_table(){
return __io_tab;
}
Чтобы можно было не меняя dll-ки перенаправить стандартные потоки в виртуальные файлы.


Top
   
 Post subject: Re: Newlib
PostPosted: Mon Feb 06, 2017 8:46 pm 
Offline

Joined: Tue Mar 08, 2016 11:00 pm
Posts: 436
inode есть не у всех файловых систем, мягко говоря.

И функции KOS не возвращают ничего подобного.

Приведенное выражение похоже на проверку симлинка


Top
   
 Post subject: Re: Newlib
PostPosted: Mon Feb 06, 2017 9:53 pm 
Offline

Joined: Thu Mar 31, 2016 10:18 am
Posts: 11
Это код из busybox (tar.c), о котором я говорю приводит к ошибке в моей сборке. Если libc stat не заполняет st_ino, то там может быть все что угодно, включая 0. При совпадении dev и inode программа падает с ошибкой, говоря что помещаемый в архив файл сам является создаваемым архивом, в который этот файл пемещается.


Top
   
 Post subject: Re: Newlib
PostPosted: Tue Feb 07, 2017 4:05 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
netryx

st_ino должна быть уникальна для каждого файла ? Туда можно писать указатель на структуру с данными файла.

Update.

Посмотрел stat(), лучше хеш писать.


Top
   
 Post subject: Re: Newlib
PostPosted: Fri Feb 17, 2017 11:17 am 
Offline

Joined: Thu Mar 31, 2016 10:18 am
Posts: 11
Serge,
Да, st_ino должен быть уникальным для каждого уникального файла (при одном и том же st_dev).
Да ладно. Тот нюанс можно вручную профиксить.

Гораздо больше проблем создает другой нюанс stat:
Не работает stat:
stat .
stat /fd2/1
stat /rd/1
stat /hd0/1
stat /tmp0/1
stat /cd2/1
stat /sys
stat /fd2

Из-за этого может не работать:
busybox ls
busybox mkdir с ключом -p
Распаковщик tar не может создать иерархию каталогов, потому что stat с первым компонентом пути (типа "/tmp0") возвращает -1.

Это может быть от странного поведения функции 70.5 (stat вроде как на нее опирается) : Функция не поддерживает виртуальные папки типа /, /rd и корневые папки типа /rd/1
Я думал что это профиксили в ядре (у меня старая документация), но видимо ошибся.

Удивительно, но работает stat /kolibrios


Пример для тестирования stat:
Code:
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>

int main(int argc,char** argv)

{
   struct stat buf;
   int ret;
   const char* arg=".";
   if (argc<=1){
      printf("\nUsage:\nstat <filename>\n");
      //return 0;
   }else
      arg=argv[1];
   if ((ret=stat(arg,&buf))==0){
      printf("\nOK stat !file=%s,\nmode:0x%x\n" ,arg,(int)buf.st_mode);
      printf("\nst_dev:0x%x" ,(int)buf.st_dev);
      printf("\nst_ino:0x%x" ,(int)buf.st_ino);
      printf("\nst_nlink:0x%x" ,(int)buf.st_nlink);
      printf("\nst_uid:0x%x" ,(int)buf.st_uid);
      printf("\nst_gid:0x%x" ,(int)buf.st_gid);
      printf("\nst_rdev:0x%x" ,(int)buf.st_rdev);
      printf("\nst_size:0x%x" ,(int)buf.st_size);
      
   }else{
      printf("\nFailed,ret=%i\n ",ret);
   }
   return ret;
}

У меня есть небольшая наработка кода, не совсем полностью устраняющая этот нюанс, могу показать (реализация lstat, которая просто парсит переданный в функцию путь, если соответствует определенному шаблону, то возвращает, что это директория, иначе возвращает значение stat из под newlib).


Top
   
 Post subject: Re: Newlib
PostPosted: Fri Feb 17, 2017 12:45 pm 
Offline
Mentor/Kernel Developer
User avatar

Joined: Thu Mar 26, 2015 5:16 pm
Posts: 1262
Как раз сейчас чиню это для FAT. Для NTFS уже должно работать.


Top
   
 Post subject: Re: Newlib
PostPosted: Fri Feb 17, 2017 1:43 pm 
Offline

Joined: Tue Mar 08, 2016 11:00 pm
Posts: 436
Pathoswithin wrote:
Как раз сейчас чиню это для FAT. Для NTFS уже должно работать.
Раз чинишь, глянь, может аттрибуты расширить по подобию stat ?
http://man7.org/linux/man-pages/man2/stat.2.html
Quote:
S_IFMT 0170000 bit mask for the file type bit field

S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO

симлинки имеются в NTFS и ext
/hd0/1 - блокдевайс
- а что stat возвращает в линухе для /, /dev, /dev/sda0 ?


Top
   
 Post subject: Re: Newlib
PostPosted: Fri Feb 17, 2017 6:31 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
netryx
Quote:
Удивительно, но работает stat /kolibrios
под /kolibrios монтируется настоящий каталог. В ядре путь разворачивается в реальный, поэтому stat работает.
Quote:
У меня есть небольшая наработка кода, не совсем полностью устраняющая этот нюанс, могу показать (реализация lstat, которая просто парсит переданный в функцию путь, если соответствует определенному шаблону, то возвращает, что это директория, иначе возвращает значение stat из под newlib).
Это будет замечательно. Выкладывай здесь.


Top
   
 Post subject: Re: Newlib
PostPosted: Fri Feb 17, 2017 7:30 pm 
Offline

Joined: Thu Mar 31, 2016 10:18 am
Posts: 11
Serge,
Code:
static void set_rdir(struct stat * buf){
      buf->st_mode=(S_IFDIR| S_IRWXU);
      buf->st_ino=(unsigned)rand();
      buf->st_dev=(unsigned)rand();
      buf->st_size=0;
}

static char* expect_num_in_path(char* path,int* is_num){
   char* s,c;
   
   *is_num=0;
   c=0;
   s=path;
   while(*s){
      c=*s;
      s++;
      if (c>='0' && c<='9'){
            *is_num=1;
         }else{
            if (c=='/'){
               if (*is_num)
                  *is_num='/';
               break;
            }else{
               is_num=0;
               break;
               
            }
            
         }
   }
   return s;
   
}
int kolibri_fix_stat(const char * path, struct stat * buf){
   char temp[264];
   char* s;
   char* end_s;
   int i,le;
   int is_int;
   char c;
   
   if (strcmp(path,".")==0 || strcmp(path,"./")==0)
   {
      set_rdir(buf);
      return 0;
   }
   if (*path!='/'){
      if (NULL==realpath(path,temp)){
         return -1;
      }
   }else{
      strcpy(temp,path);
   }
   
   le=strlen(temp);
   if (le<=0) {
      return -1;
   }
   
   end_s=temp+(le-1);
   if (*end_s=='\\' || *end_s=='/'){
      temp[le-1]=0;
      le--;
      
   }
   if (le<=0) {
      return -1;
   }
   for (i=0;i<le;i++){
      temp[i]=tolower(temp[i]);
   }
   
   if (
      strncmp(temp,"/hd",3)==0 ||
      strncmp(temp,"/rd",3)==0  ||
      strncmp(temp,"/fd",3)==0 ||
      strncmp(temp,"/cd",3)==0 ||
      strncmp(temp,"/tmp",4)==0
      )
   {
      s=temp+3;
      if (  strncmp(temp,"/rd",3)==0  ){
         if (temp[3]==0){
            set_rdir(buf);
            return 0;   
         }
         if (temp[3]=='/' )
            s++;
      }else{
         if ( //temp[4]=='/' &&
            strncmp(temp,"/tmp",4)==0  ){
            s++;
         }
      }
      s=expect_num_in_path(s,&is_int);
      
      if (is_int ){
         if (*s==0 )
         {
            set_rdir(buf);
            return 0;
         }
         if (is_int=='/'){
            s=expect_num_in_path(s,&is_int);
            if (*s==0 && is_int){
               set_rdir(buf);
               return 0;
            }
         }
      }
      //not found path liked "/hd0/1"
      //
      return -1;
   }
   if (
      strcmp(temp,"/")==0 ||
      strcmp(temp,"/sys")==0 ||
      strcmp(temp,"/kolibrios")==0
      )
   {
      set_rdir(buf);
      return 0;
   }
   return -1;
   
}

int lstat(const char * path, struct stat * buf){
   int ret;
   //unimplemented_func_message("lstat");
   ret=kolibri_fix_stat(path,buf);
   if (ret==0) return ret;
   
   ret= stat(path,buf);
   #if 1
   if (ret==0){
      //fix EQUAL INO BUG
      buf->st_ino=(unsigned)rand();
   }
   #endif
   return ret;
}


Attachments:
realpath.c [2.45 KiB]
Downloaded 85 times
Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 226 posts ]  Go to page Previous 112 13 14 15 16 Next

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited