Spec-Zone.ru › Perl 5.30

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 и расширения, которые требуют максимальной переносимости, должны использовать перечисленные выше функции вместо функций, определенных в 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_t stdio.

PerlIO_tell(f)

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

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

Spec-Zone.ru

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