OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 25 Сентябрь, 2023 08:33

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: Исправления в LinFiles
СообщениеДобавлено: Четверг, 04 Май, 2023 09:07 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1105
нашёл мелкую ошибочку в HostFiles64/Lin: в процедуре `Register()` вместо `Libc.fopen64()` используется `Libc.fopen()`.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Пятница, 05 Май, 2023 12:49 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1105
кстати, HostFiles/Lin можно ещё немножко улучшить. не уверен, что это очень нужно именно сейчас, но с другой стороны — это и не деструктивно. вкрации(ц): в процедуре `Delete()` (она внутренняя, непубличная) использующийся открытый файл можно просто удалять, а не переименовывать во временное имя. в винде так нельзя, а в линуксах удаление открытого файла разрешено, и не убивает файловые дескрипторы.

это позволит избавиться от кучи временных файлов, которые возникают при сохранении документов. потому что среда при сохранении делает так: пишет новый анонимный файл, потом его регистрирует под именем старого; но старый всё ещё открыт. таким образом у нас появляется временный «удалённый» файл, который нужен низачем, и будет удалён по выходу из среды (потому что винда не позволяет удалять открытые файлы, а лин-филес просто калька с виндового). короче, вот так можно:
Код:
   PROCEDURE Delete (IN fname, path: FullName; OUT res: INTEGER);
   VAR
      num, n: INTEGER;
      f: File; new: FullName;
      attr: SET;
      fn, nn: ShortName;
      buf: Libc.stat_t;
      isDir: BOOLEAN;
   BEGIN ASSERT(fname # '', 20);
      f := ThisFile(fname); NameToLocal(fname, fn);
      IF f = NIL THEN
         IF Libc.remove(fn) = 0 THEN res := ok
         ELSE
            res := Libc.fflush(0);
            IF Libc.remove(fn) = 0 THEN res := ok ELSE res := Libc_errno() END
         END
      ELSE (* still in use => make it anonymous *)
         (* k8: we can safely delete it; this will not invalidate file handles;
            one gotcha: the file should be opened; for non-opened-yet files, use the old method *)
         IF f.ref # invalid THEN
            IF Libc.remove(fn) = 0 THEN res := ok
            ELSE
               res := Libc.fflush(0);
               IF Libc.remove(fn) = 0 THEN res := ok ELSE res := Libc_errno() END
            END;
            IF res = ok THEN   (* it is hidden, and has no name anymore *)
               f.state := hidden; f.name := ''
            END;
         ELSE   (* old method *)
            CloseFileHandle(f, ^res);
            Stat(f.name, buf, res);
            ModeToAttr(buf.st_mode, attr, isDir);
            IF (res = ok) & ~(Files.readOnly IN attr) THEN
               num := Libc.clock(); n := 200;
               REPEAT
                  GetTempFileName(path, new, num); INC(num); DEC(n);
                  NameToLocal(new, nn);
                  MoveFile(fn, nn, res);
               UNTIL (res # fileExistsErr) OR (n = 0);
               IF res = ok THEN
                  f.state := hidden; f.name := new$
               END
            ELSE
               res := writeProtectedErr
            END
         END
      END
   END Delete;


также в `CreateFile()` можно использовать стандартную либц-функцию для создания безымянных временных файлов (потому что временные файлы по контракту нельзя регистрировать в файловой системе):
Код:
   PROCEDURE CreateFile (f: File; OUT res: INTEGER);
   VAR num, n: INTEGER;
   BEGIN
      IF f.name = '' THEN
         (* k8: temp files cannot be registered, and need no name *)
         IF f.state = temp THEN
            f.ref := Libc.tmpfile();
            IF f.ref = invalid THEN res := Libc_errno() ELSE res := ok END
         ELSE
            num := Libc.clock(); n := 200;
            REPEAT
               GetTempFileName(f.loc.path, f.name, num); INC(num); DEC(n);
               OpenFile(f, create, f.name, f.ref, res)
            UNTIL (res # fileExistsErr) OR (n = 0)
         END
      ELSE
         OpenFile(f, f.state, f.name, f.ref, res)
      END
   END CreateFile;

это идеологически правильней, нежели создавать файлы с временными именами, потому что `tmpfile()` правильно сделает такие файлы в "/tmp".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Пятница, 05 Май, 2023 12:55 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1105
а, и ещё там же, в HostFiles/Lin: процедуру `ExistingFile()` лучше заменить на такую:
Код:
   PROCEDURE ExistingFile (IN n: ShortName): BOOLEAN;
   BEGIN RETURN (Libc.access(n, Libc.F_OK) = 0)
   END ExistingFile;

в Libc надо докинуть:
Код:
CONST
   F_OK* = 0;
   X_OK* = 1;
   W_OK* = 2;
   R_OK* = 4;

и
Код:
PROCEDURE [ccall] tmpfile* (): PtrFILE;
PROCEDURE [ccall] tmpfile64* (): PtrFILE;
PROCEDURE [ccall] access* (pathname: PtrSTR; mode: int): int;

зачем так? потому что в оригинальном `ExistingFile()` во-первых, без нужды делается `fopen()`, а во-вторых, `fopen()` менее надёжна для проверки существования файла, нежели `access()`. то есть, если файл существует, но его нельзя открыть (права не позволяют), то вариант с `fopen()` скажет, что файла нет, а вариант с `access()` — что есть (как и должно быть, логика требует именно такого поведения).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Понедельник, 08 Май, 2023 10:30 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3731
arisu писал(а):
нашёл мелкую ошибочку в HostFiles64/Lin: в процедуре `Register()` вместо `Libc.fopen64()` используется `Libc.fopen()`.

В общем, тут не требуется исправление, поскольку там открывается пробный файл, в который запись не планируется. В после проверки временный файл перемещается.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Понедельник, 08 Май, 2023 10:36 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3731
arisu писал(а):
также в `CreateFile()` можно использовать стандартную либц-функцию для создания безымянных временных файлов (потому что временные файлы по контракту нельзя регистрировать в файловой системе)
...
это идеологически правильней, нежели создавать файлы с временными именами, потому что `tmpfile()` правильно сделает такие файлы в "/tmp".

Если директория и /tmp на разных дисках, то получится, что в момент сохранения произойдёт копирование с одного диска на другой. Нежелательное поведение. А вот если файл создан именно временный через .Temp, то вот тут было бы логично его складывать в /tmp чтобы не тратить ресурсы SSD, к примеру, если у кого-то временная папка специально выделена в отдельный ресурс. Но тут можно столкнуться с проблемой, что на некоторых VPS, директория для временных файлов очень маленькая. В целом для пользователя могут быть неприятные сюрпризы с этим. А так всё меньше людей берегут ресурсы SSD, они и повыносливее становятся. Ради похожести поведения Windows и Linux версии я бы оставил как есть пока с временными файлами. Мы как-то раз эту тему обсуждали небольшой компанией, и решили эти временные odc оставить. В норме ББ достаточно редко должен падать, чтобы их за собой не чистить.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Понедельник, 08 Май, 2023 11:08 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3731
arisu писал(а):
это позволит избавиться от кучи временных файлов, которые возникают при сохранении документов. потому что среда при сохранении делает так: пишет новый анонимный файл, потом его регистрирует под именем старого; но старый всё ещё открыт. таким образом у нас появляется временный «удалённый» файл, который нужен низачем, и будет удалён по выходу из среды (потому что винда не позволяет удалять открытые файлы, а лин-филес просто калька с виндового). короче, вот так можно:
Код:
   PROCEDURE Delete (IN fname, path: FullName; OUT res: INTEGER);
   VAR
      num, n: INTEGER;
      f: File; new: FullName;
      attr: SET;
      fn, nn: ShortName;
      buf: Libc.stat_t;
      isDir: BOOLEAN;
   BEGIN ASSERT(fname # '', 20);
      f := ThisFile(fname); NameToLocal(fname, fn);
      IF f = NIL THEN
         IF Libc.remove(fn) = 0 THEN res := ok
         ELSE
            res := Libc.fflush(0);
            IF Libc.remove(fn) = 0 THEN res := ok ELSE res := Libc_errno() END
         END
      ELSE (* still in use => make it anonymous *)
         (* k8: we can safely delete it; this will not invalidate file handles;
            one gotcha: the file should be opened; for non-opened-yet files, use the old method *)
         IF f.ref # invalid THEN
            IF Libc.remove(fn) = 0 THEN res := ok
            ELSE
               res := Libc.fflush(0);
               IF Libc.remove(fn) = 0 THEN res := ok ELSE res := Libc_errno() END
            END;
            IF res = ok THEN   (* it is hidden, and has no name anymore *)
               f.state := hidden; f.name := ''
            END;
         ELSE   (* old method *)
            CloseFileHandle(f, ^res);
            Stat(f.name, buf, res);
            ModeToAttr(buf.st_mode, attr, isDir);
            IF (res = ok) & ~(Files.readOnly IN attr) THEN
               num := Libc.clock(); n := 200;
               REPEAT
                  GetTempFileName(path, new, num); INC(num); DEC(n);
                  NameToLocal(new, nn);
                  MoveFile(fn, nn, res);
               UNTIL (res # fileExistsErr) OR (n = 0);
               IF res = ok THEN
                  f.state := hidden; f.name := new$
               END
            ELSE
               res := writeProtectedErr
            END
         END
      END
   END Delete;


Товарищи, может кто-то посмотреть опытным взглядом на это предложение? Выглядит весьма разумно.
Это позволит избавиться от мусорных odc при падении среды.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Понедельник, 08 Май, 2023 12:33 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1105
Иван Денисов писал(а):
arisu писал(а):
нашёл мелкую ошибочку в HostFiles64/Lin: в процедуре `Register()` вместо `Libc.fopen64()` используется `Libc.fopen()`.

В общем, тут не требуется исправление, поскольку там открывается пробный файл, в который запись не планируется. В после проверки временный файл перемещается.
ну, для красоты и единообразия. ;-)

Иван Денисов писал(а):
А вот если файл создан именно временный через .Temp, то вот тут было бы логично его складывать в /tmp
дык именно это я и предлагаю: чтобы `Files.dir.Temp()` создавал временные файлы через специально для этого придуманый API. с просто анонимными (но не временными) файлами так нельзя, конечно.

Иван Денисов писал(а):
Но тут можно столкнуться с проблемой, что на некоторых VPS, директория для временных файлов очень маленькая. В целом для пользователя могут быть неприятные сюрпризы с этим.
так их почти никто не создаёт, и они как раз мелких размеров. сама среда в освновном использует их как spill buffer в Text (как динамический массив, короче), и там нет варианта гигабайтных размеров. ;-)

Иван Денисов писал(а):
Ради похожести поведения Windows и Linux версии я бы оставил как есть пока с временными файлами. Мы как-то раз эту тему обсуждали небольшой компанией, и решили эти временные odc оставить. В норме ББ достаточно редко должен падать, чтобы их за собой не чистить.
ну, аргумент «как в винде», мне кажется, тут несостоятелен просто потому, что в виндоверсии тоже сделано неправильно: там тоже есть спецместо для временных файлов, которое можно получить специальным API. мне всё-таки кажется, что лучше временные файлы во временном каталоге делать — то есть, вести себя прилично, как предполагает host OS. и надо не линукс-версию оставлять кривой, а виндоверсию починить на правильное поведение.

Иван Денисов писал(а):
Товарищи, может кто-то посмотреть опытным взглядом на это предложение? Выглядит весьма разумно.
Это позволит избавиться от мусорных odc при падении среды.
я как обычно могу сказать, что у меня проблем с этим изменением не возникало. но если у кого-то есть время и ресурсы посмотреть свежими глазами — то будет здорово.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Понедельник, 08 Май, 2023 15:39 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1105
алсо, я могу вам сделать описаные выше изменения в LinFiles, если надо. имеет смысл?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Понедельник, 08 Май, 2023 15:45 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3731
arisu писал(а):
алсо, я могу вам сделать описаные выше изменения в LinFiles, если надо. имеет смысл?

Да вроде вы там понятно описали. Пока не надо делать. Ещё надо пообсуждать.

UPD: к тому же есть ещё глюк с сохранением файлов по ссылкам, и хочется это сразу тоже решить. Сделаю тестовый пример.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: BlackBox 2.0
СообщениеДобавлено: Понедельник, 08 Май, 2023 15:48 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1105
Иван Денисов писал(а):
arisu писал(а):
алсо, я могу вам сделать описаные выше изменения в LinFiles, если надо. имеет смысл?
Ещё надо пообсуждать.
ага, я потому и спросил.

Иван Денисов писал(а):
UPD: к тому же есть ещё глюк с сохранением файлов по ссылкам, и хочется это сразу тоже решить. Сделаю тестовый пример.
в смысле по симлинкам? сделайте, пожалуйста, будем разбираться.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2023, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB