Skip to content

Commit

Permalink
Provide asciiopen and asciiopen3 for z/OS ASCII I/O
Browse files Browse the repository at this point in the history
 - 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)``.
  • Loading branch information
Mike Fulton authored and khwilliamson committed Jan 2, 2022
1 parent 7643f9b commit 1c267c8
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 3 deletions.
80 changes: 79 additions & 1 deletion doio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
18 changes: 16 additions & 2 deletions iperlsys.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
*/
#include "perlio.h"


typedef Signal_t (*Sighandler1_t) (int);
typedef Signal_t (*Sighandler3_t) (int, Siginfo_t*, void*);

Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 1c267c8

Please sign in to comment.