Newlib

Discussing libraries simplifying applications development
  • Правильно ли я понимаю, что строковые функции из newlib не работают с ассемблерными строками? Т.е. я немогу скопировать путь возвращаемый OpenDialog например, и для этого придется писать свой вариант функции? Или же это все таки ошибка в реализации функции?
    to infinity and beyond
  • Судя по исходникам rtfread (файл rtfread.asm, строки 116-124, 848-855), OpenDialog возвращает имя файла в виде ASCIIZ - т.е. с завершающим нулевым символом. Т.е. функции стандартной библиотеки Си для работы со строками должны результат обработать. Код newlib смотрел давно, но не верится, что там ошибка. Скорее всего что-то не так в коде "прослойки Си-ассемблер" (возможно, в выравнивании полей структуры OpenDialog).
  • punk_joker
    C opendial должны работать. Посмотри http://websvn.kolibrios.org/filedetails ... endial.asm
  • Ситуация такая. Код CMM, запуская, прога отрабатывает, корректно завершается, но остаётся висеть один процесс cmm. Причём грузит проц на 100%. Вычислил, что такое происходит, если вызвать fopen-fclose. Причём даже просто писал в main:
    Spoiler:FILE* inih = fopen("/rd/1/settings/c--.ini","rb");
    fclose(inih);
    return 0;
    При этом, я пишу такой код в Hello, и всё как положено работает. Но в CMM обязательно зависнет какой-то поток, если был вызов fopen. Не представляю, в какую сторону искать.
    Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
  • Сделал конверсию из UTF16 в однобайтные кодировки. Для русского языка

    Code: Select all

    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:
    1.png
    1.png (63.09 KiB)
    Viewed 11109 times
  • Serge, хотелось бы нормальной работы функции stat, для аргументов ".","/fd2/1","/hd0/1","/sys" и т.д.
    Вроде как в некоторых случаях эта функция возвращает -1 .
    Я написал свою реализацию lstat, которая исправляет эти нюансы, но опирается на вашу реализацию stat( из dll-ки ). Можно еще сделать заполнения полей st_dev, st_ino, хотя бы случайными значениями, можно st_ino заполнять хэш суммой канонического имени файла в нижнем регистре. А то моя сборка busybox глючит. Я приведу код, будет понятно почему из-за незаполненого st_ino возникает ошибка :

    Code: Select all

      
    	/* 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-ки перенаправить стандартные потоки в виртуальные файлы.
  • inode есть не у всех файловых систем, мягко говоря.

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

    Приведенное выражение похоже на проверку симлинка
  • Это код из busybox (tar.c), о котором я говорю приводит к ошибке в моей сборке. Если libc stat не заполняет st_ino, то там может быть все что угодно, включая 0. При совпадении dev и inode программа падает с ошибкой, говоря что помещаемый в архив файл сам является создаваемым архивом, в который этот файл пемещается.
  • netryx

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

    Update.

    Посмотрел stat(), лучше хеш писать.
  • 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: Select all

    #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).
  • Как раз сейчас чиню это для FAT. Для NTFS уже должно работать.
  • Pathoswithin wrote:Как раз сейчас чиню это для FAT. Для NTFS уже должно работать.
    Раз чинишь, глянь, может аттрибуты расширить по подобию stat ?
    http://man7.org/linux/man-pages/man2/stat.2.html
    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 ?
  • netryx
    Удивительно, но работает stat /kolibrios
    под /kolibrios монтируется настоящий каталог. В ядре путь разворачивается в реальный, поэтому stat работает.
    У меня есть небольшая наработка кода, не совсем полностью устраняющая этот нюанс, могу показать (реализация lstat, которая просто парсит переданный в функцию путь, если соответствует определенному шаблону, то возвращает, что это директория, иначе возвращает значение stat из под newlib).
    Это будет замечательно. Выкладывай здесь.
  • Serge,

    Code: Select all

    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 302 times
  • Who is online

    Users browsing this forum: Yandex [Bot] and 1 guest