diff options
author | Mike Fulton <mikefultonpersonal@gmail.com> | 2021-12-31 13:50:32 -0800 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2022-01-01 18:09:35 -0700 |
commit | 1c267c880abb4d52f0dc23c70636b5f2e80253be (patch) | |
tree | db658be8b12abcaefadb5cc012cb985e69a73b4f | |
parent | 7643f9bc98b3e5397ff14343c1c5f1ee3e00a8d9 (diff) | |
download | perl-1c267c880abb4d52f0dc23c70636b5f2e80253be.tar.gz |
Provide asciiopen and asciiopen3 for z/OS ASCII I/O
- Provide an _asciiopen_ and _asciiopen3_ pair of functions for opening
files on z/OS. These services do a standard open and then, if the
open is successful, update the CCSID of the file descriptor to 819
(ASCII) iff the oflag has ``O_CREAT`` set (e.g. a file is being
created). We could consider printing out a warning if a file is
untagged - right now this will _work correctly_ if the file in
encoded as ASCII (CCSID 819) but will fail if the file is EBCDIC.
- Provide a wrapper _Perl_mkstemp_cloexec_ which not only creates a
temporary file using mkstemp but will also tag the file as CCSID 819.
The tagging is only performed if ``__CHARSET_LIB == 1``, i.e. the
code is compiled with -qascii.
- Define _PerlIO_open_ and _PerlLIO_open3_ as _asciiopen_ and
_asciiopen3_ respectively, when the code is built for ASCII ``#if
(__CHARSET_LIB == 1)`` on z/OS ``#if defined(OEMVS)``.
-rw-r--r-- | doio.c | 80 | ||||
-rw-r--r-- | iperlsys.h | 18 |
2 files changed, 95 insertions, 3 deletions
@@ -218,6 +218,57 @@ Perl_PerlLIO_dup2_cloexec(pTHX_ int oldfd, int newfd) #endif } +#if defined(OEMVS) + #if (__CHARSET_LIB == 1) +# include <stdio.h> +# include <stdlib.h> + + static int setccsid(int fd, int ccsid) + { + attrib_t attr; + int rc; + + memset(&attr, 0, sizeof(attr)); + attr.att_filetagchg = 1; + attr.att_filetag.ft_ccsid = ccsid; + attr.att_filetag.ft_txtflag = 1; + + rc = __fchattr(fd, &attr, sizeof(attr)); + return rc; + } + + static void updateccsid(int fd, const char* path, int oflag, int perm) + { + int rc; + if (oflag & O_CREAT) { + rc = setccsid(fd, 819); + } + } + + int asciiopen(const char* path, int oflag) + { + int rc; + int fd = open(path, oflag); + if (fd == -1) { + return fd; + } + updateccsid(fd, path, oflag, -1); + return fd; + } + + int asciiopen3(const char* path, int oflag, int perm) + { + int rc; + int fd = open(path, oflag, perm); + if (fd == -1) { + return fd; + } + updateccsid(fd, path, oflag, perm); + return fd; + } + #endif +#endif + int Perl_PerlLIO_open_cloexec(pTHX_ const char *file, int flag) { @@ -246,8 +297,34 @@ Perl_PerlLIO_open3_cloexec(pTHX_ const char *file, int flag, int perm) #endif } +#if defined(OEMVS) + #if (__CHARSET_LIB == 1) + #define TEMP_CCSID 819 + #endif +static int Internal_Perl_my_mkstemp_cloexec(char *templte) +{ + PERL_ARGS_ASSERT_MY_MKSTEMP_CLOEXEC; +#if defined(O_CLOEXEC) + DO_ONEOPEN_EXPERIMENTING_CLOEXEC( + PL_strategy_mkstemp, + Perl_my_mkostemp(templte, O_CLOEXEC), + Perl_my_mkstemp(templte)); +#else + DO_ONEOPEN_THEN_CLOEXEC(Perl_my_mkstemp(templte)); +#endif +} int -Perl_my_mkstemp_cloexec(char *templte) +Perl_my_mkstemp_cloexec(char *templte) +{ + int tempfd = Internal_Perl_my_mkstemp_cloexec(templte); +#if defined(TEMP_CCSID) + setccsid(tempfd, TEMP_CCSID); +#endif + return tempfd; +} + +#else /* OEMVS */ +Perl_my_mkstemp_cloexec(char *templte) { PERL_ARGS_ASSERT_MY_MKSTEMP_CLOEXEC; #if defined(O_CLOEXEC) @@ -259,6 +336,7 @@ Perl_my_mkstemp_cloexec(char *templte) DO_ONEOPEN_THEN_CLOEXEC(Perl_my_mkstemp(templte)); #endif } +#endif int Perl_my_mkostemp_cloexec(char *templte, int flags) diff --git a/iperlsys.h b/iperlsys.h index edf9d50c44..b27764555c 100644 --- a/iperlsys.h +++ b/iperlsys.h @@ -49,6 +49,7 @@ */ #include "perlio.h" + typedef Signal_t (*Sighandler1_t) (int); typedef Signal_t (*Sighandler3_t) (int, Siginfo_t*, void*); @@ -776,8 +777,21 @@ struct IPerlLIOInfo # define PerlLIO_lstat(name, buf) PerlLIO_stat((name), (buf)) #endif #define PerlLIO_mktemp(file) mktemp((file)) -#define PerlLIO_open(file, flag) open((file), (flag)) -#define PerlLIO_open3(file, flag, perm) open((file), (flag), (perm)) +#if defined(OEMVS) + #if (__CHARSET_LIB == 1) + int asciiopen(const char* path, int oflag); + int asciiopen3(const char* path, int oflag, int perm); + + #define PerlLIO_open(file, flag) asciiopen((file), (flag)) + #define PerlLIO_open3(file, flag, perm) asciiopen3((file), (flag), (perm)) + #else + #define PerlLIO_open(file, flag) open((file), (flag)) + #define PerlLIO_open3(file, flag, perm) open((file), (flag), (perm)) + #endif +#else +# define PerlLIO_open(file, flag) open((file), (flag)) +# define PerlLIO_open3(file, flag, perm) open((file), (flag), (perm)) +#endif #define PerlLIO_read(fd, buf, count) read((fd), (buf), (count)) #define PerlLIO_rename(old, new) rename((old), (new)) #define PerlLIO_setmode(fd, mode) setmode((fd), (mode)) |