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_fill(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);
Size_t PerlIO_unread(PerlIO *f,const void *vbuf, size_t count
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(pTHX_ PerlIO *f, const char *mode,
const char *layers);
int PerlIO_binmode(pTHX_ PerlIO *f, int ptype, int imode,
const char *layers);
void PerlIO_debug(const char *fmt,...); ОПИСАНИЕ
Исходный код Perl и расширения, которые требуют максимальной переносимости, должны использовать вышеперечисленные функции вместо функций, определённых в ANSI C в stdio.h. Заголовки Perl (в частности, "perlio.h") #define их с механизмом ввода-вывода, выбранным во время конфигурации.
Функции моделируются по функциям в stdio.h, но порядок параметров немного "приведён в порядок".
PerlIO * заменяет FILE *. Как и FILE *, его следует рассматривать как непросвечиваемый (вероятно, безопасно предположить, что это указатель на что-то).
В настоящее время существуют два варианта реализации:
- 1. USE_STDIO
-
Все вышеперечисленные функции #define'd к функциям 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, режим), PerlIO_fdopen(fd, режим)
-
Они соответствуют fopen()/fdopen(), и аргументы одинаковы. Возвращают
NULLи устанавливаютerrnoпри ошибке. Может быть ограничение на количество открытых дескрипторов, которое может быть меньше предела на количество открытых файлов —errnoможет не устанавливаться, когда возвращаетсяNULL, если этот предел превышен. - PerlIO_reopen(path, режим, f)
-
Хотя эта функция в настоящее время существует в обеих реализациях, сам Perl её не использует. Поскольку perl её не использует, она не была хорошо протестирована.
Perl предпочитает
dupнового низкоуровневого дескриптора к дескриптору, используемому существующим PerlIO. В будущем это может стать поведением этой функции. - PerlIO_printf(f, формат, ...), PerlIO_vprintf(f, формат, a)
-
Это эквиваленты fprintf()/vfprintf().
- PerlIO_stdoutf(формат, ...)
-
Это эквивалент printf(). printf определён через эту функцию, поэтому в исходных кодах Perl разрешается использовать
printf(fmt,...). - PerlIO_read(f, буфер, количество), PerlIO_write(f, буфер, количество)
-
Функционально они соответствуют fread() и fwrite(), но аргументы и возвращаемые значения отличаются. Подписи PerlIO_read() и PerlIO_write() моделировались по более разумным низкоуровневым функциям read() и write(): аргумент "файл" передаётся первым, есть только одно "количество", а возвращаемое значение может различать ошибку и
EOF.Возвращает количество байтов при успешном выполнении (которое может быть нулевым или положительным), возвращает отрицательное значение и устанавливает
errnoпри ошибке. В зависимости от реализацииerrnoможет бытьEINTRесли операция была прервана сигналом. - PerlIO_fill(f)
-
Заполняет буфер, связанный с
fданными из нижнего уровня.PerlIO_readвызывает эту функцию в рамках своей обычной работы. Возвращает 0 при успешном выполнении; -1 при неудаче. - 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_unread(f, буфер, количество)
-
Это позволяет возвращать больше одного байта. По существу, оно возвращает
countбайтов в начало буфераbuf, так что следующая операция чтения вернёт их до чего-либо другого, что было в буфере.Возвращает количество прочитанных байтов.
- PerlIO_getc(f)
-
Это соответствует getc(). Несмотря на c в названии, поддерживается только диапазон байтов 0..0xFF. Возвращает прочитанный символ или -1 (
EOF) при ошибке. - PerlIO_eof(f)
-
Это соответствует feof(). Возвращает значение true/false, указывающее, находится ли дескриптор в конце файла. Для устройств терминала это может быть "прилипающим", в зависимости от реализации. Флаг сбрасывается функциями PerlIO_seek() или PerlIO_rewind().
- PerlIO_error(f)
-
Это соответствует ferror(). Возвращает значение true/false, указывающее, была ли ошибка ввода-вывода для дескриптора.
- 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, смещение, откуда)
-
Это соответствует fseek(). Отправляет данные записи из буфера в подлежащий файл или отбрасывает любые данные чтения из буфера, затем позиционирует дескриптор файла как указано смещением и откуда (sic). Это необходимо при переключении между чтением и записью в одном дескрипторе (см. проблемы с PerlIO_flush() выше). Смещение типа
Off_t, что является значением конфигурации perl, которое может не совпадать со значением stdiooff_t. - PerlIO_tell(f)
-
Это соответствует ftell(). Возвращает текущую позицию файла или (Off_t) -1 при ошибке. Может просто возвращать значение, которое система "знает", без выполнения системного вызова или проверки подлежащего дескриптора файла (поэтому использование на общих дескрипторах файлов небезопасно без PerlIO_seek()). Возвращаемое значение типа
Off_t, что является значением конфигурации perl, которое может не совпадать со значением stdiooff_t. - PerlIO_getpos(f, p), PerlIO_setpos(f, p)
-
Эти функции (в общих чертах) соответствуют fgetpos() и fsetpos(). Вместо Fpos_t stdio они принимают "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. В зависимости от реализации могут быть "гонки", которые позволят другим процессам получить доступ к файлу, хотя, как правило, это будет безопаснее, чем схемы ad hoc. - 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 *. Стандартный типmap будет скорректирован для понимания любых изменений в этой области.
- 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().
Функции «Fast gets»
Помимо стандартного API, определённого выше, существует интерфейс «реализации», который позволяет Perl получать доступ к внутренним данным PerlIO. Следующие вызовы соответствуют различным макросам FILE_xxx, определённым Configure — или их эквивалентам в других реализациях. Этот раздел действительно представляет интерес только для тех, кто заинтересован в детальном поведении perl-core, реализации сопоставления 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)
-
Возвращает количество читаемых байтов в буфере. Возвращаемое значение 0 или отрицательное означает, что больше байтов недоступно.
- 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()(или что-то подобное) в последний раз, когда запрашивался ввод-вывод.
Другие функции
- PerlIO_apply_layers(aTHX_ f,mode,layers)
-
Новый интерфейс к реализации USE_PERLIO. Слои ":crlf" и ":raw" — единственные разрешённые для других реализаций, и они игнорируются. (Начиная с Perl5.8, ":raw" устарел.) Для портативного случая используйте PerlIO_binmode().
- PerlIO_binmode(aTHX_ f,ptype,imode,layers)
-
Крючок, используемый оператором Perl's
binmode. ptype — символ Perl для типа ввода-вывода:- '<' чтение
- '>' запись
- '+' чтение/запись
imode —
O_BINARYилиO_TEXT.layers — строка слоёв, которые нужно применить; только ":crlf" имеет смысл в случае без USE_PERLIO. (Начиная с Perl5.8, ":raw" устарел в пользу передачи NULL.)
Портативные случаи:
PerlIO_binmode(aTHX_ f,ptype,O_BINARY,NULL); and PerlIO_binmode(aTHX_ 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.36.0/perlapio