On Sun, 2015 Apr 26 14:47+0000, Thorsten Glaser wrote: > Hi again, > > a few questions back, and a few early comments on the general idea > (I’ve not yet had the time to look at the patch itself):
Seems you did shortly after you wrote that :) > Assume we have mksh running on your EBCDIC environment. Let me ask a > few questions about this sort of environment, coupled with my guesses > about it. > > - the scripts themselves are 'iconv'd to EBCDIC? That is one way, but z/OS provides multiple layers of conversion that make the process easier: 1. You can mark a particular NFS mount as "text", so that every file read through that mount is converted on the fly from ASCII to EBCDIC. (There are also "binary mounts" that do no conversion, and reading an ASCII file through them gives you gibberish.) Of course, reading any kind of binary data through a "text" mount will not go well. This is how I worked for the most part, with the mksh sources being read through such a "text"-mode NFS mount. Especially as the only text editor available in this z/OS installation appears to be vi :< 2. For files that are on the local filesystem, you can assign them an extended filesystem attribute marking them as either binary or text, and if text, you can specify the code page (be it ASCII or EBCDIC). So if the file is properly "tagged," and auto-conversion in enabled, then an EBCDIC application can read an ASCII file and have it work transparently. The tagging utility is called "chtag", and the auto-conversion parameter is "AUTOCVT", for Googling purposes. 3. I did notice that after the mksh build completed, the following files were tagged as EBCDIC text: t IBM-1047 T=on Rebuild.sh t IBM-1047 T=on conftest.c t IBM-1047 T=on rlimits.gen t IBM-1047 T=on sh_flags.gen t IBM-1047 T=on signames.inc t IBM-1047 T=on test.sh So there's also an element of auto-tagging, even though it shouldn't make a difference here conversion-wise as the files are already in EBCDIC. To return to your question, while conversion with iconv(1) is available, you can see it's far from the most convenient approach. > - stuff like print/printf \x4F is expected to output '|' not 'O' Yep! Just tried it in the shell: $ printf '\x4F\n' | > - what about \u20AC? UTF-8? UTF-EBCDIC? Many code pages have received euro-sign updates; e.g. EBCDIC 924 is the euro-ified version of EBCDIC 1047. But that doesn't mean that anyone actually _uses_ the updated versions. I haven't seen 924 pop up anywhere. UTF-8 is known to the system. There is an IBM code-page ID for it (1208), iconv(1) knows about it, and you can tag files as UTF-8 text. I don't think that necessarily indicates wider Unicode support, however, as it would ultimately get converted to EBCDIC 1047 (or whatever) anyway. UTF-EBCDIC exists, but you wouldn't know it from the z/OS environment. No code-page ID [as far as I've found], no mention in "iconv -l". When I asked the mainframe guys at my company about it, they told me, "you don't really want to deal with that." I glanced at the Wikipedia article for UTF-EBCDIC, and can vouch for the accuracy of this paragraph: This encoding form is rarely used, even on the EBCDIC-based mainframes for which it was designed. IBM EBCDIC-based mainframe operating systems, such as z/OS, usually use UTF-16 for complete Unicode support. For example, DB2 UDB, COBOL, PL/I, Java and the IBM XML toolkit support UTF-16 on IBM mainframes. Locale support in z/OS is like it was in Linux over a decade ago: If you're a U.S. user, use the default code page; if you're a Russian user, use a Russian code page, and so on... and all code pages are 8 bits. > - keyboard input is in EBCDIC? I worked by way of SSH'ing in to the z/OS OMVS Unix environment. Everything in OMVS is EBCDIC, but of course my SSH client sends and receives everything in ASCII. There is a network translation layer in between, apart from the file-content conversion layers previously mentioned, that makes it all work transparently. A "real" mainframe connection, however, would be through TN3270, using the x3270 program or the like. Then the conversion is happening on the client side. But this is not relevant to mksh, because you don't get the z/OS Unix environment through TN3270; you get the old-school full-screen menu-driven interface that mainframe operators deal with. (You can bring up OMVS via the TN3270 menu screens, but then you get a horrible IRC-like line-based interface that sidesteps the normal Unix shell. IMO, still irrelevant to mksh.) > - is there anything that allows Unicode input? >From the keyboard? I've not seen anything suggesting this is possible. Even IBM's z/OS Unicode support via UTF-16 is, as far as I can tell, for use by applications and not by logged-in users. My understanding of why things like locale/encoding support on the console/terminal aren't up to snuff on z/OS is that this would only benefit the crusty mainframe operators, who are comparatively small in number compared to the user base of the application(s) running on the system. At the same time, there is z/Linux (Linux on the mainframe), and most organizations that want a modern mainframe Unix environment---and no EBCDIC goofiness---just go with that. z/Linux is not an option for me, however, so we have to confront all this weirdness head-on. > Daniel Richard G. dixit: > > >conditionalized in the code. Primarily, EBCDIC has the normal [-9A-Za- > >z] characters beyond 0x80, so it is not possible to set the high bit > >for signalling purposes---which mksh seems to do a lot of. > > Indeed. You probably refer to the variable substitution stuff (where > '#'|0x80 is used for ${foo##bar}) and possibly the MAGIC stuff in > extglobs @(foo|bar). > > That’s all legacy. I think it can go unconditionally. I couldn't even suss out exactly what the 0x80 was being used for, though I did see several variable-substitution tests fail. I'm glad someone else knows that code like the back of their hand! > >* Added clauses for TARGET_OS == "OS/390" > > Is OS/390 always an EBCDIC environment? Applications can be compiled in ASCII mode, and in fact I was experimenting with this. But the compilers, tools et al. still need EBCDIC input. (ASCII mode just means that all char/string literals are given ASCII codepoints instead of EBCDIC, and C/system calls accept and return ASCII. You end up with an ASCII application, basically, even though the source and environment aren't.) > >* '\012\015' != '\n\r' on this platform, so use the latter > > Agreed. I think I can change most of the C code to use the char > versions, i.e. '\n' and '@' instead of 0x0A or 0x40. I will have to > see about Build.sh though. It's certainly easier to let the compiler transcode characters. I did leave in conditionals so that ASCII builds continue to use numerical escapes, however, in light of those being more reliable on some older systems. > Looking at the patch (editing this eMail later), it seems you have > conditionalised those things nicely. That is good! I, too, take portability seriously :) > *BUT* some things in Build.sh – at least the $lfcr thing – are > dependent on the *host* OS, not the *target* OS. Ah, yes, that's true. xlc on z/OS can't cross-compile, but there is at least one compiler that can cross-compile to z/OS (Dignus Systems/C). > So, as far as I see, we will require two checks: > > • host OS (machine running Build.sh): ASCII-based or EBCDIC? Perhaps the "printf '\x4F'" thing can be used to detect an EBCDIC build environment... > • target OS (machine running the mksh/lksh binary created): > z/OS ASCII, z/OS EBCDIC, or anything else? There is also the matter of the EBCDIC variant. Of the EBCDIC code pages that contain all of ASCII, the characters are generally assigned consistently to the same codepoints. But one exception occurs between EBCDICs 1047 and 037, which assign '[', ']', and '^' differently---characters that are significant to the shell. (EBCDIC 037 is likely to be the second-most-popular code page after 1047, and is in fact the x3270 default.) I don't think it's feasible to have a single mksh binary support multiple EBCDIC variants, however, so IMO this matter is best left to the user's discretion in what CFLAGS they provide (-qconvlit option). As long as the code specifies these characters literally instead of numerically, everything should fall in line. > Remember mksh is cross-buildable. So we’ll need to come up with > (compile-time) checks for all those. That should be straightforward; the C_CTYPE_ASCII hack from gnulib is a nice compile-time way of determining the character set that doesn't rely on compiler-specific symbols. Even the EBCDIC variant could be detected that way, though IMO it is better to remain as agnostic as possible on this point. > >* NSIG is, amazingly, not #defined on this platform. Sure would be > > nice if the fancy logic that calculates NSIG could conditionally > > #define it, rather than a TARGET_OS conditional... :-) > > No, a TARGET_OS conditional is probably good here, as you cannot > really guess NSIG – as you noticed, you seem to have 37 signals, the > highest number of which is 39. > > The best way to determine NSIG is to look at libc sources, followed by > looking at libc binaries (e.g. determine the size of sys_siglist). No libc sources here, I'm afraid (everything is "OCO," as the mainframe folks say---"object code only"). I'm not sure there's a sys_siglist to be found, even if I could tell where the runtime libraries live. The Build.sh code wouldn't be able to suss out the signals any better if it knew about these that are unique to z/OS? IBM might add even more signals down the line, after all... > >* On this platform, xlc -qflag=... takes only one suboption, not two > > Hm. Is this a platform thing, a compiler version thing, etc? It seems that xlc on z/OS, though sharing a name with IBM's AIX compiler, comes from a different codebase. It _feels_ like an ancient version of xlc, in not recognizing many modern options, yet I am told that the version installed is current as of 2014. (The version reported, V2.1, also happens to be the running version of z/OS. I don't think that's a coincidence.) > >* Some special flags are needed for xlc on z/OS that are not needed > > on AIX, like to make missing #include files an error instead of a > > warning (!). Conversely, most of those AIX xlc flags are not > > recognized > > Can we get this sorted out so it continues working on AIX? I do not > have access to an AIX machine any longer, unfortunately. > > (Later: conditionalised, looks good.) I tried first to have Build.sh just test to see if the options were recognized, but (1) xlc only gives warnings if it doesn't recognize the option/suboptions, and (2) neither -qhaltonmsg nor -qseverity will accept making those warnings into errors, even though they gladly do so for other warnings! I do have access to modern AIX systems with xlc. Ohhh, I'm seeing some nastiness there: "rlimits.gen", line 20.20: 1506-191 (E) The character # is not a valid C source character. "rlimits.gen", line 20.21: 1506-191 (E) The character # is not a valid C source character. I can troubleshoot this once the code has stabilized... > >* Added a note that EBCDIC has \047 as the escape character rather > > than \033 > > Do EBCDIC systems use ANSI escapes (like ESC [ 0 m) still? I can't say whether that's the case in the TN3270 environment, but if I'm connected via SSH, then my terminal is just a standard TERM=xterm terminal window that responds accordingly. Of course, this is going through the automatic EBCDIC<->ASCII conversion; not just printable characters but also control characters get translated. > >+++ check.pl > > > >* I was getting a parse error with an expected-exit value of > > "e != 0", and adding \d to this regex fixed things... this wasn't > > breaking for other folks? > > No. I don’t pretend to know enough Perl to even understand that. > > But I think I see the problem, looking at the two regexps. I think > that “+-=” is expanded as range, which includes digits in ASCII. I’ll > have to go through CVS and .tgz history and see whether this was > intentional or an accidental fuckup. Ohhh, yes, good catch! Yes, that hyphen really ought to be the first character inside the brackets. I can't imagine that this was intentional--- if it were, then it would be awful form for transparency. > >+++ check.t > > > >* The "cd-pe" test fails on this system (perhaps it should be > > disabled?) and the directories were not getting cleaned up properly > > That fails on many systems. Sure, we can disable it. > > What is $^O in Perl on your platform? $ perl -e 'print $^O' ; echo os390 It's possible that this value may vary, depending on who did the Perl port. But this seems related to the value printed by "uname" (lowercased, minus the slash), and so should hopefully be stable. > >* If compiling in ASCII mode, #define _ENHANCED_ASCII_EXT so that as > > many C/system calls are switched to ASCII as possible (this is > > something I was experimenting with, but it's not how most people > > would be building/using mksh on this system) > > So it’s possible to use ASCII on the system, but atypical? Right. In an EBCDIC environment, it's not terribly useful: $ ./mksh -c 'echo zzz'; echo ::: I'm looking into setting up an environment that is all-ASCII, starting from /bin/sh (hence why I'm here), but have yet to figure out how to switch off the EBCDIC<->ASCII network conversion layer. (There are so many layers of conversion on z/OS that at times it's hard to keep track of what is what!) > >* Because EBCDIC characters like 'A' will have a negative value if > > signed chars are being used, #define the ORD() macro so we can > > always get an integer value in [0, 255] > > Huh, Pascal anyone? :) I figured, Perl and Python have picked it up, why not here too? ;) > >+++ edit.c (back to patch order) > > Here’s where we start going into Unicode land. This file is the one > that assumes UTF-8 the most. But that need not be active, right? I saw UTFMODE in run-time conditionals all over the place. > >* I don't understand exactly what is_mfs() is used for, but I'm > > pretty sure we can't do the & 0x80 with EBCDIC (note that e.g. > > 'A' == 0xC1) > > Motion separator. It’s simply assumed that, when you e.g. jump > forwards word-wise, anything with bit7 set is Unicode and to be jumped > over, as we don’t have iswprint() et al. Ah, okay, I see. Yes, that wouldn't really be applicable to EBCDIC, then. > >* Don't know much about XFUNC_VALUE(), but that & 0x7F looks un- > > kosher for EBCDIC > > No, that’s actually fine, that’s an enum (with < 128 values), and the > high bit is used here to swallow a trailing tilde, like in ANSI Del > (^[[3~). I'm very happy not to have to figure _everything_ out =) > >I will be happy to provide further testing and answer any questions > >as needed. > > OK. This is just a start. Agreed. > I’ll add the… hopefully not discouraging… comments now. As I’ve said, > I really like the enthusiasm, and absolutely want you to continue with > this. There is just a very big thing: > > One of mksh’s biggest strengths is that it’s consistent across *all* > platforms. An analogy, to help understand: > > I don’t know how much you know about Microsoft Windows, but they use > CR+LF (\r\n) as line separators usually for (old) native code. There > are Unix-like environments for it (Cygwin, and the much better > Interix/SFU/SUA, and the less-well-working UWIN and PW32), and you can > compile mksh for those; mksh will then behave as on Unix, i.e. require > LF-only (\n) line endings. > > Someone has started to port mksh to native WinAPI, and that port is > not 100% compatible to mksh, just “similar”, and uses it as base code. > That implementation then can use CR+LF. > > By definition, mksh does all its I/O in binary mode (not “text” mode, > so no CR+LF or (old Macintosh) CR-only line endings), and in the UTF-8 > encoding of 16-bit Unicode as charset. There are the differences/similarities in behavior (LF vs. CR+LF), and then there are the differences in code (Win32 API calls instead of POSIX calls). I'm presuming your point is that the latter is more of a practical concern... I mean, if you could support MacOS 9 with its CR-only line endings just by tweaking a few lines of code, surely that would be desirable, even if it makes an exception to the "consistent across all platforms" property? In reality, it would require a lot more invasive changes (not least due to the lack of POSIX), and I'd anticipate _that_ to be the main objection to integrating such support. > I’ve got a suggestion for you here, though. Most of it depends on some > answers to the questions I had above, this is just an initial rough > draft, to be discussed. > > I’ll merge most of the EBCDIC- and z/OS-related changes. A future mksh > release will compile for z/OS in ASCII mode out of the box, and pass > all of its tests there, if at all possible. Even if this is not how a > typical z/OS user would use mksh, this should be easy. I agree that this should be possible, and I hope to get there yet. > You’ll be the maintainer of something we call mksh/zOS, or something > like that (or mksh/EBCDIC), which has a separate $KSH_VERSION string. > I was thinking either “@(#)EBCDIC MKSH R…” or “@(#) Z/OS MKSH R…”, > with LKSH instead of MKSH for builds with -L, or just one string, and > you decide on whether you want “POSIX arithmetics” mode always enabled > or not (the main compile-time dif‐ ference of lksh) – but, why remove > the flexibility. I’d also ask Michael Langguth to make mksh/Win32 fit > this scheme (i.e. use something like “@(#) WIN32 MKSH”, depending on > what we agree on; currently, mksh/Win32 is based on mksh R39, so it > didn’t have the lksh yet). Ooof... a long-term commitment like this is going to be hard for me. For my part, porting mksh is just one piece of a larger puzzle I'm building. I'd like to leave things in good shape here, and then move on to other areas of investigation. My hope is that EBCDIC support can be integrated by generalizing code that assumes ASCII, and adding a minimum of code that is specific to EBCDIC (which is why my patch all but apologizes for the tables needed for Ctrl-key mapping). The one change in my patch that best exemplifies the approach I have in mind is - if ((s[0] | 0x20) == 'x') { + if (s[0] == 'x' || s[0] == 'X') { That not only makes the code EBCDIC-compatible, it arguably makes it clearer. Not a separate section of code prone to bit rot, but simply a particular discipline applied to the common/platform-independent code. > Details of this can be hashed out later. We can have this in a range > of varieties: > • you’ll ship mksh-ebcdic-*.tgz files from a separate repository > • I’ll ship them, from a separate repository > • we develop this in the same repo, in a separate branch > • or it could be a bunch of #ifdefs I would hope for the latter, keeping the set of #ifdefs as small and manageable as possible. > To be honest, I’d prefer looking at the amount of ifdefs before > agreeing to the latter though. mksh/Win32 is also separately > developed; while the code is close to “main” mksh, there *is* a patch, > part of which I’d prefer to not ship in mksh-R*.tgz itself. (But to > keep the delta small is a good aim.) This also allows for different > development tempo and release schedules. Fair enough; I think that the changes needed to support EBCDIC would weigh in a lot lighter than those needed to support Windows natively. The same POSIX API is used, after all---the worst of it is the Ctrl-key mapping tables. > As I said, I’ll gladly add “not-hurting” portability to EBCDIC to the > main code, e.g. remove the use of |0x80 as flag magic. (I’ll come up > with something, probably after the R51 release though. I’ve got > ideas.) But mksh uses UTF-8, and my plans for it will only make this > worse, e.g. I’m planning to make some code use 16-bit Unicode > internally (though part of *this* may make EBCDIC easier again). I > cannot commit to keep supporting EBCDIC systems, due to lack of > resources (my own time, skills (I have no experience with nōn-ASCII- > based systems) and lack of such machines). Will mksh continue to support ISO 8859-1 (Latin-1) environments, even if with reduced functionality? As long as UTF-8 mode isn't outright _required_, and bit 7 is left alone, I don't see that EBCDIC systems have much to worry about. > Do you think you can help me out there and invest a little time (a few > hours per month I guess) and maintain a port of mksh to EBCDIC-based > systems (or even just z/OS) for a long-ish time? I'll be happy to test, troubleshoot and submit patches as needed. Once EBCDIC is supported, and minimal care is taken over time to avoid breaking it, fixing it down the line will be straightforward. > Do you think you can, or want to, develop this separately, merging > changes back and forth? (I can, of course, do most of the changes- > merging work, but you will have to be there to deal with EBCDIC- > specific façettes.) Well... you really think the changes are extensive enough to warrant a fork? > This is all volunteer work, so I’ll understand if you cannot or don’t > want to commit to something long-lasting like this either. But from > the two messages you already sent, I presume you have got some kind of > interest ☺ Oh, the interest is there! I just didn't think of this work as being as brave-new-world-ish (in terms of code) as a Win32 or MacOS 9 native port would be... > Legalities: I just request that anything I merge is licenced under The > MirOS Licence¹, I don’t require anything like copyright assignment or > that, and I don’t even impose any licencing terms on the derivates > (like mksh/Win32), but I prefer they use a BSD-style licencing scheme > for the whole. (Michael said he’s planning to publish the whole Win32- > portability library under BSD-ish terms as well.) I am quite agreeable to BSD-ish terms, and in any event I hereby explicitly agree to release all of my work relating to mksh under the same license terms as mksh itself. > ① I have once, on an OSI mailing list, stated requirements for a > successor to The MirOS Licence. I don’t believe it will come to > that a successor is written, but should there be one, I’d be happy > to be able to switch the licence to it. Those mostly are: lawyer- > written, also applies to neighbouring rights such as database law > (in some EU countries). I wish the licence to be tailored to EU > (mostly .de, as I live there) law, protect all involved (authors, > contributors, licensors, licensees), but usable internationally as > far as that’s possible. I don’t really wish to touch the topic of > patent licences, but let it be understood that an implicit patent > grant is included. That's a fairly tall order. I've heard plenty about the FSFE from time to time, but nothing about a BSD-centric umbrella organization based in the EU, that would be an appropriate body to tackle developing such a license... > Urgh. I’m rambling again. Sorry about that. Well, you've read this far, so at least you're game as well ;) --Daniel -- Daniel Richard G. || sk...@iskunk.org My ASCII-art .sig got a bad case of Times New Roman.