1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
* Fix job control bug in non-interactive scripts (closes: #296446)
Many thanks to Paul Stroud <pstroud@gmail.com> for the patch.
* lex.c: Don't expand aliases if there's an opening bracket just after
the token. Fixes unreported problem with pdksh reporting syntax error
on the init scripts that define function named `stop' (clashing
with an built-in alias.)
Index: pdksh-5.2.14/jobs.c
===================================================================
--- pdksh-5.2.14.orig/jobs.c 2009-07-18 15:20:19.000000000 +0200
+++ pdksh-5.2.14/jobs.c 2009-07-18 15:20:27.000000000 +0200
@@ -340,12 +340,17 @@
int i;
if (Flag(FMONITOR)) {
- /* Don't call get_tty() 'til we own the tty process group */
- tty_init(FALSE);
+ int use_tty;
+ if (Flag(FTALKING)) {
+ /* Don't call get_tty() 'til we own the tty process group */
+ use_tty = 1;
+ tty_init(FALSE);
+ } else
+ use_tty = 0;
# ifdef TTY_PGRP
/* no controlling tty, no SIGT* */
- ttypgrp_ok = tty_fd >= 0 && tty_devtty;
+ ttypgrp_ok = use_tty && tty_fd >= 0 && tty_devtty;
if (ttypgrp_ok && (our_pgrp = getpgID()) < 0) {
warningf(FALSE, "j_init: getpgrp() failed: %s",
@@ -401,8 +406,10 @@
strerror(errno));
}
# endif /* NTTYDISC && TIOCSETD */
- if (!ttypgrp_ok)
- warningf(FALSE, "warning: won't have full job control");
+ if (Flag(FTALKING)) {
+ if (!ttypgrp_ok)
+ warningf(FALSE, "warning: won't have full job control");
+ }
# endif /* TTY_PGRP */
if (tty_fd >= 0)
get_tty(tty_fd, &tty_state);
Index: pdksh-5.2.14/lex.c
===================================================================
--- pdksh-5.2.14.orig/lex.c 2009-07-18 15:20:19.000000000 +0200
+++ pdksh-5.2.14/lex.c 2009-07-18 15:20:27.000000000 +0200
@@ -723,7 +723,15 @@
#endif /* KSH */
) /* ONEWORD? */
return LWORD;
- ungetsc(c); /* unget terminator */
+
+ /* unget terminator */
+ ungetsc(c);
+
+ /*
+ * note: the alias-vs-function code below depends on several
+ * interna: starting from here, source->str is not modified;
+ * the way getsc() and ungetsc() operate; etc.
+ */
/* copy word to unprefixed string ident */
for (sp = yylval.cp, dp = ident; dp < ident+IDENT && (c = *sp++) == CHAR; )
@@ -747,6 +755,33 @@
if ((cf & ALIAS) && (p = tsearch(&aliases, ident, h))
&& (p->flag & ISSET))
{
+ /*
+ * this still points to the same character as the
+ * ungetsc'd terminator from above
+ */
+ const char *cp = source->str;
+
+ /* prefer POSIX but not Korn functions over aliases */
+ while (*cp == ' ' || *cp == '\t')
+ /*
+ * this is like getsc() without skipping
+ * over Source boundaries (including not
+ * parsing ungetsc'd characters that got
+ * pushed into an SREREAD) which is what
+ * we want here anyway: find out whether
+ * the alias name is followed by a POSIX
+ * function definition (only the opening
+ * parenthesis is checked though)
+ */
+ ++cp;
+ /* prefer functions over aliases */
+ if (*cp == '(' /*)*/) {
+ /*
+ * delete alias upon encountering function
+ * definition
+ */
+ tdelete(p);
+ } else {
register Source *s;
for (s = source; s->type == SALIAS; s = s->next)
@@ -760,6 +795,7 @@
source = s;
afree(yylval.cp, ATEMP);
goto Again;
+ }
}
}
Index: pdksh-5.2.14/ksh.Man
===================================================================
--- pdksh-5.2.14.orig/ksh.Man 2009-07-18 15:20:07.000000000 +0200
+++ pdksh-5.2.14/ksh.Man 2009-07-18 15:21:11.000000000 +0200
@@ -390,6 +390,7 @@
.IP "\fIname\fP \fB()\fP \fIcommand\fP"
Mostly the same as \fBfunction\fP.
See Functions below.
+Whitespace (space or tab) after \fIname\fP will be ignored most of the time.
.\"}}}
.\"{{{ time [-p] [ pipeline ]
.IP "\fBtime\fP [ \fB-p\fP ] [ \fIpipeline\fP ]"
@@ -1457,6 +1458,10 @@
so \fBgetopts\fP can be used properly both inside and outside the function
(Bourne-style functions leave \fBOPTIND\fP untouched, so using \fBgetopts\fP
inside a function interferes with using \fBgetopts\fP outside the function).
+.br
+Bourne-style function definitions take precedence over alias dereferences
+and remove alias definitions upon encounter, while aliases take precedence
+over Korn-style functions.
.nr PD \n(P2
In the future, the following differences will also be added:
.nr P2 \n(PD
|