summaryrefslogtreecommitdiff
path: root/doio.c
diff options
context:
space:
mode:
authorMike Fulton <mikefultonpersonal@gmail.com>2021-12-31 13:50:32 -0800
committerKarl Williamson <khw@cpan.org>2022-01-01 18:09:35 -0700
commit1c267c880abb4d52f0dc23c70636b5f2e80253be (patch)
treedb658be8b12abcaefadb5cc012cb985e69a73b4f /doio.c
parent7643f9bc98b3e5397ff14343c1c5f1ee3e00a8d9 (diff)
downloadperl-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)``.
Diffstat (limited to 'doio.c')
-rw-r--r--doio.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/doio.c b/doio.c
index 9233b9a1e1..92a9d04da4 100644
--- a/doio.c
+++ b/doio.c
@@ -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)