ANSI C89 and POSIX portability?
LordNite asks: "Here is the situation. I am maintaining a piece of source code which is written in K&R C. One of the original goals of this code was to be as portable as possible to as many platforms as possible. The code runs on UNIX and its clones as well as OS/2. The code avoids POSIX functions such as mmap(2) since at the time it was initially written (early 1990s) POSIX was not very wide spread. The code is well written, but in need of some serious fixing. As I go around fixing parts of the code I would also like to modernize it a bit. Since it is now 2004, can I rely on ANSI C89 and POSIX routines without sacrificing the portability of this code? (Yes, I do realize that the purpose of POSIX is code portability...) I am not really interested in the OS/2 port at this time. I am just interested in keeping portability with UNIX clones. To put my question another way: Are there any UNIX-like OSes in common use, which are currently developed and supported by some entity either OSS or proprietary, that do not support POSIX and ANSI C89?"
It's also worth mentioning that - as long as you stick to POSIX standards - you can then even compile your program for Windows by using some kind of compatibility layer (Cygwin or Microsoft SFU).
That is to say, POSIX is an important enough standard that even the world's least compatible operating system has a choice of POSIX compatibility modes...
In case anyone's interested, this is a HP-UX 11 (the machine is a 9000/800) system, and we can only use it, not administer it, and they pretty much refuse to upgrade anything other than Oracle on it, so we're still stuck with the damned compiler.
That said, there is a solution: GNU GCC comes with an ANSI to K&R tool. I've not tried it, but it's probably worth playing with. If your ANSI 89 C code can also stay compatable with the translator, then your plans for total compatability should hold up.
And, of course, some people would argue that K&R was never standard anyway. They're kind of correct, there was a general consensus to how it should work (some of which contradicted the book itself) and most of the incompatabilities were actually extensions, but there will be areas of incompatability whatever you do.
You are not alone. This is not normal. None of this is normal.
You can always try to install gcc in some temp dir. That's what I do on such castrated platforms. It goes a long way to restore sanity.
Plan 9 is/was the successor to Unix from the people who brought you Unix to begin with.
It's compiler suites, which approach multiple architectures a little differently, by default don't have hardly and ANSI C or POSIX support. If you need that stuff you have to use the APE frameworks. See this for more information.
The fact that it's not quite ANSI C and not quite POSIX by default shouldn't discourage you from playing with the OS though or even trying to use it. Apparently the "thin client" trend is coming back and Plan 9 systems support that metaphor quite nicely where everyone has a graphical display and a private hierarchical namespace [each process can have a different namespace in fact]. The OS is meant to be distributed across many nodes, with CPU nodes and File Serving nodes being part of a grid, but you can run it standalone fairly easily as well.
I've found that even though it doesn't have a great X implementation I can still VNC to other machines that do when I need X and that I can use ssh with their terminal emulator when I need to work with systems Plan 9 can't "mount" or "bind" into my namespace.
As you can probably tell. I was impressed.
If you don't want to mess with installing over you existing OS you can try Inferno which installs on Windows, Linux, FreeBSD and even MacOS X [but if you run Panther you will probably need this patched emulator and installer to make it work]. Once done you can build a multi-CPU-architecture grid all your own and learn the "Limbo" programming language and start harnessing those extra CPU cyucles. Inferno also supports thos hierarchical namespaces of Plan 9.
For some value of "works". Autoconf and automake are sorry hacks that should never have been undertaken.
Instead, there should be one master "config.h" file that infers from the platform headers exactly what HAVE_xxx macros should be defined, and one master "config.c" that abstracts over differences where it is trivial to do so. Everybody shares that, and nobody needs this jiggery-pokery with autoconf, automake, dlltool running recursive m4s. For the love of God, Montressor -- m4!\
-I like my women like I like my tea: green-
- The ls command returns success on OS X, even if no files were found.
- The test command has some options, like -e, which are not portable.
- HP-UX requires an ioctl() to detect that a slave PTY has closed.
- AIX has fewer than 64 PTYs configured, by default, which exposed a bug in one of my programs.
- There seems to be disagreement on the types of some socket functions.
I have yet to figure out how to get the client's address from accept() without causing a compile warning on at least one platform.
- Reaping child processes seems to be another mess.
The most portable solution I've found is to double fork, letting init clean up the zombies.
I've started porting a Unix program to Windows and VMS, which has been interesting. For example, Windows and VMS both have a select() function, but it only works on sockets. The popen()/_popen() function on Unix and Windows doesn't redirect stderr, whereas it does on VMS. VMS only lets you get the actual exit status from waitpid() or pclose() in recent versions.I have to agree.
I've done autoconf maintenance for some open source projects, I contributed to the auto* projects and my final conclusion is that they are not helping.
Instead I am just building my own detection code in a similar line as postfix' makedefs does. A lot clearer and keeps your sanity.
Jeroen Ruigrok/Asmodai
Just do it.
For both TenDRA and DragonFly we're using ANSI C94 (C90 plus amendments) along with POSIX/SUS and the code in general tends to get cleaner and cleaner (and easier to understand in my opinion).
It is amazing, since I am doing a lot of these conversions on a plethora of different old time tools, how much programming errors/mistakes the old code managed to get away with...
Jeroen Ruigrok/Asmodai
Autoconf does not work. It it supposed to dynamically test the platform and figure out the appropriate way to build your app on the system. It tries to do this, but, it all comes down to the fact that it only works on the style of systems that autoconf was written for.
.exe's.
.exe files versus .App directories, resource files, etc.
What do I mean? A big one I hate autoconf for is how cross compiling is broken on almost every one as many compiler tests require the ability to run the code locally. A neat trick I found is that I can cross compile to mingwin32 from linux if linux is on i386 and I have wine installed! But alas, I usually cannot cross compile to mingwin32 from mac osx because the autoconf tests are unable to run the
Another one is how it interacts with slightly different environments like cygwin/mingw/mac osx :
After originally being a total autoconf convert myself (I have the books!) I decided to roll my own. #ifdefs for the platforms that matter to me, and only those - for only those will be tested anyways. And Makefiles that use the filesystem to decide what files to compile into a library or executable, so nothing needs to change until a new platform is needed.
--jeff++
ipv6 is my vpn