OberonCore https://forum.oberoncore.ru/ |
|
Исправления в LinFiles https://forum.oberoncore.ru/viewtopic.php?f=134&t=6942 |
Страница 1 из 1 |
Автор: | arisu [ Четверг, 04 Май, 2023 09:07 ] |
Заголовок сообщения: | Исправления в LinFiles |
нашёл мелкую ошибочку в HostFiles64/Lin: в процедуре `Register()` вместо `Libc.fopen64()` используется `Libc.fopen()`. |
Автор: | arisu [ Пятница, 05 Май, 2023 12:49 ] |
Заголовок сообщения: | Re: BlackBox 2.0 |
кстати, 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". |
Автор: | arisu [ Пятница, 05 Май, 2023 12:55 ] |
Заголовок сообщения: | Re: BlackBox 2.0 |
а, и ещё там же, в 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()` — что есть (как и должно быть, логика требует именно такого поведения). |
Автор: | Иван Денисов [ Понедельник, 08 Май, 2023 10:30 ] |
Заголовок сообщения: | Re: BlackBox 2.0 |
arisu писал(а): нашёл мелкую ошибочку в HostFiles64/Lin: в процедуре `Register()` вместо `Libc.fopen64()` используется `Libc.fopen()`. В общем, тут не требуется исправление, поскольку там открывается пробный файл, в который запись не планируется. В после проверки временный файл перемещается. |
Автор: | Иван Денисов [ Понедельник, 08 Май, 2023 10:36 ] |
Заголовок сообщения: | Re: BlackBox 2.0 |
arisu писал(а): также в `CreateFile()` можно использовать стандартную либц-функцию для создания безымянных временных файлов (потому что временные файлы по контракту нельзя регистрировать в файловой системе) ... это идеологически правильней, нежели создавать файлы с временными именами, потому что `tmpfile()` правильно сделает такие файлы в "/tmp". Если директория и /tmp на разных дисках, то получится, что в момент сохранения произойдёт копирование с одного диска на другой. Нежелательное поведение. А вот если файл создан именно временный через .Temp, то вот тут было бы логично его складывать в /tmp чтобы не тратить ресурсы SSD, к примеру, если у кого-то временная папка специально выделена в отдельный ресурс. Но тут можно столкнуться с проблемой, что на некоторых VPS, директория для временных файлов очень маленькая. В целом для пользователя могут быть неприятные сюрпризы с этим. А так всё меньше людей берегут ресурсы SSD, они и повыносливее становятся. Ради похожести поведения Windows и Linux версии я бы оставил как есть пока с временными файлами. Мы как-то раз эту тему обсуждали небольшой компанией, и решили эти временные odc оставить. В норме ББ достаточно редко должен падать, чтобы их за собой не чистить. |
Автор: | Иван Денисов [ Понедельник, 08 Май, 2023 11:08 ] |
Заголовок сообщения: | Re: BlackBox 2.0 |
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 при падении среды. |
Автор: | arisu [ Понедельник, 08 Май, 2023 12:33 ] |
Заголовок сообщения: | Re: BlackBox 2.0 |
Иван Денисов писал(а): 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 при падении среды. |
Автор: | arisu [ Понедельник, 08 Май, 2023 15:39 ] |
Заголовок сообщения: | Re: BlackBox 2.0 |
алсо, я могу вам сделать описаные выше изменения в LinFiles, если надо. имеет смысл? |
Автор: | Иван Денисов [ Понедельник, 08 Май, 2023 15:45 ] |
Заголовок сообщения: | Re: BlackBox 2.0 |
arisu писал(а): алсо, я могу вам сделать описаные выше изменения в LinFiles, если надо. имеет смысл? Да вроде вы там понятно описали. Пока не надо делать. Ещё надо пообсуждать. UPD: к тому же есть ещё глюк с сохранением файлов по ссылкам, и хочется это сразу тоже решить. Сделаю тестовый пример. |
Автор: | arisu [ Понедельник, 08 Май, 2023 15:48 ] |
Заголовок сообщения: | Re: BlackBox 2.0 |
Иван Денисов писал(а): arisu писал(а): алсо, я могу вам сделать описаные выше изменения в LinFiles, если надо. имеет смысл? Ещё надо пообсуждать.Иван Денисов писал(а): UPD: к тому же есть ещё глюк с сохранением файлов по ссылкам, и хочется это сразу тоже решить. Сделаю тестовый пример. в смысле по симлинкам? сделайте, пожалуйста, будем разбираться.
|
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |