perlapio
СОДЕРЖАНИЕ
ИМЯ
perlapio - интерфейс абстракции ввода-вывода Perl.
СИНОПС
#define PERLIO_NOT_STDIO 0 /* For co-existence with stdio only */
#include <perlio.h> /* Usually via #include <perl.h> */
PerlIO *PerlIO_stdin(void);
PerlIO *PerlIO_stdout(void);
PerlIO *PerlIO_stderr(void);
PerlIO *PerlIO_open(const char *path,const char *mode);
PerlIO *PerlIO_fdopen(int fd, const char *mode);
PerlIO *PerlIO_reopen(const char *path, /* deprecated */
const char *mode, PerlIO *old);
int PerlIO_close(PerlIO *f);
int PerlIO_stdoutf(const char *fmt,...)
int PerlIO_puts(PerlIO *f,const char *string);
int PerlIO_putc(PerlIO *f,int ch);
SSize_t PerlIO_write(PerlIO *f,const void *buf,size_t numbytes);
int PerlIO_printf(PerlIO *f, const char *fmt,...);
int PerlIO_vprintf(PerlIO *f, const char *fmt, va_list args);
int PerlIO_flush(PerlIO *f);
int PerlIO_eof(PerlIO *f);
int PerlIO_error(PerlIO *f);
void PerlIO_clearerr(PerlIO *f);
int PerlIO_getc(PerlIO *d);
int PerlIO_ungetc(PerlIO *f,int ch);
SSize_t PerlIO_read(PerlIO *f, void *buf, size_t numbytes);
int PerlIO_fileno(PerlIO *f);
void PerlIO_setlinebuf(PerlIO *f);
Off_t PerlIO_tell(PerlIO *f);
int PerlIO_seek(PerlIO *f, Off_t offset, int whence);
void PerlIO_rewind(PerlIO *f);
int PerlIO_getpos(PerlIO *f, SV *save); /* prototype changed */
int PerlIO_setpos(PerlIO *f, SV *saved); /* prototype changed */
int PerlIO_fast_gets(PerlIO *f);
int PerlIO_has_cntptr(PerlIO *f);
SSize_t PerlIO_get_cnt(PerlIO *f);
char *PerlIO_get_ptr(PerlIO *f);
void PerlIO_set_ptrcnt(PerlIO *f, char *ptr, SSize_t count);
int PerlIO_canset_cnt(PerlIO *f); /* deprecated */
void PerlIO_set_cnt(PerlIO *f, int count); /* deprecated */
int PerlIO_has_base(PerlIO *f);
char *PerlIO_get_base(PerlIO *f);
SSize_t PerlIO_get_bufsiz(PerlIO *f);
PerlIO *PerlIO_importFILE(FILE *stdio, const char *mode);
FILE *PerlIO_exportFILE(PerlIO *f, const char *mode);
FILE *PerlIO_findFILE(PerlIO *f);
void PerlIO_releaseFILE(PerlIO *f,FILE *stdio);
int PerlIO_apply_layers(PerlIO *f, const char *mode,
const char *layers);
int PerlIO_binmode(PerlIO *f, int ptype, int imode,
const char *layers);
void PerlIO_debug(const char *fmt,...); ОПИСАНИЕ
Исходный код Perl и расширения, которые требуют максимальной переносимости, должны использовать перечисленные выше функции вместо функций, определенных в stdio.h ANSI C. Perl-заголовки (в частности, "perlio.h") #define их к механизму ввода-вывода, выбранному во время настройки.
Функции моделируются на функциях в stdio.h, но порядок параметров немного "улучшен".
PerlIO * заменяет FILE *. Как и FILE *, он должен обрабатываться как непрозрачный (вероятно, безопасно предположить, что это указатель на что-то).
В настоящее время существуют две реализации:
- 1. USE_STDIO
-
Все вышеперечисленное определено через функции stdio или является тривиальными функциями-обёртками, которые вызывают stdio. В этом случае только PerlIO * является FILE *. Это была реализация по умолчанию с момента внедрения абстракции в perl5.003_02.
- 2. USE_PERLIO
-
Введена сразу после perl5.7.0, это повторная реализация вышеупомянутой абстракции, которая позволяет Perl иметь больший контроль над выполнением операций ввода-вывода, поскольку она отвязывает операции ввода-вывода от способа, которым операционная система и библиотека C выбирают выполнять операции. Для USE_PERLIO PerlIO * имеет дополнительный уровень косвенности — это указатель на указатель. Это позволяет PerlIO * сохранять известное значение, в то время как реализация под ним меняется во время выполнения. В этом случае все вышеперечисленное являются истинными (но очень простыми) функциями, которые вызывают базовую реализацию.
Это единственная реализация, для которой
PerlIO_apply_layers()выполняет что-то "интересное".Реализация USE_PERLIO описана в perliol.
Поскольку "perlio.h" является тонким слоем (для эффективности), семантика этих функций в некоторой степени зависит от базовой реализации. Там, где эти различия понятны, они отмечены ниже.
Если не указано иное, функции возвращают 0 при успехе или отрицательное значение (обычно EOF, которое обычно равно -1) и устанавливают errno при ошибке.
- PerlIO_stdin(), PerlIO_stdout(), PerlIO_stderr()
-
Используйте их вместо
stdin,stdout,stderr. Они написаны так, чтобы выглядеть как "вызовы функций", а не переменные, поскольку это упрощает превращение их в вызовы функций, если платформа не может экспортировать данные в загруженные модули или если (скажем) у разных "потоков" могут быть разные значения. - PerlIO_open(path, mode), PerlIO_fdopen(fd,mode)
-
Они соответствуют fopen()/fdopen() и аргументы такие же. Возвращают
NULLи устанавливаютerrnoв случае ошибки. Может быть ограничение на количество открытых дескрипторов, которое может быть меньше ограничения на количество открытых файлов —errnoможет не устанавливаться при возвратеNULLесли это ограничение превышено. - PerlIO_reopen(path,mode,f)
-
Хотя эта функция в настоящее время существует в обеих реализациях, Perl её не использует. Так как Perl не использует её, она не хорошо протестирована.
Perl предпочитает
dupновый дескриптор низкого уровня к дескриптору, используемому существующим PerlIO. В будущем это может стать поведением этой функции. - PerlIO_printf(f,fmt,...), PerlIO_vprintf(f,fmt,a)
-
Они эквивалентны fprintf()/vfprintf().
- PerlIO_stdoutf(fmt,...)
-
Это эквивалент printf(). printf определён через эту функцию, поэтому в perl-источниках можно (в настоящее время) использовать
printf(fmt,...). - PerlIO_read(f,buf,count), PerlIO_write(f,buf,count)
-
Функционально они соответствуют fread() и fwrite(), но аргументы и возвращаемые значения отличаются. Подписи PerlIO_read() и PerlIO_write() смоделированы на более осмысленных функциях низкого уровня read() и write(): аргумент "файл" передаётся первым, есть только одно "количество", и возвращаемое значение может различать ошибку и
EOF.Возвращает количество байтов при успехе (которое может быть нулём или положительным), возвращает отрицательное значение и устанавливает
errnoпри ошибке. В зависимости от реализацииerrnoможет бытьEINTRесли операция была прервана сигналом. - PerlIO_close(f)
-
В зависимости от реализации
errnoможет бытьEINTRесли операция была прервана сигналом. - PerlIO_puts(f,s), PerlIO_putc(f,c)
-
Они соответствуют fputs() и fputc(). Обратите внимание, что аргументы изменены, чтобы "файл" шёл первым.
- PerlIO_ungetc(f,c)
-
Соответствует ungetc(). Обратите внимание, что аргументы изменены, чтобы "файл" шёл первым. Обеспечивает, что следующая операция чтения вернёт байт c. Несмотря на подразумеваемое "символ" в имени, определены только значения в диапазоне 0..0xFF. Возвращает байт c при успехе или -1 (
EOF) при ошибке. Количество байтов, которые могут быть "отправлены назад", может изменяться, точно известно только 1 символ, и то только если это последний символ, который был прочитан из потока. - PerlIO_getc(f)
-
Соответствует getc(). Несмотря на "c" в имени, поддерживается только диапазон байтов 0..0xFF. Возвращает прочитанный символ или -1 (
EOF) при ошибке. - PerlIO_eof(f)
-
Соответствует feof(). Возвращает индикатор истинности/ложности, указывающий, находится ли поток в конце файла. Для терминальных устройств это может быть "вязким" в зависимости от реализации. Флаг сбрасывается функциями PerlIO_seek() или PerlIO_rewind().
- PerlIO_error(f)
-
Соответствует ferror(). Возвращает индикатор истинности/ложности, указывающий, была ли ошибка ввода-вывода в потоке.
- PerlIO_fileno(f)
-
Соответствует fileno(). Обратите внимание, что на некоторых платформах значение "fileno" может не соответствовать Unix. Возвращает -1, если у потока нет ассоциированного дескриптора.
- PerlIO_clearerr(f)
-
Соответствует clearerr(), то есть сбрасывает флаги "ошибка" и (обычно) "конец файла" для "потока". Не возвращает значения.
- PerlIO_flush(f)
-
Соответствует fflush(). Отправляет все данные из буфера записи в базовый файл. Если вызывается с
NULL, это может сбросить все открытые потоки (или привести к ошибке с некоторыми реализациями USE_STDIO). Вызов для потока, открытого для чтения, или для которого последняя операция была чтением, может привести к неопределённому поведению в некоторых реализациях USE_STDIO. Реализация USE_PERLIO (слои) пытается вести себя лучше: она сбрасывает все открытые потоки, когда ей передаётсяNULL, и пытается сохранить данные в потоках чтения, либо в буфере, либо переместив указатель потока к текущей логической позиции. - PerlIO_seek(f,offset,whence)
-
Соответствует fseek(). Отправляет данные из буфера записи в базовый файл или отбрасывает данные из буфера чтения, затем позиционирует дескриптор файла, как указано значениями offset и whence (sic). Это правильная операция при переключении между чтением и записью в одном и том же потоке (см. проблемы с PerlIO_flush() выше). Значение смещения имеет тип
Off_t, которое является значением perl Configure, которое может не совпадать сoff_tstdio. - PerlIO_tell(f)
-
Соответствует ftell(). Возвращает текущую позицию файла или (Off_t) -1 при ошибке. Может просто вернуть значение, которое система "знает", без выполнения системного вызова или проверки базового дескриптора файла (поэтому использование на общих дескрипторах небезопасно без PerlIO_seek()). Возвращаемое значение имеет тип
Off_t, который является значением perl Configure, которое может не совпадать сoff_tstdio. - PerlIO_getpos(f,p), PerlIO_setpos(f,p)
-
Они (с некоторыми оговорками) соответствуют fgetpos() и fsetpos(). Вместо stdio's Fpos_t они принимают "скалярное значение Perl". Содержимое этого значения должно рассматриваться как непрозрачное. Структура данных может различаться в зависимости от потока. Если не используется stdio или если платформа не поддерживает эти вызовы stdio, они реализованы через PerlIO_tell() и PerlIO_seek().
- PerlIO_rewind(f)
-
Это соответствует rewind(). Обычно определено как
PerlIO_seek(f,(Off_t)0L, SEEK_SET); PerlIO_clearerr(f); - PerlIO_tmpfile()
-
Это соответствует tmpfile(), то есть возвращает анонимный PerlIO или NULL при ошибке. Система попытается автоматически удалить файл при закрытии. В Unix файл обычно
unlinkсразу после создания, так что способ его закрытия не важен. На других системах файл может быть удалён только при закрытии через PerlIO_close() и/или выходе программы черезexit. В зависимости от реализации могут существовать "гонки", которые позволят другим процессам получить доступ к файлу, хотя, как правило, это будет безопаснее, чем произвольные схемы. - PerlIO_setlinebuf(f)
-
Это соответствует setlinebuf(). Не возвращает значения. Что считается "строкой", зависит от реализации, но обычно означает, что запись "\n" сбрасывает буфер. Неясно, что произойдёт с такими данными как "this\nthat". (Perl core использует его только при "выгрузке"; он не связан с автоматическим сбросом $|).
Совместное использование с stdio
Есть общая поддержка совместного использования PerlIO с stdio. Очевидно, если PerlIO реализован через stdio, проблем нет. Однако в других случаях должны существовать механизмы для создания FILE *, которые можно передать коду библиотеки, который будет использовать вызовы stdio.
Первый шаг — добавить эту строку:
#define PERLIO_NOT_STDIO 0 перед включением любых perl-заголовочных файлов. (Это, вероятно, станет значением по умолчанию в какой-то момент). Это предотвращает попытки "perlio.h" определить stdio-функции через PerlIO-функции.
XS-код, скорее всего, будет лучше использовать "typemap", если он ожидает аргументы FILE *. Стандартный typemap будет изменён, чтобы учитывать любые изменения в этой области.
- PerlIO_importFILE(f,mode)
-
Используется для получения PerlIO * из FILE *.
Аргумент mode должен быть строкой, как и передаваемая в fopen/PerlIO_open. Если он равен NULL, то — для совместимости со старыми версиями — код (в зависимости от платформы и реализации) попытается эмпирически определить режим открытия f или использовать "r+" для обозначения потока чтения/записи.
После вызова FILE * должен только закрываться с помощью
PerlIO_close()на возвращённом PerlIO *.PerlIO установлен в текстовый режим. Используйте PerlIO_binmode, если требуется другой режим.
Это не обратная функция PerlIO_exportFILE().
- PerlIO_exportFILE(f,mode)
-
Используя PerlIO *, создаёт «родной» FILE *, подходящий для передачи коду, ожидающему компиляции и линковки с ANSI C stdio.h. Аргумент mode должен быть строкой, как и передаваемая в fopen/PerlIO_open. Если он равен NULL, то — для совместимости со старыми версиями — FILE * открывается в том же режиме, что и PerlIO *.
Факт, что такой FILE * был «экспортирован», фиксируется (обычно путём добавления нового «слоя» :stdio к PerlIO *), что может повлиять на будущие операции PerlIO с оригинальным PerlIO *. Вы не должны вызывать
fclose()на файле, если не вызываетеPerlIO_releaseFILE()для отсоединения его от PerlIO *. (Не используйте PerlIO_importFILE() для отсоединения.)Повторный вызов этой функции каждый раз будет создавать FILE * (и добавлять слой :stdio каждый раз).
- PerlIO_releaseFILE(p,f)
-
Вызов PerlIO_releaseFILE информирует PerlIO о том, что все операции с FILE * завершены. Он удаляется из списка «экспортированных» FILE *, и связанный PerlIO * должен вернуться к своему исходному поведению.
Используйте эту функцию для отсоединения файла от PerlIO *, который был связан с помощью PerlIO_exportFILE().
- PerlIO_findFILE(f)
-
Возвращает родной FILE *, используемый слоем stdio. Если его нет, он создаст его с помощью PerlIO_exportFILE. В любом случае FILE * должен рассматриваться как принадлежащий подсистеме PerlIO и закрываться только с помощью
PerlIO_close().
Функции «Быстрое получение»
В дополнение к стандартному API, определённому выше, существует интерфейс «реализации», который позволяет Perl получить доступ к внутренним данным PerlIO. Следующие вызовы соответствуют различным макросам FILE_xxx, определённым в Configure — или их эквивалентам в других реализациях. Этот раздел действительно интересен только тем, кто интересуется подробным поведением Perl-ядра, реализацией сопоставления PerlIO или разработкой кода, который может использовать «предварительное чтение», выполненное системой ввода-вывода так же, как это делает Perl. Обратите внимание, что любой код, использующий эти интерфейсы, должен быть готов выполнить операции традиционным способом, если обработчик их не поддерживает.
- PerlIO_fast_gets(f)
-
Возвращает true, если реализация имеет все необходимые интерфейсы, позволяющие Perl's
sv_gets«обойти» обычный механизм ввода-вывода. Это может зависеть от обработчика.PerlIO_fast_gets(f) = PerlIO_has_cntptr(f) && \ PerlIO_canset_cnt(f) && \ 'Can set pointer into buffer' - PerlIO_has_cntptr(f)
-
Реализация может вернуть указатель на текущую позицию в «буфере» и количество доступных байтов в буфере. Не используйте эту функцию — используйте PerlIO_fast_gets.
- PerlIO_get_cnt(f)
-
Возвращает количество читаемых байтов в буфере. Возвращение нуля или отрицательного значения означает, что больше байтов недоступно.
- PerlIO_get_ptr(f)
-
Возвращает указатель на следующий читаемый байт в буфере. Доступ через указатель (разыменование) безопасен только в том случае, если PerlIO_get_cnt() вернуло положительное значение. Разрешены только положительные смещения до значения, возвращённого PerlIO_get_cnt().
- PerlIO_set_ptrcnt(f,p,c)
-
Устанавливает указатель в буфер и количество байтов, оставшихся в буфере. Следует использовать только для установки указателя в пределах диапазона, подразумеваемого предыдущими вызовами
PerlIO_get_ptrиPerlIO_get_cnt. Два значения должны быть согласованными (реализация может использовать только одно из них или оба). - PerlIO_canset_cnt(f)
-
Реализация может изменить своё представление о количестве байтов в буфере. Не используйте эту функцию — используйте PerlIO_fast_gets.
- PerlIO_set_cnt(f,c)
-
Неясная функция — устанавливает количество байтов в буфере. Устарела. Используется только если PerlIO_canset_cnt() возвращает true. В настоящее время используется только в doio.c для принудительного изменения количества меньше -1 на -1. Возможно, следует переименовать в PerlIO_set_empty или аналогичное. Этот вызов может фактически ничего не сделать, если «количество» выводится из указателя и «лимита». Не используйте эту функцию — используйте PerlIO_set_ptrcnt().
- PerlIO_has_base(f)
-
Возвращает true, если реализация имеет буфер и может вернуть указатель на весь буфер и его размер. Используется Perl для тестов -T / -B. Другие случаи использования очень специфичны…
- PerlIO_get_base(f)
-
Возвращает начало буфера. Доступны только положительные смещения в буфере до значения, возвращённого PerlIO_get_bufsiz().
- PerlIO_get_bufsiz(f)
-
Возвращает общее количество байтов в буфере. Это ни количество, которое может быть прочитано, ни выделенная память под буфер. Это то, что операционная система и/или реализация последним разом выдали
read()(или что-то подобное) в ответ на запрос IO.
Другие функции
- PerlIO_apply_layers(f,mode,layers)
-
Новый интерфейс для реализации USE_PERLIO. Слои ":crlf" и ":raw" являются единственными допустимыми для других реализаций, и они будут игнорироваться. (Начиная с Perl5.8, ":raw" устарела.) Используйте PerlIO_binmode() для портативного случая.
- PerlIO_binmode(f,ptype,imode,layers)
-
Обработчик, используемый оператором Perl's
binmode. ptype — символ Perl для типа ввода-вывода:- '<' чтение
- '>' запись
- '+' чтение/запись
imode —
O_BINARYилиO_TEXT.layers — строка слоёв для применения. Только ":crlf" имеет смысл в случае, не использующем USE_PERLIO. (Начиная с Perl5.8, ":raw" устарела и заменена на NULL.)
Портативные случаи:
PerlIO_binmode(f,ptype,O_BINARY,NULL); and PerlIO_binmode(f,ptype,O_TEXT,":crlf");В Unix эти вызовы, вероятно, не будут иметь никакого эффекта. В других системах они изменят перевод "\n" на CR,LF и, возможно, приведут к записи или обработке специального признака «конец файла» при чтении. Эффект вызова после выполнения ввода-вывода зависит от реализации. (Он может быть проигнорирован, повлиять на данные, которые уже буферизованы, или применяться только к последующим данным.)
- PerlIO_debug(fmt,...)
-
PerlIO_debug — функция printf(), которая может использоваться для отладки. Значение не возвращается. Её основное применение — внутри PerlIO, где использование реальных printf, warn() и т.д. привело бы к рекурсивному вызову PerlIO и проблемам.
PerlIO_debug записывает в файл, указанный в $ENV{'PERLIO_DEBUG'}, или по умолчанию в stderr, если переменная среды не определена. Типичное использование:
Bourne shells (sh, ksh, bash, zsh, ash, ...): PERLIO_DEBUG=/tmp/perliodebug.log ./perl -Di somescript some args Csh/Tcsh: setenv PERLIO_DEBUG /tmp/perliodebug.log ./perl -Di somescript some args If you have the "env" utility: env PERLIO_DEBUG=/tmp/perliodebug.log ./perl -Di somescript args Win32: set PERLIO_DEBUG=perliodebug.log perl -Di somescript some argsВ случае Perl, скомпилированном без
-DDEBUGGING, или когда переключатель командной строки-Diне указан, или в случае загрязнения, PerlIO_debug() является пустой операцией.
© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.34.0/perlapio