Spec-Zone.ru › Perl 5.28

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_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 и расширения, требующие максимальной переносимости, должны использовать вышеперечисленные функции вместо функций, определенных в ANSI C's stdio.h. Заголовки 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 определён через эту функцию, поэтому (в настоящее время) разрешается использовать printf(fmt,...) в исходных кодах perl.

PerlIO_read(f,buf,count), PerlIO_write(f,buf,count)

Функционально они соответствуют fread() и fwrite(), но аргументы и возвращаемые значения отличаются. Подписи PerlIO_read() и PerlIO_write() были смоделированы по более разумным низкоуровневым функциям read() и write(): аргумент «файл» передаётся первым, есть только один «count», и возвращаемое значение может различать ошибку и 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(). Возвращает true/false, указывающее, находится ли поток в конце файла. Для устройств терминала это может быть или не быть «прилипчивым» в зависимости от реализации. Флаг очищается функциями PerlIO_seek() или PerlIO_rewind().

PerlIO_error(f)

Это соответствует ferror(). Возвращает true/false, указывающее, была ли ошибка ввода-вывода в потоке.

PerlIO_fileno(f)

Это соответствует fileno(), обратите внимание, что на некоторых платформах значение «fileno» может не совпадать с Unix. Возвращает -1, если у потока нет связанного с ним дескриптора.

PerlIO_clearerr(f)

Это соответствует clearerr(), т.е. очищает флаги «ошибка» и (обычно) «eof» для «потока». Не возвращает значение.

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, которое может не совпадать со значением off_t stdio.

PerlIO_tell(f)

Это соответствует ftell(). Возвращает текущую позицию файла или (Off_t) -1 при ошибке. Может просто вернуть значение, которое система «знает», не выполняя системный вызов или не проверяя базовый дескриптор файла (поэтому использование на общих дескрипторах не безопасно без PerlIO_seek()). Возвращаемое значение имеет тип Off_t, который является значением конфигурации perl, которое может не совпадать со значением off_t stdio.

PerlIO_getpos(f,p), PerlIO_setpos(f,p)

Они (с некоторыми оговорками) соответствуют fgetpos() и fsetpos(). Вместо Fpos_t stdio они ожидают «Perl Scalar Value». Содержимое этой переменной следует рассматривать как непрозрачные данные. Формат данных может различаться от потока к потоку. При отсутствии 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» сбрасывает буфер. Что происходит с такими вещами, как «это\nто», не определено. (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() (или что-то подобное) в последний раз, когда был запрошен ввод-вывод.

Другие функции

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–2020 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.28.3/perlapio

Spec-Zone.ru

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