Spec-Zone.ru › Perl 5.38

perlapio

СОДЕРЖАНИЕ

  • НАЗВАНИЕ
  • СИНТАКСИС
  • ОПИСАНИЕ
    • Совместимость с stdio
    • Функции "быстрого ввода"
    • Другие функции

НАЗВАНИЕ

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's 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, 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(): аргумент "файл" передаётся первым, есть только один "count", и возвращаемое значение может различать ошибку и 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) при ошибке. Количество байтов, которые могут быть "возвращены назад", может меняться, только один символ гарантирован, и только если это последний символ, который был прочитан из дескриптора.

PerlIO_unread(f,buf,count)

Это позволяет возвращать больше одного байта. Он фактически "возвращает назад" 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,offset,whence)

Это соответствует fseek(). Отправляет буферизованные данные записи в базовый файл или отбрасывает любые буферизованные данные чтения, а затем позиционирует дескриптор файла как указано offset и whence (sic). Это правильное действие при переключении между чтением и записью в одном и том же дескрипторе (см. проблемы с PerlIO_flush() выше). Смещение имеет тип Off_t, что является значением Perl Configure, которое может не совпадать со значением stdio's off_t.

PerlIO_tell(f)

Это соответствует ftell(). Возвращает текущую позицию файла или (Off_t) -1 при ошибке. Может просто вернуть значение, которое система "знает", не делая системного вызова или не проверяя базовый дескриптор файла (поэтому использование на общих файловых дескрипторах небезопасно без PerlIO_seek()). Возвращаемое значение имеет тип Off_t, что является значением Perl Configure, которое может не совпадать со значением stdio's off_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)

Возвращает количество читаемых байтов в буфере. Ноль или отрицательное значение возврата означает, что больше байтов недоступно.

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–2023 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.38.0/perlapio

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API