oksh
oksh copied to clipboard
Build errors on HP-UX
Hi,
Fellow OpenBSD user here, with access to an Itanium HP-UX 11.31i server. I gave this a try, inspired by your call for HP-UX testing in README.md
.
Have tried to build this with both the C and aC++ compilers (the latter can also compile ANSI-C if invoked with -Ae
).
Versions used:
$ cc -V
cc: HP C/aC++ B3910B A.06.27 [May 22 2012]
$ aCC -V
aCC: HP C/aC++ B3910B A.06.27 [May 22 2012]
$ ./configure
checking for C compiler... cc
checking if C compiler can compile C99 without -std=c99... yes
checking for -w compiler flag... yes
checking for OS... HP-UX
checking for __dead... no
checking for __dead2... no
checking for asprintf... no
checking for confstr... yes
checking for curses library... curses.h
checking for issetugid... no
checking for pledge... no
checking for reallocarray... no
checking for setresgid... yes
checking for setresuid... yes
checking for sig_t... no
checking for srand_deterministic... no
checking for st_mtim... no
checking for st_mtimespec... no
checking for stravis... no
checking for strlcat... no
checking for strlcpy... no
checking for strtonum... no
checking for strunvis... no
checking for sys_siglist... no
checking for sys_signame... no
checking for timeradd... no
checking for timersub... no
creating Makefile... done
$ make
cc -DEMACS -DVI -w -c c_sh.c
"c_sh.c", line 735: error #2020: identifier "CLOCK_MONOTONIC" is undefined
clock_gettime(CLOCK_MONOTONIC, &ts0);
^
1 error detected in the compilation of "c_sh.c".
*** Error exit code 2
Stop.
$ export CC="aCC -Ae"
$ ./configure
checking for C compiler... aCC -Ae
checking if C compiler can compile C99 without -std=c99... yes
checking for -w compiler flag... yes
checking for OS... HP-UX
checking for __dead... no
checking for __dead2... no
checking for asprintf... no
checking for confstr... yes
checking for curses library... curses.h
checking for issetugid... no
checking for pledge... no
checking for reallocarray... no
checking for setresgid... yes
checking for setresuid... yes
checking for sig_t... no
checking for srand_deterministic... no
checking for st_mtim... no
checking for st_mtimespec... no
checking for stravis... no
checking for strlcat... no
checking for strlcpy... no
checking for strtonum... no
checking for strunvis... no
checking for sys_siglist... no
checking for sys_signame... no
checking for timeradd... no
checking for timersub... no
creating Makefile... done
$ make
aCC -Ae -DEMACS -DVI -w -c alloc.c
aCC -Ae -DEMACS -DVI -w -c asprintf.c
aCC -Ae -DEMACS -DVI -w -c c_ksh.c
aCC -Ae -DEMACS -DVI -w -c c_sh.c
"c_sh.c", line 735: error #2020: identifier "CLOCK_MONOTONIC" is undefined
clock_gettime(CLOCK_MONOTONIC, &ts0);
^
1 error detected in the compilation of "c_sh.c".
*** Error exit code 2
Stop.
OK. If clock_gettime is an available function but CLOCK_MONOTONIC is not a valid clock_id, then we will have to fall back to CLOCK_REALTIME.
Can you please add the following to portable.h
and rebuild and let me know where the next issue is:
#ifndef CLOCK_MONOTONIC
#define CLOCK_MONOTONIC CLOCK_REALTIME
#endif
Thanks for the quick feedback! I'm slower, as this beast is hosted remotely and kept mostly stopped because it's a power hog.
Next issue:
$ make
cc -DEMACS -DVI -w -c c_sh.c
cc -DEMACS -DVI -w -c c_test.c
cc -DEMACS -DVI -w -c c_ulimit.c
cc -DEMACS -DVI -w -c edit.c
"edit.c", line 182: error #2020: identifier "VDISCARD" is undefined
cb.c_cc[VDISCARD] = _POSIX_VDISABLE;
^
1 error detected in the compilation of "edit.c".
*** Error exit code 2
Stop.
No problem. We'll get there eventually. This error is a new one I haven't seen before from other platforms; I'll try to figure out a solution and get back to you.
Looking at what mksh does, it seems like the thing to do is wrap that line, edit.c:182
with
#ifndef __hpux__
cb.c_cc[VDISCARD] = _POSIX_VDISABLE;
#endif
At least for now. We can add a configure check for VDISCARD later.
Same error occurs, as the branching doesn't function as expected, it seems.
I guess it's not the right thing to do, but if I use #ifdef __hpux__
instead, I get past this on HP-UX.
Next error would be:
$ make
cc -DEMACS -DVI -w -c edit.c
cc -DEMACS -DVI -w -c emacs.c
cc -DEMACS -DVI -w -c eval.c
cc -DEMACS -DVI -w -c exec.c
"exec.c", line 12: error #3696-D: cannot open source file "paths.h"
#include <paths.h>
^
"exec.c", line 712: error #2020: identifier "_PATH_BSHELL" is undefined
shell = _PATH_BSHELL;
^
2 errors detected in the compilation of "exec.c".
*** Error exit code 2
Stop.
Ah. That tells me that hpux isn't the right define to detect HPUX. That's fine; I'll make it a more generic check for VDISCARD.
Could you tell me what the default shell is on the machine? Is it /bin/sh
? That's what _PATH_BSHELL is looking for.
Though now looking at the code, that definitely needs to change for everyone, so I'll go back to the drawing board :)
OK, after some research...
Can you wrap the #include <paths.h>
line in #if 0
like so:
#if 0
#include <paths.h>
#endif
Also, in the file portable.h
can you add the following somewhere:
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif
Ah. That tells me that hpux isn't the right define to detect HPUX. That's fine; I'll make it a more generic check for VDISCARD.
OK. For now, I'll keep using the stupid define that doesn't break on HP-UX.
Could you tell me what the default shell is on the machine? Is it
/bin/sh
? That's what _PATH_BSHELL is looking for.
On HP-UX, /bin
is linked to /usr/bin
, and the default shell is ~/sbin/sh
~. Sorry, it actually is:
-
/sbin/sh
for root and other system users -
/bin/sh
for regular users.
OK, after some research... Can you wrap the
#include <paths.h>
line in#if 0
like so:#if 0 #include <paths.h> #endif
Also, in the file
portable.h
can you add the following somewhere:#ifndef _PATH_BSHELL #define _PATH_BSHELL "/bin/sh" #endif
With these changes (/bin/sh
is actually the default shell for regular users, see correction in my previous comment), I get:
$ make
cc -DEMACS -DVI -w -c edit.c
cc -DEMACS -DVI -w -c exec.c
cc -DEMACS -DVI -w -c expr.c
cc -DEMACS -DVI -w -c history.c
cc -DEMACS -DVI -w -c io.c
cc -DEMACS -DVI -w -c jobs.c
cc -DEMACS -DVI -w -c lex.c
cc -DEMACS -DVI -w -c mail.c
cc -DEMACS -DVI -w -c main.c
"main.c", line 11: error #3696-D: cannot open source file "paths.h"
#include <paths.h>
^
"main.c", line 111: error #2020: identifier "MAXLOGNAME" is undefined
char username[_PW_NAME_LEN + 1];
^
"main.c", line 202: error #2020: identifier "_PATH_DEFPATH" is undefined
def_path = _PATH_DEFPATH;
^
3 errors detected in the compilation of "main.c".
*** Error exit code 2
Stop.
I repeat the if 0
trick in main.c
and it works, only these remain:
$ make
cc -DEMACS -DVI -w -c main.c
"main.c", line 113: error #2020: identifier "MAXLOGNAME" is undefined
char username[_PW_NAME_LEN + 1];
^
"main.c", line 204: error #2020: identifier "_PATH_DEFPATH" is undefined
def_path = _PATH_DEFPATH;
^
2 errors detected in the compilation of "main.c".
*** Error exit code 2
Stop.
_PW_NAME_LEN
is the maximum length of a valid username on HP-UX. Do you happen to know what that is?
_PATH_DEFPATH
is your default $PATH
. Whatever echo $PATH
is when you log in should suffice here.
Also can you check to see if you have any of the defines here: https://github.com/ibara/oksh/blob/master/portable.h#L49 That may also shed some light on what to do for HP-UX.
_PW_NAME_LEN
is the maximum length of a valid username on HP-UX. Do you happen to know what that is?
By default, only 8 characters are allowed as maximum length for usernames. However, on this particular system, the maximum allowed length has been raised with lugadmin
to 256 characters. (We use a buildslave
username everywhere.)
_PATH_DEFPATH
is your default$PATH
. Whateverecho $PATH
is when you log in should suffice here.
Sorry, you'll have to spell it out for me, I'm not into C programming.
Also can you check to see if you have any of the defines here: https://github.com/ibara/oksh/blob/master/portable.h#L49 That may also shed some light on what to do for HP-UX.
Sorry, don't know how to check for that.
Also, forgot to say above that the default path for a regular HP-UX user seems to be:
/usr/bin:/usr/ccs/bin:/usr/contrib/bin:/usr/contrib/Q4/bin:/opt/perl/bin:/opt/gvsd/bin:/opt/ipf/bin:/opt/nettladm/bin:/opt/fcms/bin:/opt/wbem/bin:/opt/wbem/sbin:/opt/sas/bin:/opt/wli/bin:/opt/graphics/common/bin:/opt/hpvm/bin:/opt/atok/bin:/usr/bin/X11:/usr/contrib/bin/X11:/opt/sec_mgmt/bastille/bin:/opt/drd/bin:/opt/dsau/bin:/opt/dsau/sbin:/opt/resmon/bin:/opt/firefox:/usr/contrib/kwdb/bin:/opt/prm/bin:/opt/propplus/bin:/opt/caliper/bin:/opt/perl_32/bin:/opt/perl_64/bin:/opt/sfm/bin:/opt/swm/bin:/opt/sec_mgmt/spc/bin:/opt/ssh/bin:/opt/swa/bin:/opt/hpsmh/bin:/opt/thunderbird:/opt/sentinel/bin:/opt/langtools/bin:/opt/gwlm/bin:/opt/aCC/bin
No, it's not a joke. This is what a freshly added user has in the default shell with no home dir. If I use useradd -m
, the files from /etc/skel
are copied and the home dir gets appended to the path through .profile
.
All this should be taken with a grain of salt, I'm not really an HP-UX admin, even though I used to look after a couple of HP-UX servers for a while and still have access to start one of them if needed.
That's... a lot. Let's try this:
In portable.h
, at line 55, can you add the following:
#elif defined(__hpux)
#define _PW_NAME_LEN 8
Then at line 93:
#if defined(__hpux)
#define _PATH_DEFPATH "/usr/bin:/usr/ccs/bin:/usr/contrib/bin"
#endif
Thanks! The above solves previous errors, build continues to:
$ make
cc -DEMACS -DVI -w -c main.c
cc -DEMACS -DVI -w -c misc.c
cc -DEMACS -DVI -w -c path.c
cc -DEMACS -DVI -w -c shf.c
cc -DEMACS -DVI -w -c syn.c
cc -DEMACS -DVI -w -c table.c
cc -DEMACS -DVI -w -c trap.c
cc -DEMACS -DVI -w -c tree.c
cc -DEMACS -DVI -w -c tty.c
cc -DEMACS -DVI -w -c var.c
"/usr/include/term.h", line 55: error #2084: invalid combination of type
specifiers
typedef char bool;
^
1 error detected in the compilation of "var.c".
*** Error exit code 2
Stop.
Ah! I suspect we are very close.
This looks like a problem with the version of curses installed on your system. Maybe it's an old pre-C99 version of curses. Can you run ./configure --disable-curses
and continue building? That should get things moving again. You'll lose the ability to clear the screen with ^L
but we can find a way to add that back later.
True, build is successful if using ./configure --disable-curses
.
However, running the resulting binary gives:
$ ./oksh
Bus error (core dumped)
That's a bummer. Do you have a version of gcc installed? Can you try that? Any version of gcc should do.
The system has this package installed with depothelper
: http://hpux.connect.org.uk/hppd/hpux/Gnu/gcc-4.2.3/.
Have tried the same patched tree with similar options, but compilation bailes out early on:
bash-4.4$ which gcc
/usr/local/bin/gcc
bash-4.4$ gcc -v
Using built-in specs.
Target: ia64-hp-hpux11.31
Configured with: ../gcc/configure
Thread model: posix
gcc version 4.2.3
bash-4.4$ CC=gcc ./configure --disable-curses
checking for C compiler... gcc
checking if C compiler can compile C99 without -std=c99... yes
checking for -w compiler flag... yes
checking for OS... HP-UX
checking for __dead... no
checking for __dead2... no
checking for asprintf... no
checking for confstr... yes
checking for curses library... disabled by user
oksh will be built without screen clearing support
checking for issetugid... no
checking for pledge... no
checking for reallocarray... no
checking for setresgid... yes
checking for setresuid... yes
checking for sig_t... no
checking for srand_deterministic... no
checking for st_mtim... no
checking for st_mtimespec... no
checking for stravis... no
checking for strlcat... no
checking for strlcpy... no
checking for strtonum... no
checking for strunvis... no
checking for sys_siglist... no
checking for sys_signame... no
checking for timeradd... no
checking for timersub... no
creating Makefile... done
bash-4.4$ CC=gcc gmake
gcc -DEMACS -DVI -w -c -o edit.o edit.c
edit.c: In function 'x_mode':
edit.c:183: error: 'VDISCARD' undeclared (first use in this function)
edit.c:183: error: (Each undeclared identifier is reported only once
edit.c:183: error: for each function it appears in.)
gmake: *** [<builtin>: edit.o] Error 1
Remove that line from edit.c
Actually, that line was supposed to be #ifndef __hpux__
, but that didn't work with the default compiler, so at the time I did the quick and dirty hack to change it to #ifdef __hpux__
.
Apparently, with gcc
it does work, so I put #ifndef __hpux__
back. This got me to:
$ gmake
gcc -DEMACS -DVI -w -c -o edit.o edit.c
gcc -DEMACS -DVI -w -c -o emacs.o emacs.c
gcc -DEMACS -DVI -w -c -o eval.o eval.c
gcc -DEMACS -DVI -w -c -o exec.o exec.c
gcc -DEMACS -DVI -w -c -o expr.o expr.c
gcc -DEMACS -DVI -w -c -o history.o history.c
gcc -DEMACS -DVI -w -c -o io.o io.c
gcc -DEMACS -DVI -w -c -o jobs.o jobs.c
gcc -DEMACS -DVI -w -c -o lex.o lex.c
gcc -DEMACS -DVI -w -c -o mail.o mail.c
gcc -DEMACS -DVI -w -c -o main.o main.c
gcc -DEMACS -DVI -w -c -o misc.o misc.c
gcc -DEMACS -DVI -w -c -o path.o path.c
gcc -DEMACS -DVI -w -c -o shf.o shf.c
gcc -DEMACS -DVI -w -c -o syn.o syn.c
gcc -DEMACS -DVI -w -c -o table.o table.c
gcc -DEMACS -DVI -w -c -o trap.o trap.c
gcc -DEMACS -DVI -w -c -o tree.o tree.c
gcc -DEMACS -DVI -w -c -o tty.o tty.c
gcc -DEMACS -DVI -w -c -o var.o var.c
gcc -DEMACS -DVI -w -c -o version.o version.c
gcc -DEMACS -DVI -w -c -o vi.o vi.c
gcc -DEMACS -DVI -w -c -o confstr.o confstr.c
gcc -DEMACS -DVI -w -c -o reallocarray.o reallocarray.c
gcc -DEMACS -DVI -w -c -o siglist.o siglist.c
gcc -DEMACS -DVI -w -c -o signame.o signame.c
gcc -DEMACS -DVI -w -c -o strlcat.o strlcat.c
gcc -DEMACS -DVI -w -c -o strlcpy.o strlcpy.c
gcc -DEMACS -DVI -w -c -o strtonum.o strtonum.c
strtonum.c: In function 'strtonum':
strtonum.c:57: error: 'LLONG_MIN' undeclared (first use in this function)
strtonum.c:57: error: (Each undeclared identifier is reported only once
strtonum.c:57: error: for each function it appears in.)
strtonum.c:59: error: 'LLONG_MAX' undeclared (first use in this function)
gmake: *** [<builtin>: strtonum.o] Error 1
Ah, that means my configure check for needing -std=c99 is slightly off. I check for long long
support but not for the C99 preprocessor definitions of LLONG_MAX
and LLONG_MIN
.
In any event, that's a real easy fix, so easy I will add it to the file directly. For now, add the following lines in strtonum.c
underneath the TOOLARGE define:
#ifndef LLONG_MAX
#define LLONG_MAX 0x7fffffffffffffffLL
#endif
#ifndef LLONG_MIN
#define LLONG_MIN (-0x7fffffffffffffffLL-1)
#endif
You could also do without the macros:
error = INVALID;
- else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
+ else if ((errno == ERANGE && ll < 0) || ll < minval)
error = TOOSMALL;
- else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
+ else if ((errno == ERANGE && ll > 0) || ll > maxval)
error = TOOLARGE;
I'd prefer not to. If you want to see changes in these files, send them to the OpenBSD tech@ mailing list.
There is no much sense to add this change to OpenBSD source code since LLONG_MIN and LLONG_MAX are always defined there. I thought this change would be cleaner than explicitly defining those macros since that way we don't assume long long to always have 64 bits.
How many 128-bit long long platforms are out there?
Your change also subtly violates the expected return values for strtoll on overflow or underflow. oksh is C99 and so we can and should expect that. Support for non-conforming platforms should be only in the most minimal, non-invasive of approaches.
If there are any 128-bit long long platforms out there and they're not C99 compliant, they're probably not worth supporting.
C99 compliant strtoll sets errno to ERANGE only when it returns LLONG_MIN or LLONG_MAX. One of those values is positive and one is negative. So the code would remain equivalent, but would not need those macros defined. But you are right in that very few platforms, if any, have long long of size other than 64.
Ah, that means my configure check for needing -std=c99 is slightly off. I check for
long long
support but not for the C99 preprocessor definitions ofLLONG_MAX
andLLONG_MIN
.In any event, that's a real easy fix, so easy I will add it to the file directly. For now, add the following lines in
strtonum.c
underneath the TOOLARGE define:#ifndef LLONG_MAX #define LLONG_MAX 0x7fffffffffffffffLL #endif #ifndef LLONG_MIN #define LLONG_MIN (-0x7fffffffffffffffLL-1) #endif
This worked. Build is successful now:
bash-4.4$ gmake
gcc -DEMACS -DVI -w -c -o strtonum.o strtonum.c
gcc -DEMACS -DVI -w -c -o unvis.o unvis.c
gcc -DEMACS -DVI -w -c -o vis.o vis.c
gcc -o oksh alloc.o asprintf.o c_ksh.o c_sh.o c_test.o c_ulimit.o edit.o emacs.o eval.o exec.o expr.o history.o io.o jobs.o lex.o mail.o main.o misc.o path.o shf.o syn.o table.o trap.o tree.o tty.o var.o version.o vi.o confstr.o reallocarray.o siglist.o signame.o strlcat.o strlcpy.o strtonum.o unvis.o vis.o
Unfortunately, the resulting binary seems to have the same issue as the one produced by the native compiler:
bash-4.4$ ./oksh
Bus error (core dumped)
Any more ideas to try?
I don't. At least, not with access to the machine. Could you make a tarball of the oksh code you have, with all of the changes we've made, so I can at least keep HP-UX in a buildable shape in case I ever do get access to such a machine and can make the runtime fixes?