Closed NattyNarwhal closed 6 years ago
Looks like AIX needs BSD queuing? Try changing:
#if defined(__linux__)
to
#if defined(__linux__) || defined(_AIX)
in portable.h
line 182.
Yes, that was obvious in retrospect, silly me :)
now:
gcc -DEMACS -DVI -w -c -o expr.o expr.c
In file included from portable.h:21:0,
from config.h:28,
from sh.h:9,
from expr.c:14:
expr.c:42:17: error: expected identifier before '(' token
VAR, LIT, END, BAD
^
gmake: *** [<builtin>: expr.o] Error 1
those tokens are so simple looking something's bound to be conflicting...
warmer...
gcc -DEMACS -DVI -w -c -o history.o history.c
history.c: In function 'histsave':
history.c:667:16: error: 'LOCK_EX' undeclared (first use in this function)
history_lock(LOCK_EX);
^~~~~~~
history.c:667:16: note: each undeclared identifier is reported only once for each function it appears in
In file included from config.h:28:0,
from sh.h:9,
from history.c:25:
history.c:669:23: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:111:12: note: in definition of macro 'timespeccmp'
(((tsp)->tv_sec == (usp)->tv_sec) ? \
^~~
history.c:669:41: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:111:29: note: in definition of macro 'timespeccmp'
(((tsp)->tv_sec == (usp)->tv_sec) ? \
^~~
history.c:669:23: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:112:15: note: in definition of macro 'timespeccmp'
((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
^~~
history.c:669:41: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:112:34: note: in definition of macro 'timespeccmp'
((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
^~~
history.c:669:23: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:113:15: note: in definition of macro 'timespeccmp'
((tsp)->tv_sec cmp (usp)->tv_sec))
^~~
history.c:669:41: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:113:33: note: in definition of macro 'timespeccmp'
((tsp)->tv_sec cmp (usp)->tv_sec))
^~~
history.c:702:16: error: 'LOCK_UN' undeclared (first use in this function)
history_lock(LOCK_UN);
^~~~~~~
history.c: In function 'hist_init':
history.c:822:15: error: 'LOCK_UN' undeclared (first use in this function)
history_lock(LOCK_UN);
^~~~~~~
gmake: *** [<builtin>: history.o] Error 1
So it looks like
flock issue is simple; flock lives in sys/file.c
instead
AIX struct stat doesn't have a timespec which complicates a function in history.c
? Looks like -DSMALL
can make it something we don't need to deal with, but is that wise?
if I do set that, it'll work, but then
gcc -DSMALL -DEMACS -DVI -w -c -o io.o io.c
io.c: In function 'savefd':
io.c:262:19: error: 'F_DUPFD_CLOEXEC' undeclared (first use in this function)
nfd = fcntl(fd, F_DUPFD_CLOEXEC, FDBASE);
^~~~~~~~~~~~~~~
io.c:262:19: note: each undeclared identifier is reported only once for each function it appears in
are the semantics on OpenBSD at least, close enough that it could be aliased to F_DUPFD
?
Looking at the OpenBSD diff.... yes, but with small surgery to io.c
. I don't think that'd be acceptable though?
Now it compiles, with some hacks later:
diff --git a/configure b/configure
index 592ca6e..1efd2e6 100755
--- a/configure
+++ b/configure
@@ -409,6 +409,10 @@ if [ "x$os" = "xLinux" ] ; then
elif [ "x$os" = "xNetBSD" ] ; then
tflags="-D_OPENBSD_SOURCE"
cflags="$cflags $tflags"
+elif [ "x$os" = "xAIX" ] ; then
+# AIX doesn't have timespec in stat, but SMALL lets us not do that
+ cflags="$cflags -DSMALL"
+ ldflags="$ldflags -lbsd"
else
tflags=""
fi
diff --git a/io.c b/io.c
index 5d8f156..3902451 100644
--- a/io.c
+++ b/io.c
@@ -259,7 +259,7 @@ savefd(int fd)
int nfd;
if (fd < FDBASE) {
- nfd = fcntl(fd, F_DUPFD_CLOEXEC, FDBASE);
+ nfd = fcntl(fd, F_DUPFD, FDBASE);
if (nfd < 0) {
if (errno == EBADF)
return -1;
@@ -270,6 +270,7 @@ savefd(int fd)
nfd = fd;
fcntl(nfd, F_SETFD, FD_CLOEXEC);
}
+ fcntl(nfd, F_SETFD, FD_CLOEXEC);
return nfd;
}
diff --git a/portable.h b/portable.h
index 7781376..be77fff 100644
--- a/portable.h
+++ b/portable.h
@@ -123,6 +123,54 @@
} while (0)
#endif /* !__OpenBSD__ */
+#ifdef _AIX
+/* AIX doesn't have this */
+typedef void (*sig_t)(int);
+
+/* IBM cheaped out on vowels */
+#define VWERASE VWERSE
+#define VDISCARD VDISCRD
+
+/* what the hell defines this? */
+#undef BAD
+
+/* flock isn't where you expect */
+#include <sys/file.h>
+
+/* AIX doesn't have this either */
+#define MAXLOGNAME LOGIN_NAME_MAX
+
+/* or this, but we can approximate it? */
+#define _PATH_DEFPATH "/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
+
+/* terrible idea */
+#define asprintf sprintf
+
+/* copy OpenBSD's WCOREDUMP def here */
+#define WCOREFLAG 0200
+#define WCOREDUMP(x) ((x) & WCOREFLAG)
+
+/* import timeadd/sub funcs from OpenBSD sys/time.h */
+#define timeradd(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
+ if ((vvp)->tv_usec >= 1000000) { \
+ (vvp)->tv_sec++; \
+ (vvp)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+#define timersub(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
+
/*
* Prototypes
*/
@@ -179,7 +227,7 @@ extern const char *const sys_signame[NSIG];
/* The following should only be necessary on non-BSD systems. */
-#if defined(__linux__)
+#if defined(__linux__) || defined(_AIX)
/* $OpenBSD: queue.h,v 1.38 2013/07/03 15:05:21 fgsch Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
diff --git a/tty.c b/tty.c
index 648bdb7..89be883 100644
--- a/tty.c
+++ b/tty.c
@@ -49,9 +49,14 @@ tty_init(int init_ttystate)
return;
}
}
- if ((tty_fd = fcntl(tfd, F_DUPFD_CLOEXEC, FDBASE)) < 0) {
+ if ((tty_fd = fcntl(tfd, F_DUPFD, FDBASE)) < 0) {
warningf(false, "j_ttyinit: dup of tty fd failed: %s",
strerror(errno));
+ } else if (fcntl(tty_fd, F_SETFD, FD_CLOEXEC) < 0) {
+ warningf(false, "j_ttyinit: can't set close-on-exec flag: %s",
+ strerror(errno));
+ close(tty_fd);
+ tty_fd = -1;
} else if (init_ttystate)
tcgetattr(tty_fd, &tty_state);
if (do_close)
well, it's not entirely stable:
(gdb) run
Starting program: /home/calvin/oksh/oksh
aix$ cat CO<tab>
Program received signal SIGSEGV, Segmentation fault.
0x10025f00 in skip_varname ()
(gdb) bt
#0 0x10025f00 in skip_varname ()
#1 0x10023be0 in array_index_calc ()
#2 0x10023da8 in global ()
#3 0x1003a3c4 in x_try_array ()
#4 0x1003a758 in x_cf_glob ()
#5 0x10036dfc in do_complete ()
#6 0x10036b88 in x_comp_list ()
#7 0x10031e10 in x_emacs ()
#8 0x10038580 in x_read ()
#9 0x1001e7f8 in getsc_line ()
#10 0x1001e2d8 in getsc__ ()
#11 0x10020768 in getsc_bn ()
#12 0x1001ade0 in yylex ()
#13 0x10045908 in get_command ()
#14 0x10045064 in pipeline ()
#15 0x100451d0 in andor ()
#16 0x10045304 in c_list ()
#17 0x10044f5c in yyparse ()
#18 0x10047a2c in compile ()
#19 0x10001b18 in shell ()
#20 0x100013ec in main ()
Definitely don't set -DSMALL for the final diff. That won't do what you want. Let me look this over. I have some ideas.
FWIW, a better gdb session output with -g -O0
:
(gdb) run
Starting program: /home/calvin/oksh/oksh
aix$ cat CO
Program received signal SIGSEGV, Segmentation fault.
0x10025f00 in skip_varname (
s=0x636f6d70 <error: Cannot access memory at address 0x636f6d70>, aok=0)
at var.c:775
775 if (s && letter(*s)) {
(gdb) info locals
alen = 274877907
(gdb) bt
#0 0x10025f00 in skip_varname (
s=0x636f6d70 <error: Cannot access memory at address 0x636f6d70>, aok=0)
at var.c:775
#1 0x10023be0 in array_index_calc (
n=0x636f6d70 <error: Cannot access memory at address 0x636f6d70>,
arrayp=0x2ff20f4c, valp=0x2ff20f50) at var.c:136
#2 0x10023da8 in global (
n=0x636f6d70 <error: Cannot access memory at address 0x636f6d70>)
at var.c:171
#3 0x1003a3c4 in x_try_array (buf=0x2000f910 "cat CO", buflen=6,
want=0x2000f914 "CO", wantlen=2, nwords=0x2ff2102c, words=0x2ff21030)
at edit.c:620
#4 0x1003a758 in x_cf_glob (flags=3, buf=0x2000f910 "cat CO", buflen=6,
pos=6, startp=0x2ff2109c, endp=0x2ff210a0, wordsp=0x2ff21098,
is_commandp=0x2ff210a4) at edit.c:677
#5 0x10036dfc in do_complete (flags=3, type=CT_COMPLIST) at emacs.c:1721
#6 0x10036b88 in x_comp_list (c=9) at emacs.c:1676
#7 0x10031e10 in x_emacs (buf=0x2000f910 "cat CO", len=4096) at emacs.c:356
#8 0x10038580 in x_read (buf=0x2000f910 "cat CO", len=4096) at edit.c:102
#9 0x1001e7f8 in getsc_line (s=0x2000e010) at lex.c:1099
#10 0x1001e2d8 in getsc__ () at lex.c:988
#11 0x10020768 in getsc_bn () at lex.c:1633
#12 0x1001ade0 in yylex (cf=44) at lex.c:167
#13 0x10045908 in get_command (cf=0) at syn.c:206
#14 0x10045064 in pipeline (cf=0) at syn.c:77
#15 0x100451d0 in andor () at syn.c:98
#16 0x10045304 in c_list (multi=0) at syn.c:118
#17 0x10044f5c in yyparse () at syn.c:64
#18 0x10047a2c in compile (s=0x2000e010) at syn.c:763
#19 0x10001b18 in shell (s=0x2000e010, toplevel=1) at main.c:607
#20 0x100013ec in main (argc=1, argv=0x2ff22c60) at main.c:434
/usr/include/sys/param.h: #define BAD (-1)
@NattyNarwhal I took some of the changes you made for this porting effort and spun them out because they will apply to multiple potential port targets. See PR #18. I have an AIX branch on my fork, https://github.com/tssva/oksh, which then also integrates the more AIX specific changes you made. There are a couple of differences to what you tried earlier. The first is that I brought in an implementation of asprintf as part of PR #18 so it is no longer defined as sprintf. Also the AIX version of <sys/time.h> does have an implementation of timespec, but _XOPEN_SOURCE must be set >= 500 for it to be used. I have set -D_XOPEN_SOURCE=500
as a CFLAG in the configure script, so setting -DSMALL
should hopefully not be necessary.
The thing is I don't actually have access to an AIX machine. If you could give it a go and see if it fairs any better I would appreciate it.
@tssva I tried your repo's AIX branch; can't compile as I get a really long string of errors with gcc6:
checking for C compiler... gcc
checking for -w compiler flag... yes
checking for OS... AIX
checking for __dead... no
checking for __dead2... no
checking for asprintf... no
checking for confstr... yes
checking for pledge... no
checking for reallocarray... no
checking for setresgid... no
checking for setresuid... no
checking for sig_t... no
checking for srand_deterministic... 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
gcc -DEMACS -DVI -w -D_BSD=44 -D_XOPEN_SOURCE=500 -c -o alloc.o alloc.c
In file included from config.h:28:0,
from sh.h:9,
from alloc.c:12:
portable.h: In function 'asprintf':
portable.h:210:26: error: storage class specified for parameter 'sys_siglist'
extern const char *const sys_siglist[NSIG];
^~~~~~~~~~~
portable.h:213:26: error: storage class specified for parameter 'sys_signame'
extern const char *const sys_signame[NSIG];
^~~~~~~~~~~
portable.h:222:16: error: storage class specified for parameter 'sig_t'
typedef void (*sig_t)(int);
^~~~~
In file included from sh.h:14:0,
from alloc.c:12:
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include-fixed/setjmp.h:64:17: error: storage class specified for parameter 'jmp_buf'
typedef __MTYPE jmp_buf[_JBLEN];
^~~~~~~
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include-fixed/setjmp.h:82:30: error: expected ')' before 'int'
extern void longjmp(jmp_buf, int);
^~~
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include-fixed/setjmp.h:83:12: error: storage class specified for parameter 'setjmp'
extern int setjmp(jmp_buf);
^~~~~~
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include-fixed/setjmp.h:97:17: error: storage class specified for parameter 'sigjmp_buf'
typedef __MTYPE sigjmp_buf[_JBLEN];
^~~~~~~~~~
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include-fixed/setjmp.h:107:34: error: expected ')' before 'int'
extern int sigsetjmp(sigjmp_buf, int);
^~~
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include-fixed/setjmp.h:108:36: error: expected ')' before 'int'
extern void siglongjmp(sigjmp_buf, int);
^~~
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include-fixed/setjmp.h:110:12: error: storage class specified for parameter '_setjmp'
extern int _setjmp(jmp_buf);
^~~~~~~
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include-fixed/setjmp.h:111:31: error: expected ')' before 'int'
extern void _longjmp(jmp_buf, int);
^~~
In file included from sh.h:15:0,
from alloc.c:12:
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include/stdarg.h:40:27: error: storage class specified for parameter '__gnuc_va_list'
typedef __builtin_va_list __gnuc_va_list;
^~~~~~~~~~~~~~
In file included from sh.h:15:0,
from alloc.c:12:
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include/stdarg.h:99:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'va_list'
typedef __gnuc_va_list va_list;
^~~~~~~
In file included from sh.h:16:0,
from alloc.c:12:
/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/6.4.0/include/stddef.h:429:3: error: storage class specified for parameter 'max_align_t'
} max_align_t;
^~~~~~~~~~~
In file included from alloc.c:12:0:
sh.h:39:20: error: storage class specified for parameter 'kshname'
extern const char *kshname; /* $0 */
^~~~~~~
sh.h:40:14: error: storage class specified for parameter 'kshpid'
extern pid_t kshpid; /* $$, shell pid */
^~~~~~
sh.h:41:14: error: storage class specified for parameter 'procpid'
extern pid_t procpid; /* pid of executing process */
^~~~~~~
sh.h:42:14: error: storage class specified for parameter 'ksheuid'
extern uid_t ksheuid; /* effective uid of shell */
^~~~~~~
sh.h:43:12: error: storage class specified for parameter 'exstat'
extern int exstat; /* exit status */
^~~~~~
sh.h:44:12: error: storage class specified for parameter 'subst_exstat'
extern int subst_exstat; /* exit status of last $(..)/`..` */
^~~~~~~~~~~~
sh.h:45:20: error: storage class specified for parameter 'safe_prompt'
extern const char *safe_prompt; /* safe prompt if PS1 substitution fails */
^~~~~~~~~~~
sh.h:46:13: error: storage class specified for parameter 'username'
extern char username[]; /* username for \u prompt expansion */
^~~~~~~~
sh.h:53:3: error: storage class specified for parameter 'Area'
} Area;
^~~~
sh.h:55:13: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'aperm'
extern Area aperm; /* permanent object space */
^~~~~
sh.h:75:2: error: expected specifier-qualifier-list before 'Area'
Area area; /* temporary allocation area */
^~~~
sh.h:82:20: error: storage class specified for parameter 'genv'
extern struct env *genv;
^~~~
sh.h:128:28: error: storage class specified for parameter 'sh_options'
extern const struct option sh_options[];
^~~~~~~~~~
sh.h:181:13: error: storage class specified for parameter 'shell_flags'
extern char shell_flags[FNFLAGS];
^~~~~~~~~~~
sh.h:183:13: error: storage class specified for parameter 'null'
extern char null[]; /* null value for variable */
^~~~
sh.h:189:24: error: storage class specified for parameter 'Temp_type'
typedef enum temp_type Temp_type;
^~~~~~~~~
sh.h:195:2: error: expected specifier-qualifier-list before 'Temp_type'
Temp_type type;
^~~~~~~~~
sh.h:206:12: error: storage class specified for parameter 'shl_stdout_ok'
extern int shl_stdout_ok;
^~~~~~~~~~~~~
sh.h:218:2: error: expected specifier-qualifier-list before 'sig_t'
sig_t cursig; /* current handler (valid if TF_ORIG_* set) */
^~~~~
sh.h:220:3: error: storage class specified for parameter 'Trap'
} Trap;
^~~~
sh.h:247:30: error: storage class specified for parameter 'trap'
extern volatile sig_atomic_t trap; /* traps pending? */
^~~~
sh.h:248:30: error: storage class specified for parameter 'intrsig'
extern volatile sig_atomic_t intrsig; /* pending trap interrupts command */
^~~~~~~
sh.h:249:30: error: storage class specified for parameter 'fatal_trap'
extern volatile sig_atomic_t fatal_trap; /* received a fatal signal */
^~~~~~~~~~
sh.h:250:30: error: storage class specified for parameter 'got_sigwinch'
extern volatile sig_atomic_t got_sigwinch;
^~~~~~~~~~~~
sh.h:251:13: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'sigtraps'
extern Trap sigtraps[NSIG+1];
^~~~~~~~
sh.h:262:21: error: storage class specified for parameter 'ksh_tmout'
extern unsigned int ksh_tmout;
^~~~~~~~~
sh.h:263:24: error: storage class specified for parameter 'ksh_tmout_state'
extern enum tmout_enum ksh_tmout_state;
^~~~~~~~~~~~~~~
sh.h:266:12: error: storage class specified for parameter 'really_exit'
extern int really_exit;
^~~~~~~~~~~
sh.h:281:14: error: storage class specified for parameter 'ctypes'
extern short ctypes [];
^~~~~~
sh.h:288:12: error: storage class specified for parameter 'ifs0'
extern int ifs0; /* for "$*" */
^~~~
sh.h:310:3: error: storage class specified for parameter 'Getopt'
} Getopt;
^~~~~~
sh.h:312:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'builtin_opt'
extern Getopt builtin_opt; /* for shell builtin commands */
^~~~~~~~~~~
sh.h:313:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'user_opt'
extern Getopt user_opt; /* parsing state for getopts builtin command */
^~~~~~~~
sh.h:317:13: error: storage class specified for parameter 'Coproc_id'
typedef int Coproc_id; /* something that won't (realistically) wrap */
^~~~~~~~~
sh.h:322:2: error: expected specifier-qualifier-list before 'Coproc_id'
Coproc_id id; /* id of current output pipe */
^~~~~~~~~
sh.h:326:22: error: storage class specified for parameter 'coproc'
extern struct coproc coproc;
^~~~~~
sh.h:329:18: error: storage class specified for parameter 'sm_default'
extern sigset_t sm_default, sm_sigchld;
^~~~~~~~~~
sh.h:329:30: error: storage class specified for parameter 'sm_sigchld'
extern sigset_t sm_default, sm_sigchld;
^~~~~~~~~~
sh.h:331:19: error: storage class specified for parameter 'ksh_version'
extern const char ksh_version[];
^~~~~~~~~~~
sh.h:334:14: error: storage class specified for parameter 'builtin_argv0'
extern char *builtin_argv0;
^~~~~~~~~~~~~
sh.h:335:12: error: storage class specified for parameter 'builtin_flag'
extern int builtin_flag; /* flags of called builtin (SPEC_BI, etc.) */
^~~~~~~~~~~~
sh.h:338:14: error: storage class specified for parameter 'current_wd'
extern char *current_wd;
^~~~~~~~~~
sh.h:339:12: error: storage class specified for parameter 'current_wd_size'
extern int current_wd_size;
^~~~~~~~~~~~~~~
sh.h:348:12: error: storage class specified for parameter 'x_cols'
extern int x_cols; /* tty columns */
^~~~~~
In file included from sh.h:366:0,
from alloc.c:12:
shf.h:54:2: error: expected specifier-qualifier-list before 'Area'
Area *areap; /* area shf/buf were allocated in */
^~~~
shf.h:57:19: error: storage class specified for parameter 'shf_iob'
extern struct shf shf_iob[];
^~~~~~~
shf.h:77:50: error: unknown type name 'va_list'
int shf_vfprintf(struct shf *, const char *, va_list);
^~~~~~~
In file included from sh.h:367:0,
from alloc.c:12:
table.h:10:2: error: expected specifier-qualifier-list before 'Area'
Area *areap; /* area to allocate entries */
^~~~
table.h:19:2: error: expected specifier-qualifier-list before 'Area'
Area *areap; /* area to allocate from */
^~~~
table.h:111:2: error: expected specifier-qualifier-list before 'Area'
Area area; /* area to allocate things */
^~~~
table.h:139:21: error: storage class specified for parameter 'taliases'
extern struct table taliases; /* tracked aliases */
^~~~~~~~
table.h:140:21: error: storage class specified for parameter 'builtins'
extern struct table builtins; /* built-in commands */
^~~~~~~~
table.h:141:21: error: storage class specified for parameter 'aliases'
extern struct table aliases; /* aliases */
^~~~~~~
table.h:142:21: error: storage class specified for parameter 'keywords'
extern struct table keywords; /* keywords */
^~~~~~~~
table.h:143:21: error: storage class specified for parameter 'homedirs'
extern struct table homedirs; /* homedir() cache */
^~~~~~~~
table.h:151:29: error: storage class specified for parameter 'shbuiltins'
extern const struct builtin shbuiltins [], kshbuiltins [];
^~~~~~~~~~
table.h:151:44: error: storage class specified for parameter 'kshbuiltins'
extern const struct builtin shbuiltins [], kshbuiltins [];
^~~~~~~~~~~
table.h:178:14: error: storage class specified for parameter 'search_path'
extern char *search_path; /* copy of either PATH or def_path */
^~~~~~~~~~~
table.h:179:20: error: storage class specified for parameter 'def_path'
extern const char *def_path; /* path to use if PATH not set */
^~~~~~~~
table.h:180:14: error: storage class specified for parameter 'tmpdir'
extern char *tmpdir; /* TMPDIR value */
^~~~~~
table.h:181:20: error: storage class specified for parameter 'prompt'
extern const char *prompt;
^~~~~~
table.h:182:12: error: storage class specified for parameter 'cur_prompt'
extern int cur_prompt; /* PS1 or PS2 */
^~~~~~~~~~
table.h:183:12: error: storage class specified for parameter 'current_lineno'
extern int current_lineno; /* LINENO value */
^~~~~~~~~~~~~~
table.h:186:30: error: expected declaration specifiers or '...' before 'Area'
void ktinit(struct table *, Area *, int);
^~~~
In file included from sh.h:368:0,
from alloc.c:12:
tree.h:141:32: error: expected declaration specifiers or '...' before 'Area'
struct op * tcopy(struct op *, Area *);
^~~~
tree.h:142:29: error: expected declaration specifiers or '...' before 'Area'
char * wdcopy(const char *, Area *);
^~~~
tree.h:145:25: error: expected declaration specifiers or '...' before 'Area'
void tfree(struct op *, Area *);
^~~~
In file included from sh.h:369:0,
from alloc.c:12:
expand.h:30:2: error: expected specifier-qualifier-list before 'Area'
Area *areap; /* area to allocate/free from */
^~~~
expand.h:31:3: error: storage class specified for parameter 'XString'
} XString;
^~~~~~~
expand.h:33:16: error: storage class specified for parameter 'XStringP'
typedef char * XStringP;
^~~~~~~~
expand.h:71:21: error: expected declaration specifiers or '...' before 'XString'
char * Xcheck_grow_(XString *xsp, char *xp, size_t more);
^~~~~~~
expand.h:80:3: error: storage class specified for parameter 'XPtrV'
} XPtrV;
^~~~~
In file included from sh.h:370:0,
from alloc.c:12:
lex.h:11:23: error: storage class specified for parameter 'Source'
typedef struct source Source;
^~~~~~
lex.h:29:2: error: expected specifier-qualifier-list before 'Area'
Area *areap;
^~~~
lex.h:57:3: error: storage class specified for parameter 'YYSTYPE'
} YYSTYPE;
^~~~~~~
lex.h:103:16: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
extern Source *source; /* yyparse/yylex source */
^
lex.h:104:16: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'yylval'
extern YYSTYPE yylval; /* result from yylex */
^~~~~~
lex.h:105:23: error: storage class specified for parameter 'heres'
extern struct ioword *heres[HERES], **herep;
^~~~~
lex.h:105:39: error: storage class specified for parameter 'herep'
extern struct ioword *heres[HERES], **herep;
^~~~~
lex.h:106:13: error: storage class specified for parameter 'ident'
extern char ident[IDENT+1];
^~~~~
lex.h:110:17: error: storage class specified for parameter 'history'
extern char **history; /* saved commands */
^~~~~~~
lex.h:111:17: error: storage class specified for parameter 'histptr'
extern char **histptr; /* last history item */
^~~~~~~
lex.h:112:17: error: storage class specified for parameter 'histsize'
extern uint32_t histsize; /* history size */
^~~~~~~~
lex.h:117:1: error: expected declaration specifiers before 'Source'
Source * pushs(int, Area *);
^~~~~~
In file included from alloc.c:12:0:
sh.h:373:1: error: expected declaration specifiers before 'Area'
Area * ainit(Area *);
^~~~
sh.h:374:15: error: expected declaration specifiers or '...' before 'Area'
void afreeall(Area *);
^~~~
sh.h:375:22: error: expected declaration specifiers or '...' before 'Area'
void * alloc(size_t, Area *);
^~~~
sh.h:376:46: error: expected declaration specifiers or '...' before 'Area'
void * areallocarray(void *, size_t, size_t, Area *);
^~~~
sh.h:377:32: error: expected declaration specifiers or '...' before 'Area'
void * aresize(void *, size_t, Area *);
^~~~
sh.h:378:20: error: expected declaration specifiers or '...' before 'Area'
void afree(void *, Area *);
^~~~
sh.h:429:21: error: expected declaration specifiers or '...' before 'XPtrV'
void expand(char *, XPtrV *, int);
^~~~~
sh.h:430:22: error: expected declaration specifiers or '...' before 'XPtrV'
int glob_str(char *, XPtrV *, int);
^~~~~
sh.h:448:16: error: expected declaration specifiers or '...' before 'Source'
void hist_init(Source *);
^~~~~~
sh.h:497:23: error: expected declaration specifiers or '...' before 'Area'
struct temp *maketemp(Area *, Temp_type, struct temp **);
^~~~
sh.h:497:31: error: expected declaration specifiers or '...' before 'Temp_type'
struct temp *maketemp(Area *, Temp_type, struct temp **);
^~~~~~~~~
sh.h:522:11: error: expected declaration specifiers or '...' before 'Source'
int shell(Source *volatile, int volatile);
^~~~~~
sh.h:532:31: error: expected declaration specifiers or '...' before 'Area'
char * str_save(const char *, Area *);
^~~~
sh.h:533:37: error: expected declaration specifiers or '...' before 'Area'
char * str_nsave(const char *, int, Area *);
^~~~
sh.h:546:23: error: expected declaration specifiers or '...' before 'Getopt'
void ksh_getopt_reset(Getopt *, int);
^~~~~~
sh.h:547:25: error: expected declaration specifiers or '...' before 'Getopt'
int ksh_getopt(char **, Getopt *, const char *);
^~~~~~
sh.h:556:52: error: expected declaration specifiers or '...' before 'XString'
int make_path(const char *, const char *, char **, XString *, int *);
^~~~~~~
sh.h:562:21: error: expected declaration specifiers or '...' before 'Source'
struct op * compile(Source *);
^~~~~~
sh.h:566:1: error: expected declaration specifiers before 'Trap'
Trap * gettrap(const char *, int);
^~~~
sh.h:572:14: error: expected declaration specifiers or '...' before 'Trap'
void runtrap(Trap *);
^~~~
sh.h:575:14: error: expected declaration specifiers or '...' before 'Trap'
void settrap(Trap *, char *);
^~~~
sh.h:578:12: error: expected declaration specifiers or '...' before 'Trap'
int setsig(Trap *, sig_t, int);
^~~~
sh.h:578:20: error: expected declaration specifiers or '...' before 'sig_t'
int setsig(Trap *, sig_t, int);
^~~~~
sh.h:579:17: error: expected declaration specifiers or '...' before 'Trap'
void setexecsig(Trap *, int);
^~~~
alloc.c:19:1: error: expected declaration specifiers before 'Area'
Area *
^~~~
alloc.c:27:10: error: expected declaration specifiers or '...' before 'Area'
afreeall(Area *ap)
^~~~
alloc.c:42:20: error: expected declaration specifiers or '...' before 'Area'
alloc(size_t size, Area *ap)
^~~~
alloc.c:71:53: error: expected declaration specifiers or '...' before 'Area'
areallocarray(void *ptr, size_t nmemb, size_t size, Area *ap)
^~~~
alloc.c:83:33: error: expected declaration specifiers or '...' before 'Area'
aresize(void *ptr, size_t size, Area *ap)
^~~~
alloc.c:112:18: error: expected declaration specifiers or '...' before 'Area'
afree(void *ptr, Area *ap)
^~~~
In file included from config.h:28:0,
from sh.h:9,
from alloc.c:12:
portable.h:168:5: error: old-style parameter declarations in prototyped function definition
int asprintf(char **str, const char *fmt, ...)
^~~~~~~~
alloc.c:128:1: error: expected '{' at end of input
}
^
gmake: *** [<builtin>: alloc.o] Error 1
That seems really fucky; if I apply gcc Kremlinology, I think this section of portable.c may be to blame? The declaration doesn't look right to me....
/*
* Externs
*/
#if !defined(HAVE_SIGLIST) || !defined(HAVE_SIGNAME)
#ifdef NSIG
#undef NSIG
#endif /* NSIG */
#define NSIG 33
#ifndef HAVE_SIGLIST
extern const char *const sys_siglist[NSIG];
#endif /* !HAVE_SIGLIST */
#ifndef HAVE_SIGNAME
extern const char *const sys_signame[NSIG];
#endif /* !HAVE_SIGNAME */
#endif /* !HAVE_SIGLIST || !HAVE_SIGNAME */
I seem to have committed an off by one character cut & paste error earlier in the file. I have corrected it. Hopefully you will get a little farther this time.
@tssva Re-cloned, works better after changing the configure flags for AIX to -D_ALL_SOURCE
, until I get to:
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o alloc.o alloc.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o asprintf.o asprintf.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o c_ksh.o c_ksh.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o c_sh.o c_sh.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o c_test.o c_test.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o c_ulimit.o c_ulimit.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o edit.o edit.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o emacs.o emacs.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o eval.o eval.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o exec.o exec.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o expr.o expr.c
gcc -DEMACS -DVI -w -D_ALL_SOURCE -c -o history.o history.c
In file included from config.h:28:0,
from sh.h:9,
from history.c:25:
history.c: In function 'histsave':
history.c:669:23: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:148:12: note: in definition of macro 'timespeccmp'
(((tsp)->tv_sec == (usp)->tv_sec) ? \
^~~
history.c:669:41: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:148:29: note: in definition of macro 'timespeccmp'
(((tsp)->tv_sec == (usp)->tv_sec) ? \
^~~
history.c:669:23: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:149:15: note: in definition of macro 'timespeccmp'
((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
^~~
history.c:669:41: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:149:34: note: in definition of macro 'timespeccmp'
((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
^~~
history.c:669:23: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:150:15: note: in definition of macro 'timespeccmp'
((tsp)->tv_sec cmp (usp)->tv_sec))
^~~
history.c:669:41: error: 'struct stat' has no member named 'st_mtim'; did you mean 'st_mtime'?
if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==))
^
portable.h:150:33: note: in definition of macro 'timespeccmp'
((tsp)->tv_sec cmp (usp)->tv_sec))
^~~
gmake: *** [<builtin>: history.o] Error 1
This is the same thing I had to use -DSMALL
to bypass.
(There's also a typo on io.c:278; SETD
-> SETFD
.)
Also a typo on your tty.c:66
; missing semicolon.
Also had to add to configure a flag for -lbsd
for flock. After that, it seems to work! I'll let you know about stability.
diff --git a/configure b/configure
index d474b1f..faf32ce 100755
--- a/configure
+++ b/configure
@@ -473,8 +473,9 @@ case "x$os" in
cflags="$cflags $tflags"
;;
"xAIX")
- tflags="-D_BSD=44 -D_XOPEN_SOURCE=500"
+ tflags="-D_ALL_SOURCE -DSMALL"
cflags="$cflags $tflags"
+ ldflags="$ldflags -lbsd"
;;
esac
diff --git a/io.c b/io.c
index 62d242b..0011e8f 100644
--- a/io.c
+++ b/io.c
@@ -275,7 +275,7 @@ savefd(int fd)
else
errorf("too many files open in shell");
}
- fcntl(nfd, F_SETD, FD_CLOEXEC);
+ fcntl(nfd, F_SETFD, FD_CLOEXEC);
#endif
} else {
nfd = fd;
diff --git a/tty.c b/tty.c
index 9aa3650..04d9b5c 100644
--- a/tty.c
+++ b/tty.c
@@ -61,7 +61,7 @@ tty_init(int init_ttystate)
warningf(false, "%s: set tty fd close-on-exec flag failed: %s",
__func__, strerror(errno));
close(tty_fd);
- tty_fd = -1
+ tty_fd = -1;
#endif
} else if (init_ttystate)
tcgetattr(tty_fd, &tty_state);
There's a NetBSD compat flock: http://bxr.su/NetBSD/tools/compat/flock.c Should we add it in?
Maybe if someone runs into a platform without it. AIX does have it, but it's in the included "BSD" (it's a SysV, so its idea of BSD is oooollllldddddd) compat library. Just a simple -lbsd
.
Oh I thought you meant you had to download the freedesktop.org libbsd.
Did some research based upon your last results and determined the "timespec" issue. timespec is defined but until AIX 7.1 the stat struct didn't include st_mtim, the last modification time as a timespec. st_mtim was added as a requirement in POSIX.1-2008.
There are many other legacy versions of unix systems for which this could be an issue. Looking around there are 4 ways systems seem to have handled this prior to POSIX.1-2008.
Based upon this there are 3 potential courses of action:
The potential downside with option 2 is that you eventually end up with a tangle of ifdefs and checks. I'm not sure how much of a risk that is in reality.
-DSMALL should never be used; it's really for the RAMDISK kernels.
Ok, I updated my branch. It now checks for st_mtim
and st_mtimespec
(used by macOS). If st_mtimespec
is found but st_mtim
is not it defines st_mtim
as st_mtimespec
. If neither is found it falls back to using st_mtime
by defining st_mtim
as st_mtime
and timespeccmp
as timespeccmp(tsp, usp, cmp) (tsp) cmp (usp)
.
If I delete HAVE_ST_MTIMESPEC from pconfig.h on my macbook it properly falls back to using st_mtime. That is as close as I can get to testing it here before you get a crack at it.
Yes, it seems to work fine out of the box now. I'd recommend you submit it as a PR!
Guess we should close this. Reopen if anything blows up on AIX.
God help me.
diff of
portable.h
current error
system