Spec-Zone.ru › Perl 5.36

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

PerlIO_tell(f)

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

Возвращает количество читаемых байтов в буфере. Возвращаемое значение 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

Spec-Zone.ru

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