commit 54ca44b456c14a9eef317915dc3466a9ef6832fbcac6e5f3073c7e5a3c2851cc Author: Michael Schröder Date: Thu Aug 1 12:13:15 2024 +0000 - fix segfault in variable substitution [bsc#1129288] - fix untrusted environment execution [bsc#1160796] [CVE-2019-14868] OBS-URL: https://build.opensuse.org/package/show/shells/ksh?expand=0&rev=240 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/Agreement b/Agreement new file mode 100644 index 0000000..edb1c35 --- /dev/null +++ b/Agreement @@ -0,0 +1,14 @@ +http://www.research.att.com/sw/download/ +http://www.research.att.com/sw/download/beta/ +User: `I accept www.opensource.org/licenses/cpl' +Password: `.' + +#user='I accept www.opensource.org/licenses/eclipse' +user='I accept www.opensource.org/licenses/cpl' +#subdir=beta +subdir=tgz +version=2012-02-29 +wget --user="${user}" --password='.' \ + http://www2.research.att.com/sw/download/${subdir}/ast-ksh.${version}.tgz \ + http://www2.research.att.com/sw/download/${subdir}/INIT.${version}.tgz \ + http://www2.research.att.com/sw/download/${subdir}/ast-base.${version}.tgz diff --git a/CPL b/CPL new file mode 100644 index 0000000..04afe02 --- /dev/null +++ b/CPL @@ -0,0 +1,245 @@ ++------------------------------------------------------------------------------+ +| This license covers all software that refers to the URL | +| http://www.opensource.org/licenses/cpl1.0.txt | ++------------------------------------------------------------------------------+ + +Common Public License Version 1.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF + THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + + 1. DEFINITIONS + + "Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate from + and are distributed by that particular Contributor. A Contribution + 'originates' from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's + behalf. Contributions do not include additions to the Program + which: (i) are separate modules of software distributed in + conjunction with the Program under their own license agreement, and + (ii) are not derivative works of the Program. + + "Contributor" means any person or entity that distributes the Program. + + "Licensed Patents " mean patent claims licensable by a Contributor + which are necessarily infringed by the use or sale of its Contribution + alone or when combined with the Program. + + "Program" means the Contributions distributed in accordance with this + Agreement. + + "Recipient" means anyone who receives the Program under this + Agreement, including all Contributors. + + 2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare derivative works of, publicly + display, publicly perform, distribute and sublicense the + Contribution of such Contributor, if any, and such derivative + works, in source code and object code form. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in source code and object code form. This patent license + shall apply to the combination of the Contribution and the Program + if, at the time the Contribution is added by the Contributor, such + addition of the Contribution causes such combination to be covered + by the Licensed Patents. The patent license shall not apply to any + other combinations which include the Contribution. No hardware per + se is licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + 3. REQUIREMENTS + + A Contributor may choose to distribute the Program in object code form + under its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and implied + warranties or conditions of merchantability and fitness for a + particular purpose; + + ii) effectively excludes on behalf of all Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) states that any provisions which differ from this Agreement + are offered by that Contributor alone and not by any other party; + and + + iv) states that source code for the Program is available from such + Contributor, and informs licensees how to obtain it in a reasonable + manner on or through a medium customarily used for software + exchange. + + When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of the + Program. + + Contributors may not remove or alter any copyright notices contained + within the Program. + + Each Contributor must identify itself as the originator of its + Contribution, if any, in a manner that reasonably allows subsequent + Recipients to identify the originator of the Contribution. + + 4. COMMERCIAL DISTRIBUTION + + Commercial distributors of software may accept certain + responsibilities with respect to end users, business partners and the + like. While this license is intended to facilitate the commercial use + of the Program, the Contributor who includes the Program in a + commercial product offering should do so in a manner which does not + create potential liability for other Contributors. Therefore, if a + Contributor includes the Program in a commercial product offering, + such Contributor ("Commercial Contributor") hereby agrees to defend + and indemnify every other Contributor ("Indemnified Contributor") + against any losses, damages and costs (collectively "Losses") arising + from claims, lawsuits and other legal actions brought by a third party + against the Indemnified Contributor to the extent caused by the acts + or omissions of such Commercial Contributor in connection with its + distribution of the Program in a commercial product offering. The + obligations in this section do not apply to any claims or Losses + relating to any actual or alleged intellectual property infringement. + In order to qualify, an Indemnified Contributor must: a) promptly + notify the Commercial Contributor in writing of such claim, and b) + allow the Commercial Contributor to control, and cooperate with the + Commercial Contributor in, the defense and any related settlement + negotiations. The Indemnified Contributor may participate in any such + claim at its own expense. + + For example, a Contributor might include the Program in a commercial + product offering, Product X. That Contributor is then a Commercial + Contributor. If that Commercial Contributor then makes performance + claims, or offers warranties related to Product X, those performance + claims and warranties are such Commercial Contributor's responsibility + alone. Under this section, the Commercial Contributor would have to + defend claims against the other Contributors related to those + performance claims and warranties, and if a court requires any other + Contributor to pay any damages as a result, the Commercial Contributor + must pay those damages. + + 5. NO WARRANTY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS + PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY + OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely + responsible for determining the appropriateness of using and + distributing the Program and assumes all risks associated with its + exercise of rights under this Agreement, including but not limited to + the risks and costs of program errors, compliance with applicable + laws, damage to or loss of data, programs or equipment, and + unavailability or interruption of operations. + + 6. DISCLAIMER OF LIABILITY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR + ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING + WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR + DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED + HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + 7. GENERAL + + If any provision of this Agreement is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of + the remainder of the terms of this Agreement, and without further + action by the parties hereto, such provision shall be reformed to the + minimum extent necessary to make such provision valid and enforceable. + + If Recipient institutes patent litigation against a Contributor with + respect to a patent applicable to software (including a cross-claim or + counterclaim in a lawsuit), then any patent licenses granted by that + Contributor to such Recipient under this Agreement shall terminate as + of the date such litigation is filed. In addition, if Recipient + institutes patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Program + itself (excluding combinations of the Program with other software or + hardware) infringes such Recipient's patent(s), then such Recipient's + rights granted under Section 2(b) shall terminate as of the date such + litigation is filed. + + All Recipient's rights under this Agreement shall terminate if it + fails to comply with any of the material terms or conditions of this + Agreement and does not cure such failure in a reasonable period of + time after becoming aware of such noncompliance. If all Recipient's + rights under this Agreement terminate, Recipient agrees to cease use + and distribution of the Program as soon as reasonably practicable. + However, Recipient's obligations under this Agreement and any licenses + granted by Recipient relating to the Program shall continue and + survive. + + Everyone is permitted to copy and distribute copies of this Agreement, + but in order to avoid inconsistency the Agreement is copyrighted and + may only be modified in the following manner. The Agreement Steward + reserves the right to publish new versions (including revisions) of + this Agreement from time to time. No one other than the Agreement + Steward has the right to modify this Agreement. IBM is the initial + Agreement Steward. IBM may assign the responsibility to serve as the + Agreement Steward to a suitable separate entity. Each new version of + the Agreement will be given a distinguishing version number. The + Program (including Contributions) may always be distributed subject to + the version of the Agreement under which it was received. In addition, + after a new version of the Agreement is published, Contributor may + elect to distribute the Program (including its Contributions) under + the new version. Except as expressly stated in Sections 2(a) and 2(b) + above, Recipient receives no rights or licenses to the intellectual + property of any Contributor under this Agreement, whether expressly, + by implication, estoppel or otherwise. All rights in the Program not + expressly granted under this Agreement are reserved. + + This Agreement is governed by the laws of the State of New York and + the intellectual property laws of the United States of America. No + party to this Agreement will bring a legal action under this Agreement + more than one year after the cause of action arose. Each party waives + its rights to a jury trial in any resulting litigation. + +Copyright (c) 2004 by the Open Source Initiative +This is a copy of the license posted on 2004-10-06 at: + http://www.opensource.org/licenses/cpl diff --git a/EPL b/EPL new file mode 100644 index 0000000..e1d748e --- /dev/null +++ b/EPL @@ -0,0 +1,221 @@ ++------------------------------------------------------------------------------+ +| This license covers all software that refers to the URL | +| http://www.eclipse.org/org/documents/epl-v10.html | ++------------------------------------------------------------------------------+ + +Eclipse Public License - v 1.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC + LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM + CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + + 1. DEFINITIONS + + "Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate from and are + distributed by that particular Contributor. A Contribution 'originates' from + a Contributor if it was added to the Program by such Contributor itself or + anyone acting on such Contributor's behalf. Contributions do not include + additions to the Program which: (i) are separate modules of software + distributed in conjunction with the Program under their own license + agreement, and (ii) are not derivative works of the Program. + + "Contributor" means any person or entity that distributes the Program. + + "Licensed Patents" mean patent claims licensable by a Contributor which are + necessarily infringed by the use or sale of its Contribution alone or when + combined with the Program. + + "Program" means the Contributions distributed in accordance with this + Agreement. + + "Recipient" means anyone who receives the Program under this Agreement, + including all Contributors. + + 2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby grants + Recipient a non-exclusive, worldwide, royalty-free copyright license to + reproduce, prepare derivative works of, publicly display, publicly perform, + distribute and sublicense the Contribution of such Contributor, if any, and + such derivative works, in source code and object code form. + + b) Subject to the terms of this Agreement, each Contributor hereby grants + Recipient a non-exclusive, worldwide, royalty-free patent license under + Licensed Patents to make, use, sell, offer to sell, import and otherwise + transfer the Contribution of such Contributor, if any, in source code and + object code form. This patent license shall apply to the combination of the + Contribution and the Program if, at the time the Contribution is added by + the Contributor, such addition of the Contribution causes such combination + to be covered by the Licensed Patents. The patent license shall not apply to + any other combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the licenses + to its Contributions set forth herein, no assurances are provided by any + Contributor that the Program does not infringe the patent or other + intellectual property rights of any other entity. Each Contributor disclaims + any liability to Recipient for claims brought by any other entity based on + infringement of intellectual property rights or otherwise. As a condition to + exercising the rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual property rights + needed, if any. For example, if a third party patent license is required to + allow Recipient to distribute the Program, it is Recipient's responsibility + to acquire that license before distributing the Program. + + d) Each Contributor represents that to its knowledge it has sufficient + copyright rights in its Contribution, if any, to grant the copyright license + set forth in this Agreement. + + 3. REQUIREMENTS + + A Contributor may choose to distribute the Program in object code form under + its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all warranties and + conditions, express and implied, including warranties or conditions of title + and non-infringement, and implied warranties or conditions of + merchantability and fitness for a particular purpose; + + ii) effectively excludes on behalf of all Contributors all liability for + damages, including direct, indirect, special, incidental and consequential + damages, such as lost profits; + + iii) states that any provisions which differ from this Agreement are offered + by that Contributor alone and not by any other party; and + + iv) states that source code for the Program is available from such + Contributor, and informs licensees how to obtain it in a reasonable manner + on or through a medium customarily used for software exchange. + + When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of the Program. + + Contributors may not remove or alter any copyright notices contained within + the Program. + + Each Contributor must identify itself as the originator of its Contribution, + if any, in a manner that reasonably allows subsequent Recipients to identify + the originator of the Contribution. + + 4. COMMERCIAL DISTRIBUTION + + Commercial distributors of software may accept certain responsibilities with + respect to end users, business partners and the like. While this license is + intended to facilitate the commercial use of the Program, the Contributor + who includes the Program in a commercial product offering should do so in a + manner which does not create potential liability for other Contributors. + Therefore, if a Contributor includes the Program in a commercial product + offering, such Contributor ("Commercial Contributor") hereby agrees to + defend and indemnify every other Contributor ("Indemnified Contributor") + against any losses, damages and costs (collectively "Losses") arising from + claims, lawsuits and other legal actions brought by a third party against + the Indemnified Contributor to the extent caused by the acts or omissions of + such Commercial Contributor in connection with its distribution of the + Program in a commercial product offering. The obligations in this section do + not apply to any claims or Losses relating to any actual or alleged + intellectual property infringement. In order to qualify, an Indemnified + Contributor must: a) promptly notify the Commercial Contributor in writing + of such claim, and b) allow the Commercial Contributor to control, and + cooperate with the Commercial Contributor in, the defense and any related + settlement negotiations. The Indemnified Contributor may participate in any + such claim at its own expense. + + For example, a Contributor might include the Program in a commercial product + offering, Product X. That Contributor is then a Commercial Contributor. If + that Commercial Contributor then makes performance claims, or offers + warranties related to Product X, those performance claims and warranties are + such Commercial Contributor's responsibility alone. Under this section, the + Commercial Contributor would have to defend claims against the other + Contributors related to those performance claims and warranties, and if a + court requires any other Contributor to pay any damages as a result, the + Commercial Contributor must pay those damages. + + 5. NO WARRANTY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON + AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER + EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR + CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A + PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the + appropriateness of using and distributing the Program and assumes all risks + associated with its exercise of rights under this Agreement , including but + not limited to the risks and costs of program errors, compliance with + applicable laws, damage to or loss of data, programs or equipment, and + unavailability or interruption of operations. + + 6. DISCLAIMER OF LIABILITY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY + CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION + LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE + EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY + OF SUCH DAMAGES. + + 7. GENERAL + + If any provision of this Agreement is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of the + remainder of the terms of this Agreement, and without further action by the + parties hereto, such provision shall be reformed to the minimum extent + necessary to make such provision valid and enforceable. + + If Recipient institutes patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Program itself + (excluding combinations of the Program with other software or hardware) + infringes such Recipient's patent(s), then such Recipient's rights granted + under Section 2(b) shall terminate as of the date such litigation is filed. + + All Recipient's rights under this Agreement shall terminate if it fails to + comply with any of the material terms or conditions of this Agreement and + does not cure such failure in a reasonable period of time after becoming + aware of such noncompliance. If all Recipient's rights under this Agreement + terminate, Recipient agrees to cease use and distribution of the Program as + soon as reasonably practicable. However, Recipient's obligations under this + Agreement and any licenses granted by Recipient relating to the Program + shall continue and survive. + + Everyone is permitted to copy and distribute copies of this Agreement, but + in order to avoid inconsistency the Agreement is copyrighted and may only be + modified in the following manner. The Agreement Steward reserves the right + to publish new versions (including revisions) of this Agreement from time to + time. No one other than the Agreement Steward has the right to modify this + Agreement. The Eclipse Foundation is the initial Agreement Steward. The + Eclipse Foundation may assign the responsibility to serve as the Agreement + Steward to a suitable separate entity. Each new version of the Agreement + will be given a distinguishing version number. The Program (including + Contributions) may always be distributed subject to the version of the + Agreement under which it was received. In addition, after a new version of + the Agreement is published, Contributor may elect to distribute the Program + (including its Contributions) under the new version. Except as expressly + stated in Sections 2(a) and 2(b) above, Recipient receives no rights or + licenses to the intellectual property of any Contributor under this + Agreement, whether expressly, by implication, estoppel or otherwise. All + rights in the Program not expressly granted under this Agreement are + reserved. + + This Agreement is governed by the laws of the State of New York and the + intellectual property laws of the United States of America. No party to this + Agreement will bring a legal action under this Agreement more than one year + after the cause of action arose. Each party waives its rights to a jury + trial in any resulting litigation. diff --git a/INIT.2012-08-01.tar.bz2 b/INIT.2012-08-01.tar.bz2 new file mode 100644 index 0000000..6a5e704 --- /dev/null +++ b/INIT.2012-08-01.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b854435757829f9fbc9d24242192e2056069862d9c463bf8dcfb76b1f094c8b +size 295820 diff --git a/Warning b/Warning new file mode 100644 index 0000000..dd38b89 --- /dev/null +++ b/Warning @@ -0,0 +1,26 @@ + + GPL 1.0/2.0 versus CPL1.0 as well as versus EPL1.0 + ================================================== + +According to http://www.gnu.org/licenses/license-list.html +the current CPL-1.0 as well as EPL-1.0 is incompatible with +the GPL. + +Therefore no developer should use the libraries provided +by the ksh in any project under the GPL. + +For compiling use + + -I/usr/include/ast + +on the gcc compiler command line. For linking please +add the line + + -L/usr/lib/ast + +or + + -L/usr/lib64/ast + +on 64bit architectures to the command line of the +linker or gcc. diff --git a/ast-base.2012-08-01.tar.bz2 b/ast-base.2012-08-01.tar.bz2 new file mode 100644 index 0000000..82bc6c2 --- /dev/null +++ b/ast-base.2012-08-01.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81f4007679dad9a93b2a4ed241cbe2e86d1422ee3b74c4f905aaae1345070af2 +size 8035476 diff --git a/astksh_builtin_poll20120806_001.diff b/astksh_builtin_poll20120806_001.diff new file mode 100644 index 0000000..ae1c745 --- /dev/null +++ b/astksh_builtin_poll20120806_001.diff @@ -0,0 +1,887 @@ +--- src/cmd/ksh93/Makefile ++++ src/cmd/ksh93/Makefile 2012-08-06 21:25:47.000000000 +0000 +@@ -161,6 +161,7 @@ DATAFILES = limits.c msg.c strdata.c tes + + shell$(RELEASE) $(VERSION) id=shell :LIBRARY: shell.3 nval.3 alarm.c cd_pwd.c cflow.c deparse.c \ + enum.c getopts.c hist.c misc.c print.c read.c sleep.c trap.c test.c \ ++ poll.c \ + typeset.c ulimit.c umask.c whence.c main.c nvdisc.c nvtype.c \ + arith.c args.c array.c completion.c defs.c edit.c expand.c regress.c \ + fault.c fcin.c history.c init.c io.c jobs.c lex.c macro.c name.c \ +--- src/cmd/ksh93/Mamfile ++++ src/cmd/ksh93/Mamfile 2012-08-06 21:25:47.000000000 +0000 +@@ -548,6 +548,22 @@ meta test.o %.c>%.o bltins/test.c test + prev bltins/test.c + exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -D_BLD_shell -DSHOPT_DYNAMIC -DSHOPT_MULTIBYTE -DSHOPT_PFSH -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_COSHELL -DSHOPT_HISTEXPAND -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DKSHELL -c bltins/test.c + done test.o generated ++ ++make poll.o ++make bltins/poll.c ++prev ${PACKAGE_ast_INCLUDE}/tmx.h implicit ++prev FEATURE/poll implicit ++prev FEATURE/externs implicit ++prev include/builtins.h implicit ++prev include/io.h implicit ++prev ${PACKAGE_ast_INCLUDE}/error.h implicit ++prev include/defs.h implicit ++done bltins/poll.c ++meta poll.o %.c>%.o bltins/poll.c test ++prev bltins/poll.c ++exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -D_BLD_shell -DSHOPT_DYNAMIC -DSHOPT_MULTIBYTE -DSHOPT_PFSH -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_COSHELL -DSHOPT_DYNAMIC -DSHOPT_HISTEXPAND -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DKSHELL -c bltins/poll.c ++done poll.o generated ++ + make typeset.o + make bltins/typeset.c + prev FEATURE/dynamic implicit +@@ -1328,7 +1344,7 @@ meta hexpand.o %.c>%.o edit/hexpand.c he + prev edit/hexpand.c + exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_HISTEXPAND -DSHOPT_EDPREDICT -DSHOPT_MULTIBYTE -DKSHELL -DSHOPT_ESH -DSHOPT_VSH -D_PACKAGE_ast -DSHOPT_PFSH -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_COSHELL -D_BLD_shell -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -c edit/hexpand.c + done hexpand.o generated +-exec - ${AR} rc libshell.a alarm.o cd_pwd.o cflow.o deparse.o enum.o getopts.o hist.o misc.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o ++exec - ${AR} rc libshell.a alarm.o cd_pwd.o cflow.o deparse.o enum.o getopts.o hist.o misc.o poll.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o + exec - ${AR} rc libshell.a history.o init.o io.o jobs.o lex.o macro.o name.o nvtree.o parse.o path.o string.o streval.o subshell.o tdump.o timers.o trestore.o waitevent.o xec.o env.o limits.o msg.o strdata.o testops.o keywords.o options.o signals.o aliases.o builtins.o variables.o lexstates.o emacs.o vi.o hexpand.o + exec - (ranlib libshell.a) >/dev/null 2>&1 || true + done libshell.a generated +--- src/cmd/ksh93/bltins/poll.c ++++ src/cmd/ksh93/bltins/poll.c 2012-08-07 03:13:40.000000000 +0000 +@@ -0,0 +1,717 @@ ++/*********************************************************************** ++* * ++* This software is part of the ast package * ++* Copyright (c) 2007-2012 AT&T Intellectual Property * ++* and is licensed under the * ++* Eclipse Public License, Version 1.0 * ++* by AT&T Intellectual Property * ++* * ++* A copy of the License is available at * ++* http://www.eclipse.org/org/documents/epl-v10.html * ++* (with md5 checksum b35adb5213ca9657e911e9befb180842) * ++* * ++* Information and Software Systems Research * ++* AT&T Research * ++* Florham Park NJ * ++* * ++* Roland Mainz * ++* * ++***********************************************************************/ ++#pragma prototyped ++ ++#include "defs.h" ++#include "variables.h" ++#include "lexstates.h" ++#include "io.h" ++#include "name.h" ++#include "builtins.h" ++#include "history.h" ++#include "terminal.h" ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef SH_DICT ++# define SH_DICT "libshell" ++#endif ++ ++#define sh_contexttoshell(context) ((context)?((context)->shp):(NULL)) ++ ++static ++const char sh_optpoll[] = ++"[-?\n@(#)$Id: poll (AT&T Labs Research) 2012-08-01 $\n]" ++"[-author?Roland Mainz ]" ++"[-license?http://www.eclipse.org/org/documents/epl-v10.html]" ++"[+NAME? poll - input/output multiplexing]" ++"[+DESCRIPTION?The poll command provides applications with a " ++ "mechanism for multiplexing input/output over a set of " ++ "file descriptors. " ++ "For each member of the (optionally sparse) indexed or " ++ "associative compound or type (see \btypeset -T\b) array " ++ "variable \bvar\b, poll examines the given file descriptor " ++ "in the subscript \b.fd\b for the event(s) specified in " ++ "the subscript \b.events\b. " ++ "The poll command identifies those file descriptors on " ++ "which an application can read or write data, or on which " ++ "certain events have occurred.]" ++"[+?The \bvar\b argument specifies an array of file descriptors to " ++ "be examined and the events of interest for each file " ++ "descriptor. " ++ "It is a array of compound variables (or user-defined type) " ++ "with one member for each open file descriptor of interest. " ++ "The array's compound or type variable members contain the " ++ "following subscripts:]{" ++ "[+?\b.fd\b # file descriptor]" ++ "[+?\b.events\b # compound variable of requested event(s)]" ++ "[+?\b.revents\b # compound variable of returned event(s)]" ++ "}" ++"[+?The \bfd\b variable specifies an open file descriptor and the " ++ "\bevents\b and \brevents\b members are compound variables " ++ "constructed from the following boolean member variables:]" ++ "{ " ++ "[+.pollin?('true'|'false') Data other than high priority " ++ "data may be read without blocking. For STREAMS, this " ++ "flag is set in \brevents\b even if the message " ++ "is of zero length.]" ++ "[+.pollrdnorm?('true'|'false') Normal data (priority band " ++ "equals 0) may be read without blocking. For STREAMS, " ++ "this flag is set in \brevents\b even if the message " ++ "is of zero length.]" ++ "[+.pollrdband?('true'|'false') Data from a non-zero " ++ "priority band may be read without blocking. For " ++ "STREAMS, this flag is set in \brevents\b even if the " ++ "message is of zero length.]" ++ "[+.pollpri?('true'|'false') High priority data may be " ++ "received without blocking. For STREAMS, this flag is " ++ "set in \brevents\b even if the message is of zero " ++ "length.]" ++ "[+.pollout?('true'|'false') Normal data (priority band " ++ "equals 0) may be written without blocking.]" ++ "[+.pollwrnorm?('true'|'false') The same as \bpollout\b.]" ++ "[+.pollwrband?('true'|'false') Priority data (priority band " ++ "> 0) may be written. This event only examines bands " ++ "that have been written to at least once.]" ++ "[+.pollerr?('true'|'false') An error has occurred on the " ++ "device or stream. This flag is only valid in the " ++ "\brevents\b compound variable; it is not used in the " ++ "\bevents\b compound variable.]" ++ "[+.pollhup?('true'|'false') A hangup has occurred on the " ++ "stream. This event and \bpollout\b are mutually " ++ "exclusive; a stream can never be writable if a " ++ "hangup has occurred. " ++ "However, this event and \bpollin\b, " ++ "\bpollrdband\b, or \bpollpri\b are not " ++ "mutually exclusive. This flag is only valid " ++ "in the \brevents\b compound variable; it is not " ++ "used in the \bevents\b compound variable.]" ++ "[+.pollnval?('true'|'false') The specified fd value does " ++ "not belong to an open file. " ++ "This flag is only valid in the \brevents\b compound " ++ "variable; it is not used in the \bevents\b " ++ "compound variable.]" ++ "}" ++"]" ++ ++"[+?If the value fd is less than 0, events is ignored and " ++ "revents is set to 0 in that entry on return from poll.]" ++ ++"[+?The results of the poll query are stored in the \brevents\b " ++ "compound variable members in the \bvar\b structure. " ++ "\bpoll*\b-variables are set in the \brevents\b compound " ++ "variable to indicate which of the requested events are true. " ++ "If none are true, the matching member in the \brevents\b " ++ "compound variable will have the value of 'false' when the " ++ "poll command returns. " ++ "The \brevents\b compound variable members \bpollhup\b, " ++ "\bpollerr\b, and \bpollnval\b are always set to 'true' in " ++ "\brevents\b if the conditions they indicate are true; this " ++ "occurs even though these flags were not present and/or set " ++ "to 'true' in the \bevents\b compound variable.]" ++ ++"[+?If none of the defined events have occurred on any selected " ++ "file descriptor, poll waits at least timeout milliseconds " ++ "for an event to occur on any of the selected file " ++ "descriptors. " ++ "On a computer where millisecond timing accuracy is not " ++ "available, timeout is rounded up to the nearest legal value " ++ "available on that system. If the value timeout is 0, poll " ++ "returns immediately. If the value of timeout is -1, poll " ++ "blocks until a requested event occurs or until the call is " ++ "interrupted.]" ++ ++"[+?The poll utility supports regular files, terminal and " ++ "pseudo-terminal devices, STREAMS-based files, FIFOs, and " ++ "pipes. The behavior of poll on elements of fds that refer " ++ "to other types of file is unspecified.]" ++ ++"[+?The poll utility supports sockets.]" ++#ifdef __SunOS ++"[+?The poll utility may be used on Solaris on directory fds of " ++ "/proc/$pid/ to get a \bpollhup='true'\b when the process quits.]" ++#endif ++"[+?A file descriptor for a socket that is listening for connections " ++ "will indicate that it is ready for reading, once connections " ++ "are available. A file descriptor for a socket that " ++ "is connecting asynchronously will indicate that it is ready " ++ "for writing, once a connection has been established.]" ++ ++"[+?Regular files always poll TRUE for reading and writing.]" ++ ++"[e:eventarray]:[fdcount?Upon successful completion, an indexed array " ++ "of strings is returned which contains a list of array " ++ "subscripts in the poll array which received events.]" ++"[S!:pollsfio?Look into sfio streams for buffered information and set " ++ "pollin/pollout to reflect sfio stream state.]" ++"[R:pollttyraw?Put tty connections into raw mode when polling. The " ++ "fd is returned to tty cooked mode before poll(1) exits.]" ++"[t:timeout]:[seconds?Timeout in seconds. If the value timeout is 0, " ++ "poll returns immediately. If the value of timeout is -1, " ++ "poll blocks until a requested event occurs or until the " ++ "call is interrupted.]" ++"\n" ++"\nvar\n" ++"\n" ++"[+EXIT STATUS?]{" ++ "[+0?Success.]" ++ "[+>0?An error occurred.]" ++"}" ++"[+NOTES?]{" ++ "[+?poll*-variables defined in \bevents\b will always appear " ++ "in \brevents\b. This gives the script author control over " ++ "which poll*-variables he can expect in \brevents\b.]" ++ ++ "[+?The \bpollinhup\b, \bpollnval\b and \bpollerr\b variables " ++ "may appear in the \brevents\b compound variable even if " ++ "they were not requested in \bevents\b.]" ++ ++ "[+?Using the value of variables in \brevents\b which are " ++ "not set in \bevents\b can be done by putting a '-' suffix " ++ "after the variable name, e.g. use " ++ "\b${ar[x]].revents.pollhup-}\b to get the value of " ++ "\bar[x]].revents.pollhup\b or an empty string if the variable " ++ "was not set.]" ++ ++ "[+?Like \bpoll\b(2) it is legal to poll on the same fd in " ++ "multiple entries, for exanple to listen for different events " ++ "or to allow multiple callers to pool their poll lists " ++ "together into one \bpoll\b(1) call.]" ++"}" ++ ++/* quoting: ']' must be quoted as "]]" and '?' must be quoted as "//" */ ++"[+EXAMPLES?]{" ++ "[+?The following example will wait for 10 seconds for input " ++ "on fd 0, variable \bp[fd0]].revents.pollin\b will be 'true' " ++ "or 'false' depening on whether the stream 0 is ready for " ++ "reading:]{" ++ "[+?compound -A p=( [fd0]]=( fd=0 events=( pollin='true' ) ) ) ; poll -t10 p ; print -v p]" ++ "}" ++ ++ "[+?The following example will wait for 2 seconds for input " ++ "on fd 0, and variables \bp[0]].revents.pollin\b and " ++ "\bp[0]].revents.pollhup\b will be 'true' after polling ends " ++ "because there is both input data available and the end of " ++ "the stream was reached:]{" ++ "[+?printf '\\n' | ksh -c 'compound -a p=( ( fd=0 events=( pollin=\"true\" pollhup=\"true\" ) ) ) ; poll -t2 p ; print -v p']" ++ "}" ++"}" ++ ++"[+SEE ALSO?\bopen\b(1),\btmpfile\b(1),\bdup\b(1),\bclose\b(1),\bpoll\b(2)]" ++; ++ ++ ++/* Like |nv_open()| but constructs variable name on the fly using |sprintf()| format */ ++static ++Namval_t *nv_open_fmt(Dt_t *dict, int flags, const char *namefmt, ...) ++{ ++ char varnamebuff[PATH_MAX]; ++ va_list ap; ++ ++ va_start(ap, namefmt); ++ vsnprintf(varnamebuff, sizeof(varnamebuff), namefmt, ap); ++ va_end(ap); ++ ++ return nv_open(varnamebuff, dict, flags); ++} ++ ++/* Name/value mapping table for POLL*-flags */ ++struct pollflagnamemap ++{ ++ const int flag; ++ const char *name; ++}; ++ ++const ++struct pollflagnamemap pfnm[]= ++{ ++ { POLLIN, "pollin" }, ++#ifdef POLLPRI ++ { POLLPRI, "pollpri" }, ++#endif ++ { POLLOUT, "pollout" }, ++#ifdef POLLRDNORM ++ { POLLRDNORM, "pollrdnorm" }, ++#endif ++#ifdef POLLWRNORM ++ { POLLWRNORM, "pollwrnorm" }, ++#endif ++#ifdef POLLRDBAND ++ { POLLRDBAND, "pollrdband" }, ++#endif ++#ifdef POLLWRBAND ++ { POLLWRBAND, "pollwrband" }, ++#endif ++#ifdef POLLMSG ++ { POLLMSG, "pollmsg" }, ++#endif ++#ifdef POLLREMOVE ++ { POLLREMOVE, "pollremove" }, ++#endif ++#ifdef POLLRDHUP ++ { POLLRDHUP, "pollrdhup" }, ++#endif ++ { POLLERR, "pollerr" }, ++ { POLLHUP, "pollhup" }, ++ { POLLNVAL, "pollnval" }, ++ { 0, NULL }, ++}; ++ ++/* structure to keep track of per array entry data */ ++struct pollstat ++{ ++ /* name of array subscript */ ++ const char *array_subscript; ++ ++ /* |sfio| keeps track of sfio information */ ++ struct ++ { ++ Sfio_t *sfd; ++ ssize_t flags; ++ } sfio; ++ ++ /* ++ * Bits in |eventvar_found| are POLL*-bits, set if matching ++ * ar[i].events.poll* var was found. We use this later to ++ * set the same ar[i].revents.poll* variable, regardless ++ * whether it was polled or not. This was done so the script ++ * author can control which poll* variables in the "revents" ++ * compound appear and which not. ++ */ ++ int eventvar_found; ++}; ++ ++/* poll on given |fds| data and retry after EINTR/EAGAIN while adjusting timeout */ ++static ++int poll_loop(Shbltin_t* context, struct pollfd *fds, nfds_t nfds, int timeout) ++{ ++/* nanoseconds to milliseconds */ ++#define TIME_NS2MS(t) ((t)/(1000UL*1000UL)) ++/* milliseconds to nanoseconds */ ++#define TIME_MS2NS(t) (((Time_t)(t))*(1000UL*1000UL)) ++ ++ int n; ++ ++ /* We need two codepaths here: ++ * 1. timeout > 0: we have to wait for |timeout| or events. ++ * 2. timeout <= 0: we have to wait forever (-1), return ++ * immediately (0) or an event occurs. ++ */ ++ if (timeout > 0) ++ { ++ const Time_t starttime = tmxgettime(); ++ Time_t timeout_ns = TIME_MS2NS(timeout); ++ ++ do ++ { ++ while(((n = poll(fds, nfds, timeout)) < 0) && ++ ((errno == EINTR) || (errno == EAGAIN)) && ++ (!context->sigset)) ++ errno=0; ++ ++ timeout_ns=timeout_ns-(tmxgettime()-starttime); ++ timeout=TIME_NS2MS(timeout_ns); ++ } while((timeout > 0) && (!context->sigset)); ++ } ++ else ++ { ++ while(((n = poll(fds, nfds, timeout)) < 0) && ++ ((errno == EINTR) || (errno == EAGAIN)) && ++ (!context->sigset)) ++ errno=0; ++ } ++ return n; ++} ++ ++/* set ".poll*"-variables in "ar[i].revents" per data in |currpollfd| and |currps| */ ++static ++void set_compound_revents(Shell_t *shp, const char *parrayname, struct pollstat *currps, struct pollfd *currpollfd) ++{ ++ const char *subname=currps->array_subscript; ++ Namval_t *np; ++ int pi; ++ ++ np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_COMVAR, "%s[%s].revents", parrayname, subname); ++ if (!np) ++ { ++ errormsg(SH_DICT, ERROR_ERROR, "could not create pollfd %s[%s].revents", parrayname, subname); ++ return; ++ } ++ nv_setvtree(np); /* make "revents" really a compound variable */ ++ nv_close(np); ++ ++ for (pi=0 ; pfnm[pi].name != NULL ; pi++) ++ { ++ /* ++ * POLLHUP|POLLNVAL|POLLERR can always appear in |currpollfd->revents| ++ * even if we did not request them in |currpollfd->events| ++ */ ++ if ((currps->eventvar_found & pfnm[pi].flag) || ++ ((currpollfd->revents & (POLLHUP|POLLNVAL|POLLERR)) & pfnm[pi].flag)) ++ { ++ np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_NOFAIL, "%s[%s].revents.%s", parrayname, subname, pfnm[pi].name); ++ if (!np) ++ continue; ++ ++ nv_putval(np, ((currpollfd->revents & pfnm[pi].flag)?"true":"false"), 0); ++ nv_close(np); ++ } ++ } ++} ++ ++/* |main()| for poll(1) builtin */ ++extern ++int b_poll(int argc, char *argv[], Shbltin_t* context) ++{ ++ Shell_t *shp = sh_contexttoshell(context); ++ Namval_t *np, ++ *array_np, ++ *array_np_sub; ++ Sfio_t *strstk = NULL; /* stk object for memory allocations */ ++ const char *parrayname, /* name of array with poll data */ ++ *eventarrayname = NULL, /* name of array with indexes to results */ ++ *subname, /* current subscript */ ++ *s; ++ int n; ++ int fd; ++ nfds_t numpollfd = 0; /* number of entries to poll */ ++ int i, ++ j; ++ double timeout = -1.; ++ char buff[PATH_MAX*2+1]; /* fixme: theoretically enough to hold two variable names */ ++ bool ttyraw = false; ++ bool pollsfio = true; ++ int pi; /* index for |pfnm| */ ++ struct pollfd *pollfd = NULL, /* data for poll(2) */ ++ *currpollfd; /* current |pollfd| we are working on */ ++ struct pollstat *pollstat = NULL, /* context data from shell array */ ++ *currps; /* current |pollstat| we are working on */ ++ int retval = 0; /* return value of builtin */ ++ ++ while (n = optget(argv, sh_optpoll)) switch (n) ++ { ++ case 't': ++ errno = 0; ++ timeout = strtod(opt_info.arg, (char **)NULL); ++ if (errno != 0) ++ errormsg(SH_DICT, ERROR_system(1), "%s: invalid timeout", opt_info.arg); ++ ++ /* -t uses seconds */ ++ if (timeout >=0) ++ timeout *= 1000.; ++ break; ++ case 'e': ++ eventarrayname = opt_info.arg; ++ break; ++ case 'S': ++ pollsfio=opt_info.num?true:false; ++ break; ++ case 'R': ++ ttyraw=opt_info.num?true:false; ++ break; ++ case ':': ++ errormsg(SH_DICT, ERROR_ERROR, "%s", opt_info.arg); ++ break; ++ case '?': ++ errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg); ++ break; ++ } ++ argc -= opt_info.index; ++ argv += opt_info.index; ++ if(argc!=1) ++ errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0)); ++ ++ parrayname = argv[0]; ++ ++ strstk = stkopen(0); ++ if (!strstk) ++ errormsg(SH_DICT, ERROR_system(1), e_nospace); ++ ++ array_np = nv_open(parrayname, shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_NOADD); ++ if (!array_np) ++ { ++ stkclose(strstk); ++ errormsg(SH_DICT, ERROR_system(1), "cannot find array variable %s", parrayname); ++ } ++ if (!nv_isattr(array_np, NV_ARRAY)) ++ { ++ nv_close(array_np); ++ stkclose(strstk); ++ errormsg(SH_DICT, ERROR_system(1), "variable %s is not an array", parrayname); ++ } ++ ++ /* ++ * Count number of array elememts. We need to do it "manually" ++ * to handle sparse indexed and associative arrays ++ */ ++ nv_putsub(array_np, NULL, ARRAY_SCAN); ++ array_np_sub = array_np; ++ do ++ { ++ if (!(subname=nv_getsub(array_np_sub))) ++ break; ++ numpollfd++; ++ } while(array_np_sub && nv_nextsub(array_np_sub)); ++ ++ /* ++ * Done with counting, now we need to allocate a work area big enough ++ */ ++ pollfd = (struct pollfd *)stkalloc(strstk, (sizeof(struct pollfd) * numpollfd)); ++ pollstat = (struct pollstat *)stkalloc(strstk, (sizeof(struct pollstat) * numpollfd)); ++ if (!pollfd || !pollstat) ++ { ++ errormsg(SH_DICT, ERROR_ERROR, e_nospace); ++ goto done_error; ++ } ++ ++ /* ++ * Walk the array again and fetch the data we need... ++ */ ++ nv_putsub(array_np, NULL, ARRAY_SCAN); ++ array_np_sub = array_np; ++ i = 0; ++ do ++ { ++ currps=&pollstat[i]; ++ currpollfd=&pollfd[i]; ++ ++ if (!(subname=nv_getsub(array_np_sub))) ++ break; ++ ++ currps->array_subscript=subname=stkcopy(strstk, subname); ++ if (!subname) ++ { ++ errormsg(SH_DICT, ERROR_ERROR, e_nospace); ++ goto done_error; ++ } ++ ++ np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_NOADD, "%s[%s].fd", parrayname, subname); ++ if (!np) ++ { ++ errormsg(SH_DICT, ERROR_ERROR, "missing pollfd %s[%s].fd", parrayname, subname); ++ goto done_error; ++ } ++ fd = (int)nv_getnum(np); ++ nv_close(np); ++ if ((fd < -1) || (fd > OPEN_MAX)) ++ { ++ errormsg(SH_DICT, ERROR_ERROR, "invalid pollfd %s[%s].fd %d", parrayname, subname, fd); ++ goto done_error; ++ } ++ currpollfd->fd = fd; ++ ++ np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_COMVAR|NV_NOADD, "%s[%s].events", parrayname, subname); ++ if (!np) ++ { ++ errormsg(SH_DICT, ERROR_ERROR, "missing pollfd %s[%s].events", parrayname, subname); ++ goto done_error; ++ } ++ nv_close(np); ++ ++ currpollfd->events=0; ++ currpollfd->revents=0; ++ currps->eventvar_found=0; ++ for (pi=0 ; pfnm[pi].name != NULL ; pi++) ++ { ++ const char *s; ++ ++ np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_NOADD, "%s[%s].events.%s", parrayname, subname, pfnm[pi].name); ++ if (!np) ++ continue; ++ ++ currps->eventvar_found |= pfnm[pi].flag; ++ s=nv_getval(np); ++ if ((s != NULL) && (!strcmp(s, "true"))) ++ currpollfd->events |= pfnm[pi].flag; ++ nv_close(np); ++ } ++ ++ i++; ++ } while(array_np_sub && nv_nextsub(array_np_sub)); ++ ++ nv_close(array_np); ++ array_np=NULL; ++ ++ /* ++ * If sfio handles fds we need to check whether there are ++ * any data in the sfio buffers and remember this information ++ * so we can set { POLLIN, POLLOUT } on demand to reflect ++ * this information. ++ */ ++ if (pollsfio) ++ { ++ Sfio_t **sfd; ++ int num_sfd=0, ++ active_sfd=0; ++ ++ sfd = (Sfio_t **)stkalloc(strstk, (sizeof(Sfio_t *) * (numpollfd+1))); ++ if (!sfd) ++ { ++ errormsg(SH_DICT, ERROR_ERROR, e_nospace); ++ goto done_error; ++ } ++ ++ for (i=0 ; i < numpollfd ; i++) ++ { ++ currps=&pollstat[i]; ++ fd=pollfd[i].fd; ++ ++ currps->sfio.sfd=(fd>=0)?sh_fd2sfio(fd):NULL; ++ currps->sfio.flags=0; ++ if (currps->sfio.sfd!=NULL) ++ { ++ /* Only add |currps->sfio.sfd| to the ++ * |sfd| array (list of |Sfio_t*| ++ * passed to |sfpoll()|) if it is not ++ * in that list yet. This prevents ++ * that we call |sfpoll()| on the same ++ * sfio stream multiple times (which ++ * can happen if pollfd contains the ++ * same fd multiple times (which is ++ * valid usage, for example if multiple ++ * consumers pool their pool lists in ++ * one poll call or listen to different ++ * sets of poll event flags)). ++ */ ++ for (j=0 ; j < num_sfd ; j++) ++ { ++ if (sfd[j]==currps->sfio.sfd) ++ break; ++ } ++ if (j == num_sfd) ++ sfd[num_sfd++]=currps->sfio.sfd; ++ } ++ } ++ ++ active_sfd = sfpoll(&sfd[0], num_sfd, 0); ++ if (active_sfd > 0) ++ { ++ ssize_t sfpoll_flags; ++ ++ for (i=0 ; i < active_sfd ; i++) ++ { ++ sfpoll_flags=sfvalue(sfd[i]); ++ ++ /* ++ * We have to loop over all entries ++ * because single fd may be polled ++ * multiple times in different pollfd ++ * entries ++ */ ++ for (j=0 ; j < numpollfd ; j++) ++ { ++ if (pollstat[j].sfio.sfd == sfd[i]) ++ pollstat[j].sfio.flags=sfpoll_flags; ++ } ++ } ++ } ++ } ++ ++ /* ++ * Create --eventarray array on demand ++ */ ++ if (eventarrayname) ++ { ++ np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_ARRAY|NV_NOFAIL, "%s", eventarrayname); ++ if (!np) ++ { ++ errormsg(SH_DICT, ERROR_ERROR, "could not create eventarray variable %s", eventarrayname); ++ goto done_error; ++ } ++ ++ nv_close(np); ++ } ++ ++ /* ++ * Make sure we poll on "raw" tty to catch _every_ keystroke... ++ */ ++ if (ttyraw) ++ { ++ for (i=0 ; i < numpollfd ; i++) ++ { ++ fd=pollfd[i].fd; ++ if ((fd >=0) && (shp->fdstatus[fd]&IOTTY)) ++ tty_raw(fd, 1); ++ } ++ } ++ ++ /* ++ * ... then poll for events... ++ */ ++ n = poll_loop(context, pollfd, numpollfd, timeout); ++ ++ /* ++ * ... and restore the tty's to "cooked" mode ++ */ ++ if (ttyraw) ++ { ++ for (i=0 ; i < numpollfd ; i++) ++ { ++ fd=pollfd[i].fd; ++ if ((fd >=0) && (shp->fdstatus[fd]&IOTTY)) ++ tty_cooked(fd); ++ } ++ } ++ ++ if (n < 0) ++ { ++ /* |ERROR_system(0)| won't quit the builtin */ ++ errormsg(SH_DICT, ERROR_system(0), "poll(2) failure"); ++ retval=1; ++ } ++ ++ /* ++ * Write results back into the array ++ */ ++ for (i=0 ; i < numpollfd ; i++) ++ { ++ /* Adjust data in |pollfd[i]| to reflect sfio stream status (if requested) */ ++ if (pollsfio) ++ { ++ if ((pollfd[i].events & POLLIN) && (pollstat[i].sfio.flags & SF_READ)) ++ pollfd[i].revents |= POLLIN; ++ if ((pollfd[i].events & POLLOUT) && (pollstat[i].sfio.flags & SF_WRITE)) ++ pollfd[i].revents |= POLLOUT; ++ } ++ ++ set_compound_revents(shp, parrayname, &pollstat[i], &pollfd[i]); ++ ++ if (eventarrayname && pollfd[i].revents) ++ { ++ sprintf(buff, "%s+=( '%s' )", eventarrayname, pollstat[i].array_subscript); ++ sh_trap(buff, 0); ++ } ++ } ++ ++ goto done; ++ ++done_error: ++ retval=1; ++done: ++ if (array_np) ++ nv_close(array_np); ++ if (strstk) ++ stkclose(strstk); ++ ++ return(retval); ++} +--- src/cmd/ksh93/data/builtins.c ++++ src/cmd/ksh93/data/builtins.c 2012-08-06 21:25:47.000000000 +0000 +@@ -109,6 +109,7 @@ const struct shtable3 shtab_builtins[] = + #endif /* JOBS */ + "false", NV_BLTIN|BLT_ENV, bltin(false), + "getopts", NV_BLTIN|BLT_ENV, bltin(getopts), ++ "poll", NV_BLTIN, bltin(poll), + "print", NV_BLTIN|BLT_ENV, bltin(print), + "printf", NV_BLTIN|BLT_ENV, bltin(printf), + "pwd", NV_BLTIN, bltin(pwd), +--- src/cmd/ksh93/include/builtins.h ++++ src/cmd/ksh93/include/builtins.h 2012-08-06 21:25:47.000000000 +0000 +@@ -100,6 +100,7 @@ extern int b_wait(int, char*[],Shbltin_t + extern int b_whence(int, char*[],Shbltin_t*); + + extern int b_alarm(int, char*[],Shbltin_t*); ++extern int b_poll(int, char*[],Shbltin_t*); + extern int b_print(int, char*[],Shbltin_t*); + extern int b_printf(int, char*[],Shbltin_t*); + extern int b_pwd(int, char*[],Shbltin_t*); +--- src/cmd/ksh93/tests/builtin_poll.sh ++++ src/cmd/ksh93/tests/builtin_poll.sh 2012-08-07 01:22:35.000000000 +0000 +@@ -0,0 +1,100 @@ ++######################################################################## ++# # ++# This software is part of the ast package # ++# Copyright (c) 2009-2012 Roland Mainz # ++# and is licensed under the # ++# Eclipse Public License, Version 1.0 # ++# by AT&T Intellectual Property # ++# # ++# A copy of the License is available at # ++# http://www.eclipse.org/org/documents/epl-v10.html # ++# (with md5 checksum b35adb5213ca9657e911e9befb180842) # ++# # ++# # ++# Roland Mainz # ++# # ++######################################################################## ++ ++# ++# Copyright (c) 2009, 2012, Roland Mainz. All rights reserved. ++# ++ ++# ++# Test module to check the ksh93 "poll" builtin ++# ++ ++# test setup ++function err_exit ++{ ++ print -u2 -n '\t' ++ print -u2 -r ${Command}[$1]: "${@:2}" ++ (( Errors++ )) ++} ++alias err_exit='err_exit $LINENO' ++ ++set -o nounset ++Command=${0##*/} ++integer Errors=0 ++ ++typeset ocwd ++typeset tmpdir ++ ++# create temporary test directory ++ocwd="${PWD}" ++tmpdir="${ mktemp -t -d 'test_builtin_poll.XXXXXXXX' ; }" || err_exit 'Cannot create temporary directory.' ++ ++cd "${tmpdir}" || { err_exit "cd ${tmpdir} failed." ; exit $((Errors<125?Errors:125)) ; } ++ ++ ++# basic tests ++function test1 ++{ ++ compound d1=( ++ compound -A u=( ++ [y]=( integer fd=5 ; compound events=( pollin='true' ) revents=() ) ++ [x]=( integer fd=5 ; compound events=( pollin='true' ) revents=() ) ++ ) ++ ) ++ ++ # test 1: ++ print -C d1 >'testdata.cpv' ++ cat '/dev/zero' | $SHELL -o errexit -c 'builtin poll ; read -C <"testdata.cpv" d1 ; redirect 5<&0 ; poll -e d1.res -t 5. d1.u ; print -C d1 >"testdata.cpv"' >'log.txt' 2>&1 || err_exit "poll returned non-zero exit code $?" ++ unset d1 ; read -C d1 <'testdata.cpv' || err_exit 'Cannot read test data.' ++ [[ "$(< 'log.txt')" == '' ]] || err_exit "Excepted empty stdout/stderr, got $(printf '%q\n' "$(< 'log.txt')")" ++ [[ "${d1.u[x].revents.pollin-}" == 'true' ]] || err_exit "d1.u[x].revents contains '${d1.u[x].revents-}', not 'POLLIN'" ++ [[ "${d1.u[y].revents.pollin-}" == 'true' ]] || err_exit "d1.u[y].revents contains '${d1.u[y].revents-}', not 'POLLIN'" ++ [[ "${d1.res[*]-}" == 'x y' ]] || err_exit "d1.res contains '${d1.res[*]-}', not 'x y'" ++ ++ rm 'testdata.cpv' 'log.txt' ++ ++ # test 2: ++ unset d1.res ++ d1.u[z]=( integer fd=5 ; compound events=( pollout='true' ) revents=() ) ++ ++ print -C d1 >'testdata.cpv' ++ $SHELL -o errexit -c 'builtin poll ; read -C <"testdata.cpv" d1 ; { poll -e d1.res -t 5. d1.u ; } 5<"/dev/null" 5>"/dev/null" ; print -C d1 >"testdata.cpv"' >'log.txt' 2>&1 || err_exit "poll returned non-zero exit code $?" ++ unset d1 ; read -C d1 <'testdata.cpv' || err_exit 'Cannot read test data.' ++ ++ [[ "$(< 'log.txt')" == '' ]] || err_exit "Excepted empty stdout/stderr, got $(printf '%q\n' "$(< 'log.txt')")" ++ [[ "${d1.u[x].revents.pollin-}" == 'true' ]] || err_exit "d1.u[x].revents contains '${d1.u[x].revents-}', not 'POLLIN'" ++ [[ "${d1.u[y].revents.pollin-}" == 'true' ]] || err_exit "d1.u[y].revents contains '${d1.u[y].revents-}', not 'POLLIN'" ++ [[ "${d1.u[z].revents.pollout-}" == 'true' ]] || err_exit "d1.u[z].revents contains '${d1.u[z].revents-}', not 'POLLOUT,'" ++ [[ "${d1.res[*]-}" == 'x y z' ]] || err_exit "d1.res contains '${d1.res[*]-}', not 'x y z'" ++ ++ rm 'testdata.cpv' 'log.txt' ++ ++ return 0 ++} ++ ++# run tests ++builtin 'poll' || err_exit 'poll builtin not found.' ++ ++test1 ++ ++# cleanup ++cd "${ocwd}" ++rmdir "${tmpdir}" || err_exit "Cannot remove temporary directory ${tmpdir}." ++ ++ ++# tests done ++exit $((Errors<125?Errors:125)) diff --git a/cpp.patch b/cpp.patch new file mode 100644 index 0000000..a73b5d4 --- /dev/null +++ b/cpp.patch @@ -0,0 +1,24 @@ +iffe depends on cc -E not inserting newlines between tokens + +Index: ksh93/src/cmd/INIT/iffe.sh +=================================================================== +--- ksh93.orig/src/cmd/INIT/iffe.sh ++++ ksh93/src/cmd/INIT/iffe.sh +@@ -3427,7 +3427,7 @@ $src + (eval "$src") <&$nullin || e=1 + ;; + mac*|nomac*) +- if compile $cc -E $tmp.c <&$nullin >$tmp.i ++ if compile $cc -E -P $tmp.c <&$nullin >$tmp.i + then sed -e '/<<[ ]*".*"[ ]*>>/!d' -e 's/<<[ ]*"//g' -e 's/"[ ]*>>//g' $tmp.i + else e=1 + fi +@@ -3718,7 +3718,7 @@ $inc + <<\"#define $v\">> $v <<\"/* native $v */\">> + <<\"#endif\">> + #endif" > $tmp.c +- if compile $cc -E $tmp.c <&$nullin >$tmp.i ++ if compile $cc -E -P $tmp.c <&$nullin >$tmp.i + then sed -e '/<<[ ]*".*"[ ]*>>/!d' -e 's/<<[ ]*"//g' -e 's/"[ ]*>>//g' $tmp.i > $tmp.t + if test -s $tmp.t + then success diff --git a/ifs-crash.sh b/ifs-crash.sh new file mode 100644 index 0000000..117540c --- /dev/null +++ b/ifs-crash.sh @@ -0,0 +1,56 @@ +#!/bin/ksh + +typeset -lui count=${1:-4} + +function g +{ + IFS= +} + +function f +{ + typeset IFS + (g) + : $V +} + +while ((count-- > 0)) +do + f +done + +function crash +{ + typeset L_FILE + typeset L_VALIDATION + typeset L_VARIABLE + typeset L_MOD IFS + + OS=$(uname) +} + +crash + +function crash2 +{ + typeset IFS + IFS='\t' + true + unset IFS + echo a b c | while read x y z; do + echo $x + echo $y + echo $z + done +} + +crash2 + +echo a b c | while read x y z; do + echo $x + echo $y + echo $z +done + +echo "[${0##*/}: success]" +# end here diff --git a/ksh-locale.patch b/ksh-locale.patch new file mode 100644 index 0000000..fc9cd2d --- /dev/null +++ b/ksh-locale.patch @@ -0,0 +1,8 @@ +--- lib/package/ast-ksh.pkg ++++ lib/package/ast-ksh.pkg 2011-07-05 16:29:57.891926052 +0000 +@@ -1,4 +1,4 @@ +-ast-ksh :PACKAGE: ksh93 libast libcmd libcoshell libsum libdll ++ast-ksh :PACKAGE: msgcc ksh93 libpp libast libcmd libcoshell libsum libdll + + :COVERS: ksh + diff --git a/ksh-rpmlintrc b/ksh-rpmlintrc new file mode 100644 index 0000000..800f936 --- /dev/null +++ b/ksh-rpmlintrc @@ -0,0 +1,14 @@ +addFilter(".*binary-or-shlib-defines-rpath.*/lib/ast/.*\.so.*") +addFilter(".*binary-or-shlib-defines-rpath.*/lib/ast/bin/shcomp.*") +addFilter(".*binary-or-shlib-defines-rpath.*/lib/ast/bin/ksh.*") +addFilter(".*binary-or-shlib-defines-rpath.*/lib64/ast/.*\.so.*") +addFilter(".*binary-or-shlib-defines-rpath.*/lib64/ast/bin/shcomp.*") +addFilter(".*binary-or-shlib-defines-rpath.*/lib64/ast/bin/ksh.*") +addFilter(".*suse-filelist-forbidden-devel-in-lib.*/lib/ast/.*\.so.*") +addFilter(".*suse-filelist-forbidden-devel-in-lib.*/lib64/ast/.*\.so.*") +addFilter(".*devel-file-in-non-devel-package.*/lib/ast/.*\.so") +addFilter(".*devel-file-in-non-devel-package.*/lib64/ast/.*\.so") +addFilter(".*script-without-shebang.*/usr/share/ksh/fun/.*") +addFilter(".*no-rpm-opt-flags.*ldtest.c.*") +addFilter(".*invalid-suse-version-check.*") +addFilter(".*obsolete-suse-version-check.*") diff --git a/ksh.changes b/ksh.changes new file mode 100644 index 0000000..994f5c9 --- /dev/null +++ b/ksh.changes @@ -0,0 +1,2843 @@ +------------------------------------------------------------------- +Thu Aug 1 14:04:27 CEST 2024 - mls@suse.de + +- fix segfault in variable substitution [bsc#1129288] + new patch: ksh93-putval.dif +- fix untrusted environment execution [bsc#1160796] [CVE-2019-14868] + new patch: ksh93-untrustedenv.dif + +------------------------------------------------------------------- +Mon May 13 16:38:57 CEST 2024 - mls@suse.de + +- remove no longer needed qemu workaround + deleted patch: ksh-qemu.patch +- do not use posix_spawn as it lacks proper job handling [bsc#1224057] + new patch: ksh93-no-posix_spawn.dif + +------------------------------------------------------------------- +Thu Feb 22 12:41:40 UTC 2024 - Dominique Leuenberger + +- Use %patch -P N instead of deprecated %patchN. + +------------------------------------------------------------------- +Tue Nov 7 08:49:59 UTC 2023 - Dominique Leuenberger + +- Fix build with RPM 4.19: unnumbered patches are no longer + supported. + +------------------------------------------------------------------- +Tue Dec 27 13:06:43 UTC 2022 - Ludwig Nussel + +- Replace transitional %usrmerged macro with regular version check (boo#1206798) + +------------------------------------------------------------------- +Wed Mar 31 08:38:40 UTC 2021 - Jan Engelhardt + +- Remove BuildRequires: bind-libs. Requiring libs this way + is just wrong. + +------------------------------------------------------------------- +Wed Jan 27 12:50:38 UTC 2021 - Ludwig Nussel + +- prepare usrmerge (boo#1029961) +- clean up SLE11 compat sections + +------------------------------------------------------------------- +Thu Jan 21 15:03:07 UTC 2021 - Thorsten Kukuk + +- remove pwdutils buildrequires, it's not needed and pwdutils got + dropped many years ago + +------------------------------------------------------------------- +Fri Nov 13 14:10:43 CET 2020 - mls@suse.de + +- remove sys/sysctl.h include as it no longer exists in linux + new patch: ksh93-no-sysctl.dif + +------------------------------------------------------------------- +Fri Sep 6 17:25:26 CEST 2019 - mls@suse.de + +- fix build by removing -Werror=return-type and using + -ffat-lto-objects + +------------------------------------------------------------------- +Wed Dec 20 13:18:32 CET 2017 - mls@suse.de + +- fix build with new glibc versions + new patch: ksh93-filedefined.dif + +------------------------------------------------------------------- +Wed Oct 12 13:23:14 CEST 2016 - mls@suse.de + +- fix locking error in spawn implementation [bnc#988213] + new patch: ksh93-spawnlock.dif +- make patch ordering the same as in sle-11 + +------------------------------------------------------------------- +Tue Jul 5 14:49:03 CEST 2016 - mls@suse.de + +- own the ksh files in /etc/alternatives [bnc#987362] [bnc#962069] +- fix leak in optimize processing [bnc#982423] + new patch: ksh93-optimizeleak.dif +- fix editor prediction code garbling input [bnc#964966] + new patch: ksh93-edpredict.dif + +------------------------------------------------------------------- +Wed Dec 16 16:00:53 CET 2015 - mls@suse.de + +- add ast suffix to optbin manpages to prevent file conflicts +- fix fd leak when doing redirects in a subshell [bnc#954856] + new patch: ksh93-redirectleak.dif +- rewrite ksh93-backtick.dif to a more correct version + [bnc#953533] [bnc#955221] +- also tweak ksh93-backtick.dif so that the pipe is drained after + io_restore is called. + +------------------------------------------------------------------- +Tue Sep 15 18:07:09 CEST 2015 - mls@suse.de + +- fix freeing memory twice if an array is turned into an + compound variable and then unset [bnc#924043] + new patch: ksh93-nvtree-free.dif +- backport fix for segmentation fault with 'typeset -RF' + new patch: ksh93-int16double.dif +- backport hanging command substitution with large output fix from + upstream [bnc#887320] [bnc#926172] [bnc#934437] + new patch: ksh93-backtick.dif +- backport job list corruption fix from ksg93v [bnc#924318] + new patch: ksh93-jpold.dif + +------------------------------------------------------------------- +Fri Jun 12 13:54:45 CEST 2015 - mls@suse.de + +- go back to ksh93u to have a stable version in SLE-12 + use 93vu as version so that the software stack sees this + as an update. (FATE#319107, bsc#939252) +- add back the following patches: + * astksh_builtin_poll20120806_001.diff + * ksh93-backticks.dif + * ksh93-crashes.dif + * ksh93-dttree-crash.dif + * ksh93-fdstatus.dif + * ksh93-heredoclex.dif + * ksh93-jobs.dif + * ksh93-sfio.dif + * ksh93-uninitialized.dif +- fix stk aliasing code [bnc#844071] + new patch: ksh93-stkalias.dif +- fix stk restoration in sh_exec [bnc#844071] + new patch: ksh93-stkfreeze.dif +- make a unknown location fatal in stkset so that we get a core + dump right away instead of later in an unrelated part of code + new patch: ksh93-stkset-abort.dif +- fix build with std malloc + new patch: ksh93-malloc-hook.dif +- backport job locking code fix + new patch: ksh93-joblock.dif +- disable vfork, use fork instead + new patch: ksh93-disable-vfork.dif +- fix crash when the subshell number overflows [bnc#893031] + new patch: ksh93-longenv.dif +- fix path normalization in cd command [bnc#867401] + new patch: ksh93-cdpwd.dif +- fix segfault in dirname when cwd is gone [bnc#852160] + new patch: ksh93-subshellpwd.dif +- Fix ksh using wrong files is some elements in the path do not + exist [bnc#899014] + new patch: ksh93-path-skip.dif + +------------------------------------------------------------------- +Thu Jun 11 10:42:59 UTC 2015 - schwab@suse.de + +- cpp.patch: fix use of cc -E without -P + +------------------------------------------------------------------- +Fri Aug 1 06:58:17 UTC 2014 - werner@suse.de + +- Disable patch ksh93-backticks.dif as it breaks several test cases + +------------------------------------------------------------------- +Thu Jul 31 12:42:49 UTC 2014 - dimstar@opensuse.org + +- Rename rpmlintrc to %{name}-rpmlintrc. + Follow the packaging guidelines. + +------------------------------------------------------------------- +Fri Jul 18 14:14:23 UTC 2014 - werner@suse.de + +- Add patch ksh93-backticks.dif to allow the ksh to use more than + 65536 characters in the output of old fashion `...` commands (bnc#887320) + +------------------------------------------------------------------- +Thu Jul 17 11:07:34 UTC 2014 - werner@suse.de + +- Skip signal test as currently ksh93 uses malloc() within signal + handlers and this cause deadlocks even with libast memory + management + +------------------------------------------------------------------- +Tue Jul 8 12:54:51 UTC 2014 - werner@suse.de + +- Update to 2014-06-26 of ksh93v- version + * A bug on some systems in which cd to a directory without execute + permission would not fail has been fixed. + * The BASH_SOURCE variable was added when ksh is run in bash mode. + * The -D and -E options have been added to the complete builtin. + * References to dgk@research.att.com were deleted. + * The -l flag to trap and the -p flag to umask were added as in bash. + * In bash mode ${!parameter} is treated like ${$parameter}. + * Fixed a bug in which eval inside a dot script invoked by a profile file + terminated the dot script prematurely after running the eval command. + * Added parameter expansion operator ${$parameter} for variables and + positional parameters. + * Added -a option to read which is equivalent to -A. + * Fixed a bug in builtin -p. + * Added -n option to builtin to disable builtins. + * Fixed a couple of file completion bugs. + * When compiled with the SHOPT_BASH and run with the name bash, + the shell now uses dynamic scoping for name() and function name. + In addition the builtins declare and local are supported. + The SHOPT_BASH option is on by default in the Makefile. + More work remains with the bash compatibility option. + * Fixed a bug in vi command completion in which tab did not work + after a space. + * Replaced the -p option for read with -p prompt. For backword + compatibility, if a coprocess is running and prompt begins with - + or is a valid variable name, -p causes the read from a pipe. + * Modified the -u option for read and print so that it accepts the + option argument p to indicate the coprocess file descriptor. +- Remove patch ksh93-cd_pwd.dif and ksh93-jobs.dif as now upstream + +------------------------------------------------------------------- +Fri Jun 27 10:29:17 UTC 2014 - werner@suse.de + +- Add patches + ksh93-cd_pwd.dif to see error if a directory does not have execution bit + ksh93-jobs.dif to avoid a crash due broken optimization in job locking + +------------------------------------------------------------------- +Thu May 15 07:02:32 UTC 2014 - werner@suse.de + +- Add SIGALRM to sigexec +- Enforce reentrant usage of glibc + +------------------------------------------------------------------- +Wed May 14 11:07:39 UTC 2014 - werner@suse.de + +- Update to 2014-05-09 of ksh93v- version + * A bug in the option parser which could cause 'X -a v=((...)...) to + core dump has been fixed. + * A change to improve the performance of appending an element to an + array has been fixed. + * A complilation option to add programmable completion with the two + new builtins, complete and compgen has been added. It should behave + the same as it does with bash. Please try this out and report any + problems you find. Use compgen --man and complete --man to get the + man pages. Use the bash documentation for now for information about + programmable completion. The compilation is on by default for now. + 14-05-12 libast: + * features/lib: mmap() error return may be ((caaddr_t)0) or ((caaddr_t)-1) + * misc/optget.c: save opt_info state in case infof callout munges it + * misc/spawnvex.c: fix nil pointer deref +- Modified patch ksh93-crashes.dif to remove fixed issues + +------------------------------------------------------------------- +Tue Apr 29 11:47:11 UTC 2014 - werner@suse.de + +- Update to 2014-04-15 of ksh93v- version + * A bug in which type name starting with the letter a, did not + allow instances to be created has been fixed. + * A bug which caused a syntax error when a here-doc was embedded + in `` command substitution has been fixed. + * A bug in `` command substition of a pipeline which could cause + memory problems has been fixed. + * A bug in which the assignment A=() when A is an index array of types + did not eliminate the zero-th element has been fixed. + * A bug in which the braceexpand option was ignored when noglob was + on has been fixed. + * A bug in which a timer alarm during a built-in could cause a core + dump has been fixed. + * A bug in which creating an empty array of a type variable with + required fields has been fixed + * A bug which occurs in an interactive shell when a file is opened as + file descriptor 3 for reading which causes a subsequent read + command to fail to read a line from the file has been fixed. + 14-04-15 libast: + * sfio/sfcvt.c: fix flot bug that printed |x|<1 as 0 +- Modified patch ksh93-crashes.dif to fix two new issues + +------------------------------------------------------------------- +Wed Apr 23 10:10:17 UTC 2014 - dmueller@suse.com + +- avoid hanging build on probe run + +------------------------------------------------------------------- +Fri Apr 11 15:07:59 UTC 2014 - werner@suse.de + +- Update to 2014-03-01 of ksh93v- version + * The description of .sh.match in the sh.1 man page was fixed. + * A typeset -p bug for an associative array of types has been fixed. + * A process substitution bug which caused a process to hang has been + fixed. + * Another bug in which extended regular expressions give with the =~ + operator in [[...]] gave syntax errors with multiple (...){...} has + been fixed. + * The value of errno is now saved and restored during shell interrupt + handlers. + * A bug in which a read from a script invoked with set -m could stop + when trying to read, and cause the parent to try to restart which + causes a loop has been fixed. + * A bug in the right shift operator in arithmetic expressions when the + shift count is greated then the number of bits in a long integer has + been fixed. + * Another memory leak which occured for functions defined in subshells + has been fixed. +- Add patch ksh93-crashes.dif to fix various crashes as shown in + bnc #844071 + * Avoid double free() as well as sfclose() + +------------------------------------------------------------------- +Thu Feb 20 12:29:05 UTC 2014 - werner@suse.de + +- Update to 2014-01-14 of ksh93v- version + 13-12-05 cmd/builtin: + * Round about 10 bugs had been fixed + 14-01-14 --- Release ksh93v- --- + * More than 120 bugs had been fixed + 14-01-14 libast: + * Round about 80 changes + 13-12-05 libcmd: + * Round about 35 changes + 13-07-24 libcoshell: + * Two fixes had been done +- Deleted the following patches + * astksh_builtin_poll20120806_001.diff + * ksh93-dttree-crash.dif + * ksh93-fdstatus.dif + * ksh93-heredoclex.dif + * ksh93-jobs.dif + * ksh93-pwd.dif + * ksh93-sfio.dif + * ksh93-uninitialized.dif + as now upstream +- Modify or extend the following patches + * ksh-locale.patch + * ksh-qemu.patch + * ksh93-alias-k.dif + * ksh93-aso.dif + * ksh93-builtin.dif + * ksh93-compat.dif + * ksh93-env.dif + * ksh93-foreground-prgrp.dif + * ksh93-gcc.dif + * ksh93-heredoc.dif + * ksh93-ia64.dif + * ksh93-limit-name-len.dif + * ksh93-pathtemp.dif + * ksh93-profile.dif + * ksh93-reg.dif + * ksh93-s390.dif + * ksh93-shift_ijs.dif + * ksh93-signals.dif + * ksh93-suid_exec.dif + * ksh93-test.dif + * ksh93-typedef.dif + * ksh93-unset-f.dif + * ksh93-vi.dif + * ksh93-vm.dif + * ksh93.dif + * workaround-stupid-build-system.diff + to work with new ksh93v release + +------------------------------------------------------------------- +Sat Feb 8 13:13:22 UTC 2014 - gber@opensuse.org + +- adjust update-alternative usage to packaging policy + (see http://lists.opensuse.org/opensuse-packaging/2014-02/msg00024.html) + +------------------------------------------------------------------- +Fri Dec 6 21:13:42 UTC 2013 - matz@suse.de + +- Recognize ppc64le (setting HOSTTYPE to powerpc64le) + +------------------------------------------------------------------- +Fri Nov 29 15:45:44 UTC 2013 - werner@suse.de + +- Add patch ksh93-pwd.dif to fix crash if cwd is gone (bnc#852160) + +------------------------------------------------------------------- +Wed Nov 20 11:42:55 UTC 2013 - werner@suse.de + +- Make typeset builtin not crash but show an error (bnc#851300) + +------------------------------------------------------------------- +Mon Nov 18 16:04:27 UTC 2013 - werner@suse.de + +- Extend patch ksh93-sfio.dif which may avoid yet an other crash + +------------------------------------------------------------------- +Thu Nov 14 13:55:13 UTC 2013 - werner@suse.de + +- Finally the last changes had fixed the crash reportd in bnc#844071 + +------------------------------------------------------------------- +Tue Oct 29 17:44:05 UTC 2013 - gber@opensuse.org + +- deliver %{_sysconfdir}/ksh.kshrc as a packaged symlink on + openSUSE >= 13.2 + +------------------------------------------------------------------- +Fri Oct 25 14:07:57 UTC 2013 - werner@suse.de + +- Add missing sfsetbuf() in patch ksh93-fdstatus.dif +- Rework patch ksh93-dttree-crash.dif +- Rework patch ksh93-uninitialized.dif + +------------------------------------------------------------------- +Tue Oct 22 11:58:21 UTC 2013 - werner@suse.de + +- Change patch ksh93-fdstatus.dif by adding some more EINTR wrapper + +------------------------------------------------------------------- +Fri Oct 18 12:21:58 UTC 2013 - werner@suse.de + +- Add patch ksh93-sfio.dif as on overlapping memory areas there + should memmove be used instead of memcopy (backport 2013-10-10) + +------------------------------------------------------------------- +Fri Oct 18 10:41:05 UTC 2013 - werner@suse.de + +- Change patch ksh93-fdstatus.dif which may solve bnc#844071 +- Add patch ksh93-fs3d.dif to avoid crash due dummy function call + fs3d_mount(3ast) during valgrind sessions +- Add patch ksh93-uninitialized.dif to avoid sometimes random + errors on busy systems which may also related to bnc#844071 + +------------------------------------------------------------------- +Thu Sep 19 08:43:37 UTC 2013 - werner@suse.de + +- Make vmbalance awk script more clear for small vm page sizes + +------------------------------------------------------------------- +Wed Sep 18 11:09:34 UTC 2013 - werner@suse.de + +- Extend patch ksh93-fdstatus.dif to solve bnc#835885 +- Modify patch ksh93-builtin.dif to reduce timeouts of pty utility + +------------------------------------------------------------------- +Tue Aug 13 09:59:45 UTC 2013 - dmueller@suse.com + +- rediff ksh-qemu.patch + +------------------------------------------------------------------- +Thu Aug 1 12:32:53 UTC 2013 - werner@suse.de + +- Use own subsection 1ast in manual section 1 to avoid name space + conflicts + +------------------------------------------------------------------- +Tue Jun 11 16:55:30 UTC 2013 - werner@suse.de + +- Add patch ksh93-alias-k.dif as fix for bnc#824187 + +------------------------------------------------------------------- +Tue Apr 23 12:31:35 UTC 2013 - werner@suse.de + +- Add patch ksh93-fdstatus.dif as fix for bnc#814135 and bnc#808449 + +------------------------------------------------------------------- +Tue Mar 19 16:48:37 UTC 2013 - werner@suse.de + +- Add patch ksh93-typedef.dif as found during debugging + +------------------------------------------------------------------- +Tue Mar 19 15:14:00 UTC 2013 - werner@suse.de + +- Make Shift_JIS patch more reliable as requestef from upstream +- Drop remaining part of the patch ksh93-zerofill.dif for zerofilled + variables (bnc#785360 as the first part of the patch is upstream + together with an other change. This fix a side effect of cutting + variables if TMOUT is used (bnc#808956) + +------------------------------------------------------------------- +Thu Feb 28 13:10:09 UTC 2013 - werner@suse.de + +- Add patch ksh93-heredoclex.dif: substitution in here-document + results in syntax error (bnc#804998) + +------------------------------------------------------------------- +Fri Feb 15 14:40:41 UTC 2013 - werner@suse.de + +- Avoid segmentation fault on typeset on ENV variable (bnc#803613) + +------------------------------------------------------------------- +Thu Feb 7 13:56:58 UTC 2013 - werner@suse.de + +- Do not use Shift-JIS work around with UTF-8 + +------------------------------------------------------------------- +Tue Feb 5 17:41:08 UTC 2013 - werner@suse.de + +- Update to 2012-08-01 of ksh93u+ for bugfix version + 12-08-01 A bug that ignored interrupts for some builtins (e.g. cmdtst::grep) + that read from stdin has been fixed. + 12-08-01 A bug that interpreted "cd .foo" as "cd foo" has been fixed. + 12-07-30 Added automatic restart for EINTR for ioctl, tcgetattr, and tcsetattr. + 12-07-23 A scoping error with namrefs to compound associative arrays has + been fixed. + 12-07-20 A bug where builtin -d /path/foo deleted foo has been fixed. + 12-07-18 A bug in which /dev/stdout did not work in command substitution on + some systems has been fixed. + 12-07-17 A bug in which the restricted option set in a subshell prevented + some variables from getting restored when the subshell completed + has been fixed. + 12-07-09 A bug in which the directory is not restored after a subshell changes + the name of the directory for subshells executed in the same process + has been fixed. + 12-07-09 A bug in which file descriptors created with {n}< file were not being + closed has been fixed. + 12-07-09 The 12-04-04 fix for cd .. was not correct causing cd /etc;cd .. to + remain in /etc. This has been fixed. + 12-07-02 A bug in which builtin name did now work for builtins found in a + library added by builtin -f lib has been fixed. + 12-07-02 A bug in the edit modes which after a directory did not refresh + the input line has been fixed. + 12-07-02 A bug in which an exit status > 256 corresponding to a signal was + not returned by a function to indicate a signal exit has been fixed. + 12-06-28 Fix ulimit -a to list (Kibytes) instead of (kbytes). + 12-06-27 Fix unitialized data reference for as first char in --vi mode. + 12-06-26 The formatting of printf "%q" for multibyte locales has changed to + output using \u[xxx] format for valid wide characters. + 12-06-25 The size limit for read -N and read -n has been raised to INT_MAX. + 12-06-22 A bug in which an exit trap set in a subshell might not be triggered + when the last command was a simple executable has been fixed. + 12-06-22 A bug which could cause the shell to hang when a coprocess exits + while a command inside a command substitution is reading from it has + been fixed. + 12-06-21 +ksh new accepts for commands of the form for i; do;...;done + 12-06-19 Tab completion after a / when there is only one match not completes + with that match rather than generating a menu of matches. + 12-06-19 A bug in which patterns containing {...} where not processed + correctly inside ${var/pattern/string} has been fixed. + 12-06-18 Code modified to eliminate fts_notify variable. + 12-06-15 Change the .paths plugin/builtin library variable name from + BUILTIN_LIB to PLUGIN_LIB to prevent new plugin_version() aware + -lcmd from causing older non-plugin_version() aware ksh to dump core. + 12-06-14 builtin without argument no longer lists .sh.tilde as a built-in. + 12-06-12 For assignments if the form x=(foo bar), foo is only check for an + alias if it is float, integer, compound, or nameref. + 12-06-12 +The shell supports 64 bit i-nodes even for 32 bit binaries. + 12-06-11 A bug wth >; redirection systems for which vfork() was the same a + fork() has been fixed. + 12-06-11 A bug in path lookup that ignored buffer boundaries has been fixed. + 12-06-08 typeset -a var and typeset -A var, first unset var when var is + a compound variable. + 12-06-08 A bug in which running shcomp on a program containg namespace + could core dump has been fixed. + 12-06-06 A bug in which unset of an associative array of compound variables + did not completely unset the variable has been fixed. + 12-06-06 A bug in which exporting left or right justfied fields could loose + the field width has been fixed. + 12-06-06 A bug on Solaris11 in which >; did not work for /dev/null was fixed. + 12-06-05 A race condition which occured when stopping a builtin command + invoked from a subshell has been fixed. + 12-06-05 A bug with appending elements to an empty indexed array has been + fixed. + 12-06-04 A bug in which continuing a stopped builtin could cause it to + terminate has been fixed. + 12-06-04 By default, builtins added at runtime will restore the current + directory if they are killed or stopped. + 12-06-04 A bug in handling \\ in read has been fixed. + 12-05-31 Use getrlimit64/setrlimit64 on systems that support it. + 12-05-31 Fix 64 bit big-endian arithmentic bug that mishandled nan and inf. + 12-05-31 Handle ECONNRESET like EPIPE. + 12-05-31 Change .paths parse to use only the last BUILTIN_LIB from the top + and treat BUILTIN_LIB value as a ':' separated list of lib names. + 12-05-29 Fix BUILTIN_LIB binding bug that ignored subsequent lookups. + 12-05-29 shtests: --nocompile omits the compile test and --compile does only + the compile test. + 12-05-25 A command subsitution containing a here-document that itself contains + a here-document no longer hangs. + 12-05-24 When the redirection operatory >; is directed to a symlink, it now + overwrites the file named by the link rather than the link. + 12-05-21 +Added printf formats %(type)q where type can be html, url, pattern, + ere, or csv. + 12-05-18 A bug with appending elements to an indexed array has been fixed. + 12-05-18 The exit status from getopts --man interactively was 0 instead of 2 + and has been fixed. + 12-05-18 Another bug with SHOPT_EDPREDICT which could cause a core dump has + been fixed. + 12-05-17 A bug with fixed size arrays which could cause a core dump has been + fixed. + 12-05-17 A bug in which the here-document <<< $(^V, the terminal was not + restored to insert mode after a character is entered has been fixed. + 12-04-27 A bug in which old attributes were not cleared when assigning a + value using typeset has been fixed. + 12-04-26 +Enabled multiline editing by default. set +o multiline can disable. + 12-04-25 The 12-04-17 PATH fix created a new bug which was fixed. + 12-04-25 Fixed a big memory leak problem in which unsetting compound variables + did not free all the space. + 12-04-25 A bug in which test ! ! ! was treated as an error has been fixed. + 12-04-24 A bug with print -v for a compound variable that contained fixed + arrays which prevented the output from being used again as input + has been fixed. + 12-04-23 +kill provides the STKFLT signal on systems that support it. + 12-04-23 +The -L option was added to kill. The -L option is the same as -l + except that without arguments the output format is in the form of + a select menu. + 12-04-23 A bug in which the exit status for an interactive shell was always + 0 has been fixed. + 12-04-20 Entering blank lines interactively no longer resets the exit status. + 12-04-18 A bug in file completion in which the second tab completion on a file + would list the completion rather than inserting the completion has + been fixed. + 12-04-18 A bug in which "${arr[@]:i:j}" and "${@:i:j}" generated the empty + string when i was a valid subscript and j was <=0 rather than + generating nothing has been fixed. + 12-04-17 A bug in which read -d delim from a terminal did not respond to + interrupt and did not termrinate when the delimiter was entered + has been fixed. + 12-04-17 A bug in which a directory in PATH containing a .paths file that + contains a line with FPATH=dir, where dir does not exist could + cause the path search to fail has been fixed. + 12-04-16 A bug in which $(trap -p) did not display traps such as ERR and + DEBUG that are not associated with signals has been fixed. + 12-04-11 A bug in which unsetting a variable did not unset attributes when + the variable did not have a value has been fixed. + 12-04-11 A bug in which read -A for an array whose index is an enumeration + type, lost the enumeration type has been fixed. + 12-04-10 Shared libraries loaded from a library named by a BUILTIN_LIB= found + in a .paths file found in a directory on PATH now add builtins that + are associated with the directory in PATH containing the .paths file. + 12-04-09 Increased I/O buffer sizes for better performance. + 12-04-09 A bug in which the leading 0 was stripped from $x, when $x contained + a heximadecimal constant inside an arithmetic expression inside + a for or while loop. + 12-04-06 Modified namespaces to hand variabes FPATH, PATH, and OPTIND that + are defined in name spaces appropriately. This also fixed OPTIND + and OPTARG processing for functions. + 12-04-04 A bug in which cd .. fails when the current directory has been + renamed has been fixed. + 12-04-02 Made some namespace changes and added a regression test. + 12-03-30 A bug with namespaces in which PATH and FPATH set in a namespace was + not restored when leaving the namespace has been fixed. + 12-03-29 A bug in which appending an index array onto an array without elements + caused the first element to be 1 rather than 0 has been fixed. + 12-03-29 A bug which could cause a core dump when copying a large index array + has been fixed. + 12-03-28 The shell now generates an error message when the sizes with L, Z, and + R are > 32767 on 32 bit binaries instead of generating a core dump. + 12-03-28 A bug in left and right justification in which the width of invalid + characters was not taken as zero has been fixed. + 12-03-26 A bug in which typeset -p ref, when ref is a reference to an index + array element did not display the subscript has been fixed. + 12-03-23 A bug in lowercase and uppercase fields when expanding ${name:=val} + when name is the empty string has been fixed. + 12-03-22 A namespace bug in which a type t defined in namespace foo could not + be referenced outside the namespace as .foo.t has been fixed. + 12-03-22 A bug in name reference scoping in which a name function called from + another function is pass a name reference to a compound variable + instance to be created and the compound variable is in the global + scope. + 12-03-22 A bug in which ${ref[@}} did not behave like ${arr[i][@]} when + ref is a name reference to arr[i] has been fixed. + 12-03-21 A bug in which assigning a compound variable into arr[i], where + arr[i] is an array variable did not work correctly has been fixed. + 12-03-21 A bug with multi-dimenstional index arrays in which ${arr[i][j]} + could generate a bogus error message when i was > 9 has been fixed. + 12-03-21 A bug in which typeset v=foo, typeset -p v[0] generated a core dump + has been fixed. + 12-03-20 A bug in vi edit mode in which the sequence bar0il left the + cursor on the b rather than the a has been fixed. + 12-03-20 A bug which caused a core dump when defining a type with a field + as ' integer -a data=([0]=0)' has been fixed. + 12-03-19 Using typeset -a array when array is an associative arry not + generated an error message. + 12-03-19 typeset +a, typeset +A, and typeset +C not displays the variables + with the attributes a, A, and C respectively instead of an error. + 12-03-19 A bug in which typeset -pC, typeset -pa, and typeset -pA output all + variables rather than those of type C, a, or A only has been fixed. + 12-03-18 A bug in which unset foo where foo is a name reference to a compound + variable defined inside a function is not unset has been fixed. + 12-03-18 A bug with SHOPT_EDPREDICT which could cause a core dump when the + list of matches became empty has been fixed. + 12-03-15 The assignment, typeset -C foo=(a b c) now generates a syntax + error since a is not an assignment command. + 12-03-16 A bug in which an unset discipline from a variable defined in a + subshell is not invoked in the subshell has been fixed. + 12-03-08 The assignment typeset -a (x=1 y=2) now creates an index array + of two elements rathern than an array of one element which is + a compound variable. + 12-03-02 +The vi and emacs edit modes now list all the entries in a directory + when entering a for completion after a /. + 12-03-02 A bug in which a program that exits with value 12 when called + from a command substitution in which standard output has been + redirected caused the shell to hang has been fixed. + 12-03-01 A bug in which the shell could not parse [[ ']' == ~(E)[]] ]] + has been fixed. + 12-02-29 A bug in which ~user expanded first in a subshell prevented it + from expanding later in a program has been fixed. +- Remove our patches which are part of this update +- Re-add Shift-JIS patch to make it work again + +------------------------------------------------------------------- +Wed Jan 30 11:17:34 UTC 2013 - werner@suse.de + +- Finally found the reason for bnc#795324, that is avoid to free + data which is used lateron in the has tree of reloaded shell + functions. + +------------------------------------------------------------------- +Thu Jan 17 11:19:59 UTC 2013 - werner@suse.de + +- Avoid to skip builtin functions of the gcc if the libast does not + provide them. Maybe related, to bnc#795324, where a crash happens + in libc strcmp() if optimized for sse2 on AMD Opteron[tm] 6128. + +------------------------------------------------------------------- +Thu Dec 20 12:48:02 UTC 2012 - werner@suse.de + +- Add ksh93-dttree-crash.dif - Allow empty strings in (dt)trees + (bnc#795324) +- Modify ksh93-jobs.dif - make sure that tty is closed even if an + interrupt has been happen at close and also be aware that the + return value of tcgetpgrp() is greater than `1' that does not + match the process group ID of any existing process group (bnc#790315) + +------------------------------------------------------------------- +Fri Oct 26 15:05:09 UTC 2012 - coolo@suse.com + +- add explicit buildrequire on grof for man pages + +------------------------------------------------------------------- +Thu Oct 25 12:09:48 UTC 2012 - werner@suse.de + +- Make last patch smart that is use /dev/shm for temporary file + descriptors + +------------------------------------------------------------------- +Tue Oct 23 13:23:12 UTC 2012 - werner@suse.de + +- Add a workaround for filled /tmp file systems (bnc#786134) +- Check for subshell if tmp file can be used otherwise use a + a pipe (bnc#786134) +- Restore shell variables before any outpur will be placed in + a temp file or buffer (bnc#786134) + +------------------------------------------------------------------- +Fri Oct 19 15:06:50 UTC 2012 - werner@suse.de + +- Be able to export justified and zerofilled variables (bnc#785360) +- This requires that variables with this attributes should be really + cleared if unset + +------------------------------------------------------------------- +Wed Oct 17 09:22:34 UTC 2012 - werner@suse.de + +- Do not chrash if the value of an environment variable is NULL (bnc#785266) + +------------------------------------------------------------------- +Tue Sep 18 14:18:09 UTC 2012 - werner@suse.de + +- Add polling builtin patch (bnc #779888) + +------------------------------------------------------------------- +Fri Jul 13 12:47:35 UTC 2012 - agraf@suse.com + +- Fix qemu-user build by not evaluating ps output that doesn't reflect + what the virtual processes see + +------------------------------------------------------------------- +Wed Jun 6 12:16:52 UTC 2012 - werner@suse.de + +- Do not ignore backslashes/escapes for read builtin (bnc#765171) + +------------------------------------------------------------------- +Wed May 23 10:33:09 UTC 2012 - werner@suse.de + +- Better check on update for postun scriptlet and error correct with + an posttrans scriptlet, that is do not remove /etc/ksh.kshrc on + an update of an older ksh version (bnc#759730) + +------------------------------------------------------------------- +Thu Mar 15 12:32:36 UTC 2012 - werner@suse.de + +- Port and readd memory leak patch to put_ifs() of sh/init.c +- Make sigexec more smart to help the pty helper binary to work as + this helper is used in the test suite + +------------------------------------------------------------------- +Wed Mar 14 11:58:12 UTC 2012 - werner@suse.de + +- Update to 2012-02-29 of ksh93u+ for final version + 12-02-29 A bug which could lead to a core dump when more that four shared + libraries were added with the builtin command has been fixed. + 12-02-29 Fixed a few bugs which caused SIGCHLD to be blocked preventing + background jobs from being reaped until a foreground job was run. + 12-02-27 A bug in which sh -c for a simple command caused a fork() has been + fixed. + 12-02-27 A timing bug on systems such as AIX that doesn't support vfork() + that could cause the exist status to get lost has been fixed. + 12-02-22 A private file descriptor that was not close-on-exec for a command + substitution and has been fixed. + pty: + 12-02-28 pty.c: change --verbose[=level] to --debug=level + + libast: + 12-03-10 misc/optget.c: HELP_index for "PLUGIN" too + 12-02-29 include/shcmd.h: PLUGIN_VERSION 20111111 for cdt disc/meth change + 12-02-29 comp/spawnveg.c: fix sigcritical() to include waitpid() for internal child + 12-02-29 malloc.c: make __malloc_hook initialization thread safe + 12-02-24 comp/iconv.c: fix winix UTF-8 vs UCS-2 over-conversion + 12-02-24 astsa/*.h: clean up header guards + 12-02-24 astsa/astsa.omk: clean up standalone old make makefile interactions + 12-02-21 misc/cmdarg.c: fix bug that set argv[0] + + libcoshell: + 12-02-22 coinit.c: handle non-identifier export var names + + libpp: + 12-02-29 pp.probe: handle predefined function-like macro definitions + + libsum: + 12-02-29 sum-sha2.c: bitcount[] order reversed to allow a single noalias buffer copy + +------------------------------------------------------------------- +Mon Feb 27 15:24:02 UTC 2012 - werner@suse.de + +- Add CLOEXEC flag on file descriptors for pipe handling (bnc#704898) + +------------------------------------------------------------------- +Fri Feb 24 11:38:56 UTC 2012 - werner@suse.de + +- Remove check-build.sh as the memory leaks are fixed now + +------------------------------------------------------------------- +Tue Feb 21 10:43:58 UTC 2012 - werner@suse.de + +- Avoid possible problems pointed out by a gcc warning about overflow + in arraysubscript, that is use full size of structure Namval as + well as access this area at position 0 + +------------------------------------------------------------------- +Mon Feb 20 14:09:55 UTC 2012 - werner@suse.de + +- Update to 2012-02-14 of ksh93u+ which includes the real fix for + the IFS crash, the ulimit, and the mem leaks (bnc#743244, bnc#744355, + bnc#744589, and bnc#744992) as well as other fixes like: + 12-02-14 A bug in which ^Z did not stop a pipeline when the last component + was a shell built-in has been fixed. + 12-02-14 getconf("PATH") used to initialize ed(1) path. + 12-02-13 +In earlier version read from standard input would fail when called + from the KEYBD trap. Now read options -N, -n, and -t should work + when called from a KEYBD trap. + 12-02-13 If FCEDIT is not set and fc is invoked without the -e option, + ed will be invoked if found instead of /bin/ed. + 12-02-10 Another bug in the saving and restoring of IFS in a subshell + that caused a core dump has been fixed. + 12-02-08 A bug in which .sh.fun disciplines could be cleared after a + function completes has been fixed. + 12-02-08 A bug in job control in which the foregroup process group was not + set correctly after restarting a stopped pipeline has been fixed. + 12-02-07 A bug in which numbers with leading zeros could be treated as + octal constants outside of ((...)) has been fixed. + 12-02-06 A bug in arithmetic with compound variables containing multiple + array elements has been fixed. + libast: + 12-02-10 sfvprintf.c: fix 1 byte too long buffer access + 12-02-07 malloc.c/features/vmalloc: add gnu __malloc_hook tests + 12-02-06 vmmopen.c: fix ALIGN vs sys/param.h macro conflict + libcmd: + 12-02-14 rm.c: --force ignores no file operands specified + libpp: + 12-02-14 ppproto.c: fix "already noticed" logic + cmd/builtin: + 12-02-11 what.c: fix boyer moore cut n paste bug -- thanks werner + +------------------------------------------------------------------- +Tue Feb 14 15:36:22 UTC 2012 - werner@suse.de + +- Fix a nasty crash in IFS handling + +------------------------------------------------------------------- +Fri Feb 10 17:11:36 UTC 2012 - werner@suse.de + +- Fix bug in src/cmd/builtin/what.c + +------------------------------------------------------------------- +Fri Feb 10 15:45:09 UTC 2012 - werner@suse.de + +- Make pty and other ast-base command available as this helps to + test out some major features of the ksh (compare with bnc#743244) + +------------------------------------------------------------------- +Thu Feb 9 14:14:53 UTC 2012 - werner@suse.de + +- Modify some tests of the test suite not to show false results on + highly loaded build hosts as well as on build shares mounted with + noatime option + +------------------------------------------------------------------- +Thu Feb 9 09:47:38 UTC 2012 - werner@suse.de + +- Add patch from David Korn to fix foreground job control (bnc #743244) + +------------------------------------------------------------------- +Mon Feb 6 12:01:10 UTC 2012 - werner@suse.de + +- Update to 2012-02-02 of ksh93u+ which includes some of our patches + and fixes for the observerd memory leaks + 12-02-02 A bug in the ulimit option table was fixed. + 12-01-26 A bug in which a set command that did not change monitor could + effect the behavior of the monitor when monitor mode is on is fixed. + 12-01-21 +You can now test whether the shell implements a math function using + typeset -f .sh.math.name, where name is the name of the function. + 12-01-21 A bug in which typeset -L and typeset -R did not handle multibyte + characters correctly has been fixed. + 12-01-20 A bug that could cause the shell to hang waiting for an incorrect + job pid has been fixed. + 12-01-19 A memory leak which occured for a nested command subtiution has been + fixed. + 12-01-17 A bug in which typeset -u PS1 could enable the uppercase attribute + for some other variables, for exampe, HISTFILE has been fixed. + 12-01-16 A bug in which .sh.match was not correct after a substring match when + the replacement string contained a substring match has been fixed. + 12-01-12 +Files that are sourced from profile files are now read and executed + one command at a time so that alias definitions take effect as they + do for profile files. + 12-01-12 A bug in which whence -p would find a function if one existed and + there was no command of that name on PATH. + 12-01-11 Change b_* prototype (int, char**, void*) => (int, char**, Shbltin_t*). + 12-01-05 A bug in which read was not terminating for a signal that had a trap + set has been fixed. + libast: + 12-01-31 spawnveg.c: fix transient bug that made invalid setpgid() call + 12-01-27 pathpath.c: fix buffer size math when internal allocation requested + 12-01-24 malloc.c: fix _vmkeep() bug that did not return previous state + 12-01-23 malloc.c: add VMALLOC_OPTIONS=break to try sbrk() block allocator first + 12-01-18 malloc.c: disable multiple regions for tracing or !vmbest or ASO_SIGNAL + 12-01-12 sfpkrd.c: add __sun I_PEEK+rsh runtime workaround + 12-01-10 shcmd.h: void* => Shbltin_t* + 12-01-10 tmxdate.c: handle { n>=1000 } TM_PARTS + libcmd: + 12-01-10 b_* (int, char**, void*) => (int, char**, Shbltin_t*) + +------------------------------------------------------------------- +Thu Feb 2 11:32:15 UTC 2012 - werner@suse.de + +- Fix an off-by-one error which cause that the builtin ulimit may + fail (bnc#744355), patch from Li Bin. + +------------------------------------------------------------------- +Tue Jan 24 18:42:48 UTC 2012 - werner@suse.de + +- Make ex really work that is vim is required for build otherwise + libpp API does not work correct + +------------------------------------------------------------------- +Tue Jan 24 16:06:20 UTC 2012 - werner@suse.de + +- Make sigexec using a contolling terminal + +------------------------------------------------------------------- +Mon Jan 23 12:53:26 UTC 2012 - werner@suse.de + +- Avoid compiler optimizers which may cause asynchrony behaviour + +------------------------------------------------------------------- +Fri Jan 20 14:49:47 UTC 2012 - werner@suse.de + +- Update to 2012-01-01 of ksh93u+ which includes some of our patches + 12-01-01 A timing problem with >; has been fixed. + 12-01-01 A macro expansion memory leak has been fixed. + 11-12-26 A bug in array assignments of the form arr=( $arr[i] ...) in which + arr was not unset before the assignment has been fixed. + 11-12-20 A number of code changes were made based on the results of errors + indicated by static code analysis. + 11-12-13 In vi edit mode a lteral can now be entered by preceding it + with a backshash. + 11-12-13 When tab is entered for completion after a ' or ", the ' and " + characters are no longer deleted. + 11-12-07 A bug in which a program in the current direcotry with a . in the + name could fail to execute when both PATH and FPATH end with :. has + been fixed. + 11-12-07 I fixed a bug in which a variable expansion in a large here-document + could be expanded to a null string. + 11-12-06 An optimization to read was added in the case the the read command + was redirected from a file. + 11-12-06 Changes were made to make the line limit for read unlimited by + default. + 11-12-05 A bug in which unsetting an array variable did not completely clear + the variable in some cases has been fixed. + 11-12-02 +The printf alternative character # when applied to the %q format will + quote argument in a form suitable for a field in a .csv format file. + 11-12-02 +A -S option was added to read to be able to read .csv format files. + 11-11-28 A bug in which redirection of standard error in a function called from + command substitution caused standard error to be lost has ben fixed. + 11-11-21 [[ (-n foo) ]] no longer requires a space before (. + 11-11-11 The readonly attribute for a variable now applies to compound + assignments to that variable. + 11-11-07 Changes were made to reduce the stack size to allow deeper function + recursion. + 11-10-10 +Added alternate flag to printf %H for encoding of URI's. + 11-10-10 A bug which could lead to a core dump when the shell was invoked + with more than twenty five open files has been fixed. + 11-10-06 A bug in the scoping of name references in functions called by other + functions has been fixed. + 11-10-05 A bug in which wait on a pid may return the exit status of an + earlier background job with that pid instead has been fixed. + 11-09-22 A bug in which a read timed out with TMOUT did not always restore + the terminal state has been fixed. + 11-09-21 An optimization that allowed the last command in a script to use + the same process id as the script has been eliminated. + 11-09-21 Added letoctal option that enables the let command to recognize + octal constants starting with 0. + 11-09-20 A bug in which ${var.} could cause a core dump has been fixed. + 11-09-20 A bug with SHOPT_EDPREDICT when neither vi or emacs was enabled for + lines beginning with # when in a multibyte locale has been fixed. + 11-09-20 A bug in emacs edit mode with SHOPT_EDPREDICT that would cause + history searches matching comments lines to generate predictions + has been fixed. Only user typed comment lines generate predictions. + 11-09-20 A bug in emacs edit mode with a search that matches a comment line + that could cause a core dump has been fixed. + 11-09-16 A bug in which a command name ending in .. could cause the shell to + abort has been fixed. + 11-09-16 The characters ! + - % and @ in file names are no longer escaped with + file name completion. + 11-09-13 The let command no longer treats numbers starting with 0 as octal + constants. + 11-09-08 A bug in which printf "%R" could cause a core dump for invalid shell + patterns has been fixed. + 11-08-09 With set -u, ${var#pattern} reported that var was unset for special + variables. + 11-08-03 A bug in which the shell did not preserve the exit status for a + coprocess has been fixed. + 11-08-02 A bug in the saving and restoring of IFS in command substitution that + cause case a core dump has been fixed. + 11-07-21 Modified the 10-08-27 bug fix so that background jobs started in for + and while loops created interactively generate completion messages. + 11-07-20 I fixed a bug in here documents in which multi-byte characters that + crossed buffer boundaries were not processed correctly. +- Extend workaround for bug in glibc with signbit() macro that is that + the inlined part for long doubles does not work on IA64 +- Extend check for __sync_fetch_and_add gcc builtins for uint64_t, uint16_t, + and uint8_t to avoid those functions is missed in gcc from older SLES versions +- Avoid to have to large default mimimum region size at an initial memory mapping +- Avoid MAP_FIXED on IA-64 and S/390x, use MAP_32BIT +- Avoid compiler options which increase the risk of memory leaks + +------------------------------------------------------------------- +Sun Dec 4 23:00:26 UTC 2011 - agraf@suse.com + +- Don't run tests in qemu - they fail + +------------------------------------------------------------------- +Tue Aug 30 16:44:06 UTC 2011 - werner@suse.de + +- Implement a patch for both regressions reported here + mailman.research.att.com/pipermail/ast-developers/2011q3/000951.html + +------------------------------------------------------------------- +Mon Aug 15 16:46:10 UTC 2011 - werner@suse.de + +- Add patch from mailing list to avoid stupid crahs on empty job list. + +------------------------------------------------------------------- +Fri Jul 22 14:56:27 UTC 2011 - werner@suse.de + +- Fix a typo in the patch + +------------------------------------------------------------------- +Fri Jul 22 11:29:02 UTC 2011 - werner@suse.de + +- Add and modify a patch from David korn to be able to handle multi + byte characters at the boundary of the buffer used for parsing + here documents (bnc#705032) + +------------------------------------------------------------------- +Thu Jul 7 12:48:24 UTC 2011 - werner@suse.de + +- Check for ascii8 troff device, if not available use utf8 + +------------------------------------------------------------------- +Wed Jul 6 14:15:44 UTC 2011 - werner@suse.de + +- Extract messages from ksh source code automagic by using msgcc and + libpp from upstream ast-base packages (realted to bnc#703854) only + missing are the translations for those messages + +------------------------------------------------------------------- +Tue Jul 5 15:17:58 UTC 2011 - werner@suse.de + +- Drop locale support as it is out of sync since year 2000 (bnc#703854) + +------------------------------------------------------------------- +Mon Jul 4 15:19:20 UTC 2011 - werner@suse.de + +- Avoid crash on unset of function within the same function + +------------------------------------------------------------------- +Thu Jun 30 16:04:22 CEST 2011 - werner@suse.de + +- Update to 2011-06-30 of ksh93u which includes our patches for + several problems (e.g. Shift.JIS, S390, bnc#697394): + 11-06-22 The shell compiler now supports process substitution. + 11-06-22 +Added code to support process substitution on systems that do + not supply the /dev/fd directory. + 11-06-21 Fixed extraneous jobs Done messages when builin is at the end of a + pipeline. + 11-06-20 Fixed two regression tests. + 11-06-20 Fixed a bug introduced on last update. + 11-06-14 A bug with pipefail in which the shell would wait for background + jobs to complete has been fixed. + 11-06-09 A bug which caused the options.sh regression test to fail on OS390 + Linux has been fixed. The bug could also have affected other systems. + 11-06-07 A number of changes to support the still undocuments namespace option + have been added. + 11-06-06 A bug in which command substitution of eval would hang when it had + standard error redirected to standard output has been fixed. + 11-06-01 A bug in case statement fall through (;&) ignoring set -e was fixed. + 11-06-01 A bug in which creating a left or right justified upper or lowercase + variable with an empty string has been fixed. + 11-06-01 A bug in which the .paths directory wasn't read when a subshell was + executed before any other command has been fixed. + 11-05-31 The shell now gives an error when a type variable is assigned to + an array instance when the array has been declared a compound variable + array. + 11-05-31 A bug in which typeset -m of an array instance did not remove the + original instance has been fixed. + 11-05-28 A bug in which typeset -m dest=src fails when src and are passed as + name references was fixed. + 11-05-28 A bug in which typeset -m "c.board[1][i]=el", where el is a compound + variable core dumps has been fixed. + 11-05-28 Two bugs in the display of arrays of compound variables with print -v + have been fixed. + 11-05-27 A bug with command substitution with the shift jis locale has been + fixed. + 11-05-25 A bug in which unset -f foo, called within function foo could cause + the shell to core dump has been fixed. + 11-05-24 A bug in unsetting arrays of compound variables that could lead to + a core dump has been fixed. + 11-05-24 A scoping bug in with typeset -m for variables passed as references + has been fixed. + 11-05-09 A bug in which 'typeset +p array[$i]' in a subshell could cause an + exception has been fixed. + +------------------------------------------------------------------- +Tue Jun 14 11:36:28 UTC 2011 - werner@suse.de + +- Fix off by one error which should make timetype.sh work now +- Update the array fix as well as the pipe fix +- This also fixes bnc#677790 + +------------------------------------------------------------------- +Fri Jun 10 19:11:07 CEST 2011 - werner@suse.de + +- Avoid redirection in subshell if an eval was used (bnc#697394) + +------------------------------------------------------------------- +Wed Jun 8 15:14:46 CEST 2011 - werner@suse.de + +- Extend Shift.JIS patch to avoid breakage of the parsers above +- Avoid mounting 3D file system as this does not exist on linux + +------------------------------------------------------------------- +Wed Jun 1 11:23:03 CEST 2011 - werner@suse.de + +- Correct timetype.sh ... nevertheless typeset -T does not work + with array types as this requires ksh93u + +------------------------------------------------------------------- +Tue May 24 18:34:36 CEST 2011 - werner@suse.de + +- gcc dumps out poerpc64 even on powerpc which does break the + binary in a very special way e.g. in getopt(3) +- do not use CC but CCFLAGS and HOSTTYPE at make time + +------------------------------------------------------------------- +Fri May 13 15:29:04 UTC 2011 - werner@suse.de + +- Add workaround to enforce synchronization on here documents done + for forked sub shell or processes (bnc#690623) + +------------------------------------------------------------------- +Thu May 05 15:44:33 CEST 2011 - werner@suse.de + +- Update to 2011-05-05 of ksh93u which includes various fixes for + e.g. bnc#690623, bnc#661875, and bnc#636389, from RELEASE notes: + 11-05-03 Two more scoping bug with name references and read -C were fixed. + 11-05-03 A potential race condition which occurs when here-documents are + processed in asynchronous blocks has been eliminated. + 11-05-02 Another scoping bug with name references defined in a function has + been fixed. + 11-05-02 A bug in which the shell discards saved exit status of a job if it is + followed by a subshell execution has been fixed. + 11-04-28 The shell now checks for numerical overflows with process ids. + 11-04-28 Another scoping bug with compound variables defined by name references + inside a function has been fixed. + 11-04-28 A bug which caused a core dump on 32 bit systems with the basic.sh + regression test has been fixed. + 11-04-27 A scope binding error for name references has been fixed. + 11-04-27 Assignment of compound variable to compound array element by name + is now working. + 11-04-25 A bug in the references to two domensional compound arrays has + been fixed. + 11-04-20 A bug in which a name reference to a multidimentional index array + index, nameref x=foo[3][4], did not work correctly has been fixed. + 11-04-18 Changes were added to allow fixed size arrays of variable sized + objects when the SHOPT_FIXEDARRAY compile option defined on 10-09-28. + 11-04-18 A bug in which name references to array elements could fail has + been fixed. + 11-04-11 A bug in which readonly var, where var is exported could cause var + to be unset has been fixed. + 11-04-06 A tokenizer bug in which ${x/{3}(\d)/ } would cause in infinite + loop has been fixed. + 11-04-05 A bug in which ${!x.} could cause a core dump has been fixed. + 11-04-04 A bug in which cleaning out the history file could terminate before + keeping all the recent history events has been fixed. + 11-03-29 A bug in which ${#array[@]} was 1 rather than 0 after issuing + typeset array[7] has been fixed. + 11-03-29 The subscript out or range message for fixed arrays has been fixed. + 11-03-29 A bug in which suspend could cause a core dump has been fixed. + 11-03-24 For the showme option added 09-09-09, commands beginning with a ; + inside an arithmetic for loop, no longer produce syntax errors. + 11-03-18 A bug in _WINIX ~domain/user expansion has been fixed. + 11-03-16 A bug in the pipefail option which could cause a script to hang + has been fixed. + 11-03-12 The shell no longer treats ${##pattern} as a syntax error. + 11-03-11 A bug in typeset -u on systems that don't supply the towctrans() + function has been fixed. + 11-03-11 A bug in which a compound assignment of the form var[sub]=(...) + would evaluate sub for each assignment has been fixed. + 11-03-07 A bug in which reassigning a compound variable to an associative + array index could incorrectly increase the count of the number + of elements has been fixed. + 11-03-04 +The tilde expansion on windows has been modifed to handle user + names of the form domain/user so that ~domain/user now expands + to the home directory of that domain user. + 11-03-03 A bug in which the width of the prompt was calculated incorectly + which cause the wrong line length for edit commands has been fixed. + 11-03-02 A bug in which a global variables set from within a function inside + a subshell can leave side effects in parent shell has been fixed. + 11-03-01 A bug in which whence -a could dump core when the first match + was due to : in PATH and the program was in the current directory. + 11-02-28 A bug in emacs mode with SHOPT_EDPREDICT (added on 10-05-20) which + disabled prediction on a line starting with # when the cursor was not + at the end of line has been fixed. + 11-02-28 The output format for compound variables with set has been fixed. + 11-02-25 A bug which could lead to a core dump occurred when a shell script + without #! is invoked by name from a parent shell that has name + references defined and the script creates name references of the + same name. + 11-02-21 The shell now fails with a syntax error when a here-document in a + command substition is not completed before the closing ) + 11-02-18 A bug in which the value of $0 in a function defined by name() + was changed to name has been fixed. + 11-02-17 A bug in which the declaration typeset var[100] did not work + correctly has been fixed. + 11-02-15 A bug in which [[ -v sh.match ]] did not work correctly has been + fixed. + 11-02-08 A bug in which opening standard output after it has been closed with + exec 1>&- doesn't work has been fixed. + 11-02-07 A bug on some systems for which a command subtitution could hang + has been fixed. + 11-01-28 A bug in file name completion for files containing both multibyte + characters shell special characters has been fixed. + 11-01-18 The .sh.match variable now shows elements that do not match as + as not set rather than an empty string. + 11-01-18 A bug with typeset -m of an array into an element of an indexed + array has been fixed. + 11-01-13 A bug in handling of arrays of compound variables inside ((...)) which + reported a syntax error been fixed. + 11-01-10 A bug in arithmetic assignment operators of the form op= for array + variables when the same array was referenced on the left and the + right hand side with different indices has been fixed. + 11-01-10 A bug in which the output of time was lost when { time...;} 2>&1 + occured inside command substition has been fixed. + 11-01-07 [[ -v sh.match[i] ]] was returning false when sh.match[i] was set. + 11-01-05 Added and modified warning messages with sh -n. + 11-01-02 Fixed bugs with typeset -l/-u/-M and arrays. + 10-12-28 Fixed a bug with typeset -l/-u/-M values in arithmetric expressions. + 10-12-26 Fixed a time parsing bug in sleep and localeconv() initialization. + 10-12-23 Prevented the shell from generating a core dump when it sends itself + a termination signal because the last command terminated with that + signal. This prevents a core dump to be overwritten by the shell. + 10-12-22 A bug in the expansion of ${A[@]} ${B[@]}, introduced in 10-12-01 + when A="" B=B has been fixed. + 10-12-21 +Use MS_3D in b_vpath() for setting win32 WoW mount defaults. + 10-12-17 A bug in the expansion of ${var:i:j} which caused a core dump when + i > ${#var} has been fixed. + 10-12-16 +sleep now treats . as decimal point even in locales that use comma. + 10-12-16 +typeset -M mapname was added to generalize on toupper and tolowwer + mapping as provided with wctrans(). + 10-12-10 A bug in which typeset -l displayed namespaces as well as lower case + variables has been fixed. + 10-12-06 A bug in which a pipeline could terminate prematurely for a pipeline + whose right hand side is a builtin, and whose left hand side ends in + a simple command that has standard output redirected has been fixed. + 10-12-06 A bug in hexfloat assignments when the right hand side is a string + variable starting with 0x has been fixed. + 10-12-01 A bug in the expansion of ${$1+"$@"} which causes the last positional + parameter to disappear when it is empty has been fixed. + 10-12-01 A number of changes were made to reduce the startup time. + 10-11-29 When wait is interrupted by a signal that is caught, it now exits + with a non-zero exit status. + 10-11-29 An incorrect warning message was eliminated with the -n option for + arithmetic expressions with associative arrays. + 10-11-29 Some changes were made to slightly reduces startup time. + 10-11-24 A bug in which a name reference is make to arr[0] when arr is not + an array has been fixed. + 10-11-23 If a type definition is made without a compound variable assignment it + produces an error message and no longer shows up as a defined type. + 10-11-22 The handling of \ inside [...] for for shell and ~(E) patterns has + been fixed. + 10-11-22 A patch was made to pfsh to handle an error case. + 10-11-22 +Modified types defined in namespace so that they do not clash with + types in other namespaces. Types can be referenced using .namespace.typename. + 10-11-22 A bug which caused functions addressed as .namespace.funct to not + work has been fixed. + 10-11-22 A bug in which if nr was a name reference to an unset associative + array subscript, then ${!nr} did not output the subscript correctly + has been fixed. + 10-11-18 A bug in which shcomp -n was not processing double quotes correctly + has been fixed. + 10-11-18 Fixed a bug in which typeset -T foo; typeset -T could cause a + core dump. + 10-11-17 Fixed a bug in which the error message for set -u could come out + garbeled. + 10-11-17 Modified the parser so that typeset -a var=(...) no longer checks + the first index for aliases and reserved words. + 10-11-17 A bug in which a subshell command consisted of only a for or until + command has been fixed. + 10-11-16 Fixed a bug in which typeset -u would display namespace variables + as well as upper case variables. + 10-11-16 A bug which could cause a core dump when unsetting a type variable + when there are references to type elements has been fixed. + 10-11-15 A bug which could cause a core dump when unsetting a compound + array variable when there are references to array subscripts has + been fixed. + 10-11-15 A bug in which using typeset -m to move an indexed array instance + to another array could cause the array to display incorrectly has + been fixed. + 10-11-12 A bug in which the unset discipline function for a type is called + when the type is initialized has been fixed. + 10-11-12 The sequences \< and \> are now preserved after patterns contaning + ~(E) in ${var/pattern/string} expansions. + 10-11-11 A bug in typeset -m when the variables were compound arrary instances + has been fixed. + 10-11-10 A bug in output of a compound variable with types containing types + has been fixed. + 10-11-10 Fixed ``name=value export [-p]'' to list environment. + 10-11-09 shtests resets SIGPIPE to SIG_DFL for all tests. + 10-11-09 Fixed a bug in expansion of $"..." when used in assignments. + 10-11-09 Fixed a getaddrinfo() memory leak that didn't call freeaddrinfo() + after an interrupt. + 10-11-08 Modified the behavior of set -u so that the shell terminates with + error message when when var is unset with ${!var} and ${#var}. + 10-11-02 Fix a bug in which a signal received while in a subshell could be + ignored. + 10-10-26 Fix a bug where terminal interrupt was ignored while in vi/emacs + edit search mode. + 10-10-26 Fix $'a\0b'c to expand to 'ac'. + 10-10-26 Provide user defined round() if not in . + 10-10-26 Fix bug where $((undefined_function(1))) dumped core. + 10-10-22 Provide user defined iszero() if not in . + 10-10-22 Fixed a bug with BGX compile option that could cause the shell to hang. + 10-10-22 Fixed a bug with user define math function on systems for which + char is unsigned. + 10-10-21 A bug in which function autoloaded in a function leaves a file open + has been fixed. + 10-10-20 Modified the behavior of set -u so that the shell terminates when + when var is unset with ${var op string} when op is #, % or /. + 10-10-20 Fixed a bug with the AUDIT option in which the audit file was not + not close-on-exec. + 10-10-20 +Made a number of changes and fixes for the NAMESPACE compile option + which as added on 10-06-09 but some problems still remain. + 10-10-15 Fixed a bug in which arithmetic functions (added on 10-03-24) did + not work when the function definition was in the same compound + command in which the function was referenced. + 10-10-13 A bug in which creating an associative array of compound variables + with no members as an element of a compound variable did not work + has been fixed. + 10-10-08 A bug in which killing the last command in a function defined + with function name, terminated the calling script has been fixed. + 10-10-08 A bug which could cause a core dump if IFS is unset inside a function + has been fixed. + 10-10-07 +To reduce unwanted side effects, invoking typeset without the export + option and without an assignment now causes the variables to be unset + if the variable is inherited from the environment. + 10-10-06 The closing brace for ${ command } is now a token no matter what + character follows it. + 10-10-04 The change for $'...' expansion on 10-08-09 did not expand parameters + contained in the error message and this has been fixed. + 10-10-04 A bug in which a declaration of indexed array (-a_ in a type + definition would be displayed as a compound indexed array (-C -a) + has been fixed. + 10-09-30 The C99 math funtion ldexp has been added. + 10-09-30 A bug with two dimensional arrays with expansion of the form + ${ref[0..5]} where ref is a nameref to array[i] has been fixed. + 10-09-29 A bug in which an eval with redirections invoked from a dot script + would not restore the file has been fixed. + 10-09-29 A bug in which loading a function from FPATH could leave a file + descriptor open has been fixed. + 10-09-28 +A new compile option SHOPT_FIXEDARRAY has been added and is being + evaluation. It allows fixed sized indexed arrays be to defined + using "typeset array[dim1][dim2]...[dimn]". Fixed sized arrays + are used the same way indexed arrays are. Currently, only fixed + arrays of fixed objects (float, int, and justifies objects) are + supported. + 10-09-22 A bug which could cause an excpetion when a function with static + variables was redefined has been fixed. + 10-09-21 A bug in the processing of (command&) which created a job in the + parent process has been fixed. + 10-09-21 A for loop optimization bug with arithmetic expression evaluation + has been fixed. + 10-09-21 A bug in which a recursive function containing a pipeline could + lead to an exception fixed after 8 levels of recursion has been + fixed. + 10-09-18 A bug in which the count of elements in an array was wrong leading + to an excpetion has been fixed. + 10-09-13 A bug which occured when both xtrace and showme options where + specified in which the xtrace option disabled showme has been fixed. + 10-09-13 A bug in which creating a reference to an array variable with any + elements could cause subsequent array elements to be treated as + compound variables has been fixed. + 10-09-09 A bug which caused ((c.ar[x][y])) to be treated as a syntax error + has been fixed. + 10-09-08 A bug in the processing of references to multidimensional arrays + in arithmetic expressions has been fixed. + 10-09-08 A bug in the handling of multi-dimensional arrays which caused + the number of elements in each dimension to be incorrect has + been fixed. + 10-09-07 The change for messages on 10-08-09 did not handle message in + assignments and this has been fixed. + 10-09-07 A bug in the indentation of compound variables in arrays when + output with print -v has been fixed. + 10-09-07 A rare bug with indexed arrays when assigned a null string that could + cause a core dump has been fixed. + 10-09-03 A number of changes were made for jobs pools. + 10-08-31 typeset -p was modified to output name references after other + variables so that the output could be used as input. + 10-08-31 A bug with typeset -p in which variables with attributes but + without attributes were not displayed correctly has been fixed. + 10-08-27 +When running a subshell, the current pool is unset. + 10-08-27 A bug in which jobs started from within for or while lists in + interactive shells could generate completion messages has been fixed. + 10-08-25 Fixed a couple of bugs related to job pools. + 10-08-24 +[[ -e /dev/xxx/ ]] can be used to check whether special files of + those names are handled by the shell. + 10-08-24 A bug in the running of a compiled dot script in which only the + first command was executed has been fixed. + 10-08-23 A bug which sometimes caused a core dump with a confgire script + has been fixed. + 10-08-20 A bug in command substitution which caused a configure script to + hang has been fixed. + 10-08-19 Eliminated unnecessary ; from output of compound variable with + typeset -p. + 10-08-17 Fixed a bug in command substitution in which under certain + circumstances a file whose size is a power of 2 plus one, and the last + character was not a new-line, could cause memory corruption. + 10-08-13 +Added static discipline functions to type similar to C++ static + class functions. + 10-08-11 A bug in time when applied to a pipeline in which the shell did + not wait for all elements of the pipeline to complete has been fixed. + 10-08-11 Restored sh_fmtq() quoting to not quote NAME= in NAME=VALUE. + 10-08-09 +Modified the expansion of message strings, $"...", so that they + are expanded each time they are referenced rather than expanding + them when the script is compiled or read in. + 10-08-06 +The process id for jobs in job pools is now of the form poolname.n + where n is the jobid in that pool. Commands that accept job names + or numbers now understand names in this format. + 10-08-05 A bug in which an assignment from within an arithmetic expression + inside a function would create a local variable has been fixed. + 10-08-04 A bug in the expanding of variables whose names contain multibyte + characters has been fixed. + 10-08-04 A bug which caused an exception when processing scripts compiled + with shcomp -n has been fixed. + 10-08-02 Tests using very small buffer sizes uncovered a number of bug most + connected with here documents which have been fixed. + 10-07-27 The format modifier , used for digit grouping with d and f formats + has been documented. + 10-07-26 cd '' now produces and error rather than changing to the current + directory. + 10-07-26 A bug in multi-byte locales which the last character of a + multi-byte character is a \ or pattern character which could occur + when the character was the last character of a command substitution + has been fixed. + 10-07-23 Another bug in the processing of ${var:offset;len} in multi-byte + locales when len is larger than the number of characters has been + fixed. + 10-07-23 Many coding changes have been made to eliminate most of the uses + of global variables in the shell code. + 10-07-22 Fixed a bug in which discipline functions were not being invoked + when it was invoked as ref.discipline where ref was a name reference + to an array instance. + 10-07-22 Fixed a bug in which discipline functions were not being invoked it + was invoked on a two dimensional array, i.e., arr[5][9].discipline. + 10-07-19 Fixed a buffering problem which occured when running a script with + ssh and the parent ssh process is killed. + 10-07-14 Modifed the parser to treat ((...)) inside [[...]] as ( (...) ) to + that it is a nested (...). + 10-07-09 A bug in the handling of process substitution inside command + substitution as part of a pipeline has been fixed. + 10-07-07 A bug in the output for compound variables containing + multi-dimensional arrays has been fixed. + 10-07-06 ksh now recovers from changes made by bash to the history file without + loosing history commands. + 10-06-25 A bug in which a large here document containing command substitutions + of a dynamically loaded function that contained a here document + could get truncated has been fixed. + 10-06-24 If after executing a script found in FPATH, if a function, builtin, + or type name corresponding to that script is not defined, the shell + now outputs an error message and returns value 126. + 10-06-23 Floating point functions that happened to return integer values + were being treated as if the function returned integers so that + integer division could be used instead of floating point division. + 10-06-22 Fixed a bug in earlier ksh93u in which an arithmetic assignment to a + variable in the global scope would instead create a local variable if + the variable had an attribute but did not have a value. + 10-06-18 Modified trap handling so that if the same signal is received when + executing the handler, it is deferred until the handler completes. + 10-06-16 Fixed a bug in which ulimit -v was setting the the cpu limit + on Linux. + 10-06-14 +The command 'typeset -T' now generates the list of type definitions + in a format that can be used as input to the shell. + 10-06-09 Put in patch from Solaris for output quoting with %q. + 10-06-09 +Made changes to the NAMESPACE compile option so that it now seems + to work. With this option, namespace { command;} will + run command in the namespace .name so that all variables and + functions created by command are accessable outside the name + space via .name.var and .name.fun. Variables and functions that + are not in the namespace are not modifed when runnning command. + 10-06-07 Change most internal interfaces to take Sh_t* argument. + 10-06-03 +Types can be loaded on first reference by putting defintions in PFPATH. + 10-06-03 +The shell is now able to parse commands which use type statements + before the typeset -T command to define the type executes. + 10-06-03 A bug in the quoting for name reference declarations which did + not properly handle [ and ] in subscripts for associative arrays. + 10-06-02 A bug in which a discipline function defined by a type instance to + override the default was not being registered has been fixed. + 10-06-02 A bug in which read -C of an associative array of compound variables + was not working has been fixed. + 10-06-02 A bug in which the error message for an unset parameter with set -u + did not contain the name of the variable has been fixed. + 10-06-01 A bug in typeset -m for moving an indexed array instance to a variable + has been fixed. + 10-06-01 A bug in which caused memory to be freed twice when unset was called + for an indexed array that had get or set disciplines has been fixed. + 10-06-01 A bug in which the %b format of printf was not preserving NUL bytes + with \0 has been fixed. + 10-06-01 A bug in the handling of name references to array variables in + arithmetic expressions has been fixed. + 10-05-28 Fixed bugs in changing attributes for two dimensional arrays. + 10-05-28 Eliminated a few unreferenced variables and a reference to + uninitialized memroy. + 10-05-27 Rewrote the subshell code to avoid using pipes an many cases. + 10-05-24 Fixed a bug which cause an exception when both -l and -s were + +------------------------------------------------------------------- +Fri Mar 4 16:15:16 CET 2011 - werner@suse.de + +- Avoid to export local variables from real subshells + +------------------------------------------------------------------- +Tue Feb 22 13:04:48 UTC 2011 - werner@suse.de + +- Make shell functions POSIX compliant (bnc#661875) + +------------------------------------------------------------------- +Wed Oct 27 14:14:28 CEST 2010 - werner@suse.de + +- Change fix for bnc#636389 to my first approach as this + does not hang on x86_64 + +------------------------------------------------------------------- +Thu Oct 21 12:36:44 CEST 2010 - werner@suse.de + +- Yet an other file descriptor leak caused by audit feature + +------------------------------------------------------------------- +Tue Oct 19 13:11:24 CEST 2010 - werner@suse.de + +- Close file descriptor leak caused by loading shell functions + +------------------------------------------------------------------- +Mon Oct 11 14:53:35 CEST 2010 - werner@suse.de + +- Add script for testing out the previous bug + +------------------------------------------------------------------- +Fri Oct 8 14:50:56 CEST 2010 - werner@suse.de + +- Fix crash on unset on local IFS within shell functions (bnc#636389) + +------------------------------------------------------------------- +Tue Jun 29 16:09:17 CEST 2010 - werner@suse.de + +- Avoid memory leak as reported on mailing list + +------------------------------------------------------------------- +Mon Jun 28 17:33:29 CEST 2010 - werner@suse.de + +- Update to 2010-06-21 of ksh93t+ bug fix version + ksh: + 10-06-21 The next release this directory will be renamed ksh93t and will + install as ksh93t and ksh93u will become the default ksh. + 10-05-27 Rewrote the subshell code to avoid using pipes in many cases. + +------------------------------------------------------------------- +Fri May 28 13:21:46 CEST 2010 - werner@suse.de + +- Update to 2010-05-27 of ksh93t+ bug fix version + ksh: + 10-05-24 --- Release ksh93t+ --- + 10-05-24 Fixed a bug which cause an exception when both -s and -s were + specified with typeset -i. + 10-05-21 Inputting of three dimensional indexed arrays with ( ( (...)...)...) + was not working and has been fixed. + 10-05-21 A bug in which adding the attributes -Ai to a variable via a name + reference could cause the value to display incorrectly has been fixed. + 10-05-21 A bug in which using $var inside ((...)) did not work when var was + a hex float variable. + 10-05-20 A bug which caused an exception when multiple levels of composite + functions in arithemtic expressions has been fixed. + 10-05-19 <<< with an empty string no longer gives an error. + 10-05-19 A bug in arithmetic evaluation when a name reference to an array + instance was used has been fixed. + 10-05-14 A bug in which the shell treats a valid index array assignment, + typeset -a x=(foo (x=3;y=4) bar) as a syntax error has been fixed. + 10-05-13 A bug in creating name references to assocative array variable + after a lookup of one of its elements has been fixed. + 10-05-12 Two bugs in the handling of function static type variables in + subshells have been fixed. One could cause an exception and the + other would leave side effects in the parent shell. + 10-05-10 A bug in which static variables in functions were not being saved and + restored properly when running subshells has been fixed. + 10-05-05 A bug in which print -v did not work correctly when an operand was an + indexed array element refering to a compound variable has been fixed. + 10-05-05 A change to improve performace by special casing empty string + assignments to avoid repeated malloc() and free(). + 10-05-05 A bug in which creating a name reference to a non-existant associative + array element would create the array element has been fixed. + 10-05-04 A bug in which name references to static variables in the static + scope were not found has been fixed. + 10-04-30 Do not use socketpair() on systems that implement ioctl(I_PEEK) on pipes. + 10-04-28 A type defined with a member foo that is an associative array without + elements followed by an expansion ${bar.foo[a]} and an assignment + bar.foo[a]=b, no longer indicates that ${#bar.foo[@]} has 0 members. + 10-04-27 Another bug in which a nested command substitution could hang if it + generated too much data has been fixed. + 10-04-26 A type defined with a member that is an indexed array without elements + would behave as if the 0th element of each instance was defined after + a non-zero element was specified and this has been fixed. + 10-04-26 A bug in which types defined in a subshell were not undefined when + the subshell completed has been fixed. + 10-04-23 For file completion in commmand line editing, file names starting + with # are now escaped so that they are not treated as comments. + 10-04-23 A bug in which ${t.var:=value}, where t is an instance of a type + variable, could assign value to the type variable rather than to + the type instance has been fixed. + 10-04-22 A bug in which a nested command substitution could hang if it + generated too much data has been fixed. + 10-04-20 A bug which corrupted one byte of memory when read was called with + reads that did not use a delimiter has been fixed. + 10-04-19 The display of a compound variable with an embedded array with + attributes was sometimes not working correctly and has been fixed. + 10-04-16 A bug in which attributes were not be propogated to elements in + an associative array has been fixed. + 10-04-15 A bug which caused scripts containing user defined math functions to + fail to compile with shcomp has been fixed. + 10-04-14 A bug in which a coprocess connection could terminate prematurely + when running a nested subshell has been fixed. + 10-04-07 On Darwin on Mac/OS a bug has been fixed which generated an + inappropriate error message when continuing a background job. + 10-04-07 A bug in which setting the trap on CHLD to ignore could cause + an incorrect exit status has been fixed. + 10-04-06 A bug in which LINENO was not incremented for a here-document when + the here-document word was followed by a comment has been fixed. + 10-04-06 The optimization that execs the last process of a script rather + than creating a new process has been removed when a trap on + interrupt has been set. + 10-04-06 Unsetting the 'C', 'A' or 'a' typeset attribute now produces an + error message rather than generating an exception. + 10-04-06 A bug in which .sh.name contained the subscript and .sh.subscript + was empty in some cases with discipline functions on array instances + has been fixed. + 10-04-05 A bug in the edit modes where preceding the interrupt character with + the literal next character did not work has been fixed. + 10-04-05 A bug in the creation of type instances of arrays which could cause + an exception has been fixed. + 10-03-30 A bug in the display of a compound variable containing an indexed + array of compound variables has been fixed. + 10-03-24 A bug in which integer division was mistakenly used when the + numerator was a binary operator with the first operand floating + point and the second integer, e.g. (.1**3)/3, has been fixed. + 10-03-24 The >; file operator was modified so that the temporary file is + created in the same physical directory as file. + 10-03-23 A warning message was added to sh -n when $var was used inside + ((...)) instead of var. + 10-03-19 fmin was added to the list of math function on the man page. + 10-03-19 Fixed the return value for unalias when the alias did not exist. + 10-03-19 A bug in which the SHLVL variable exported the value it had on + input rather than the incremented value has been fixed. + 10-03-19 A bug which causes whence -q to go into an infinite loop has been fixed. + 10-03-19 Removed space between Stopped message and (SIGTTIN) and (SIGTTOUT). + 10-03-17 Modified profile shell execution so that when builtins that + correspond to executable have extended attributes, they are + executed by pfksh instead of being treated as built-ins. + 10-03-16 A bug in whence -a which produced duplicate lines of output has been fixed. + 10-03-16 A bug in the handling of process groups in monitor mode for + command substitutions has been fixed. + 10-03-12 A bug in which a here-document containing command substitutions + that contained here-documents did not process correctly has been fixed. + 10-03-12 A bug in which the terminal is not restored to cannonical mode + after read times out when in a multibyte locale with no edit mode + enabled has been fixed. + libast: + 10-05-25 include/sfhdr.h: adjust SF_NMAP according to _ptr_bits + 10-05-25 include/shcmd.h: add sh_builtin() macro for lib_init() table initialization + 10-05-21 misc/optget.c: --html \bfoo::bar([[:digit:]][[:upper:]]*) => foo-bar.html + 10-05-15 include/proc.h,misc/procopen.c: add PROC_ORPHAN + 10-05-09 misc/optget.c: add --???MAN[section] --???SECTION + 10-05-07 sfio,stdio: fix all snprintf() variants to handle buf==0 and/or n==0 + 10-05-04 string/fmtesc.c: add mb iswsoace() and iswcntrl() quoting checks + 10-05-03 fix LC_MESSAGES catalog lookup bugs, check for $set==3, accept $set==1 + 10-04-30 string/chresc.c: add chrexp() for FMT_EXP_* + 10-04-30 string/stresc.c: add strexp() for FMT_EXP_* + 10-04-30 string/chresc.c: fix \uXXXXY bug that consumed Y + 10-04-22 misc/optget.c: check for html entities in + 10-04-22 misc/getcwd.c: add features/syscall check for SYSGETCWD() { linux solaris } + 10-04-22 string/stresc.c: wide chars absent locale guidance default to UTF-8 + 10-04-12 port/mnt.c: favor bsd getfsstat() over getmntinfo() + 10-04-11 string/strtoi.h: k (1000) and ki (1024) now differentiated + 10-04-10 misc/recstr.c: fix 'd[delimiter]' parse + 10-04-08 include/vmalloc.h,vmalloc/vmstat.c: add Vmstat_t.mode region mode bits + 10-04-05 misc/fts.c: drop 1997-01-07 fts_open()=0 is one file and stat() fails + 10-04-05 misc/optget.c,optlib.h: add Optpass_t.release for --nroff .TH + 10-04-02 misc/optget.c: fix $'[-n?\n...]' --version bug + 10-04-02 regex/regcomp.c: ~(X) => REG_EXTENDED|REG_AUGMENTED, ~(PU) instead of ~(U) + 10-03-24 misc/procopen.c: add PROC_FD_CTTY(fd) + 10-03-24 path/pathtemp.c: fix pointer => int casts + 10-03-15 regex/regcache.c: fix 1 byte buffer overflow (didn't count trailing \0) + libcmd: + 10-05-09 tail.c: fix -0f bug that inially listed the entire file + 10-05-06 basename.c: add { -a,--all -s,--suffux=suffix } from BSD + 10-04-12 cat.c: fix -v bug that dumped core and make consistent with cmp --print-chars + 10-04-11 cmp.c: add --print-bytes, --count=n, --differences=n + 10-04-08 vmstate.c: add { method flags } vars for Vmstat_t.mode + 10-04-08 mkdir.c: fix check for { S_ISUID S_ISGID S_ISVTX } after successful mkdir(2) + 10-04-01 stty.c: add --fd=fd option + 10-03-23 tail.c: fix -f large initial offset bug that didn't copy all data + +------------------------------------------------------------------- +Mon May 3 14:47:52 CEST 2010 - werner@suse.de + +- Add patch from mail list tp avoid deadlock in builtin `whence' + +------------------------------------------------------------------- +Fri Apr 9 10:46:24 CEST 2010 - werner@suse.de + +- Add patch from upstream for problem with trap on SIGCHLD (bnc#591248) + +------------------------------------------------------------------- +Mon Mar 15 10:59:42 CET 2010 - werner@suse.de + +- Add patch from upstream for minor problem with tty reset + +------------------------------------------------------------------- +Wed Mar 10 12:34:45 CET 2010 - werner@suse.de + +- Use a wrapper to execute the ksh test suite without ignoring the + signals SIGPIPE and SIGQUIT +- Update to 2010-03-09 of ksh93t+ for bug fix version + + ksh: + 10-03-05 --- Release ksh93t+ --- + 10-03-05 A varibale unset memory leak has been fixed and tests/leaks.sh + has been added to verify the fix. + 10-03-04 Documentation, comment, and disgnostic spelling typos corrected. + + libast: + 10-03-08 features/tvlib: fix utimensat probe to include all macros/structs + 10-03-07 features/lib: change stream_peek to test pipes only + 10-03-07 string/strelapsed.c: fix next char return overrun + 10-03-06 tm/tvtouch.c: use runtime fallback if utimensat() fails with ENOSYS + 10-03-05 path/pathtemp.c: add pfx /seed for regression testing + 10-03-04 vmalloc/vmwalk.c: add user supplied handle arg + 10-03-04 path/pathtemp.c: properly handle mktemp()-style *+(X) templates + 10-03-03 include/ast_getopt.h: remove NULL guard - _AST_GETOPT_H now handles it + + libcmd: + 10-03-07 tail.c: sfsync(sfstdout) after all -f done, fix -f partial line + 10-03-05 mktemp.c: add --regress=seed for testing + 10-03-05 vmstate.c: add + +------------------------------------------------------------------- +Mon Mar 8 15:10:07 CET 2010 - werner@suse.de + +- Make it build for SLES10 and SLES9 +- Check if the shell used for build ignores SIGPIPE + +------------------------------------------------------------------- +Fri Mar 5 20:07:06 UTC 2010 - guido+opensuse.org@berhoerster.name + +- Add forgotten preun scriptlet for update-alternatives +- Fixed typo + +------------------------------------------------------------------- +Fri Mar 5 14:38:39 CET 2010 - werner@suse.de + +- Submit ksh93t+ from 2010-03-01 which fixes bnc#502622, bnc#523212, + bnc#548588, bnc#555938, bnc#561405, bnc#564967, and bnc#585244 +- Add bugfix from David Korn to close memleak again + +------------------------------------------------------------------- +Wed Mar 3 14:25:52 CET 2010 - werner@suse.de + +- Update to 2010-03-01 of ksh93t+ for final version + + ksh: + 10-02-14 Fix sh_getenv() initialization to cooperate with the 3d fs. + 10-02-12 A bug in which the get discipline function was not invoked for + associative array subscripts for unset array elements has been fixed. + 10-02-12 A bug which could occur if the last line of a script was an eval + that executed multiple commands has been fixed. + 10-02-02 A buffer overflow in read and another in binary type base64 + encoding were fixed. + 10-01-20 A bug in the evaluation of arithmetic expression in which the + subscript was evaluated twice for $((foo[x++]++)) has been fixed. + 10-01-19 A workaround for a double-free of a trap in both a subshell and its + parent has been added. + 10-01-18 A bug in type handling of typeset -H has been fixed. + 10-01-15 The "adding empty subscript" warning now only emitted with -x set. + 10-01-01 A bug in the parser in which '$((case i in i):;esac);:))' was not + parsed correctly was fixed. + 10-01-01 A bug in the parser in which '$(( 2 , 3.6 ))' dumped core for locales + with radix char , and thousands separator . has been fixed. + 09-12-28 A bug in the handling of SIGCLD on systems that generated SIGCLD + while blocked waiting for process to complete has been fixed. + 09-12-24 ast setlocale() reworked to differentiate env var changes from user + override. + + libast: + 10-02-24 comp/getopt.h: fix ast_std.h interactions + 10-02-24 vmalloc/malloc.c: empty { VMALLOC_OPTION VMDEBUG ... } => no debug! + 10-02-02 string/base64.c: fix corner case output buffer overflow + 10-02-01 misc/optget.c: uppercase --html heading -- doh + 10-01-29 misc/optget.c: [+NAME?...] overrides error_info.id for >= STYLE_man + 10-01-25 vmalloc/vmprivate.c: fix seg ptr initialization bug (24 years old!!) + 10-01-20 misc/optget.c: handle nested {...} rendering + 10-01-20 misc/state.c: add ast.version for runtime api version + 10-01-20 port/astconf.c: "_AST_VERSION" now returns ast.version + 10-01-20 include/ast_std.h: add ast.version for runtime api version + 10-01-01 vmalloc: VMALLOC_OPTIONS env var for all runtime options + 10-01-01 include: change some refs to less intrusive + 10-01-01 setlocale.c,translate.c,fmterror.c: AST_LC_internal retains prev state + 10-01-01 comp/setlocale.c: AST_LC_setenv defers to LC_ALL (for sh) + 10-01-01 ast_std.h: add { AST_LC_internal AST_LC_setenv } + 09-12-24 comp/setlocale.c: fix setlocale(LC_ALL,"") when already initialized + + libcmd: + 10-01-26 tail.c: -f sleep(1) only if no progress from last round of checks + 10-01-20 fts_fix.[ch]: use instead of (see fts_fix.c) + 10-01-20 cp.c: free(state) if called from old shell + +------------------------------------------------------------------- +Mon Mar 1 23:13:55 UTC 2010 - guido+opensuse.org@berhoerster.name + +- install /bin/ksh93 and /usr/bin/ksh93 symlinks +- use update-alternatives + +------------------------------------------------------------------- +Mon Dec 21 14:20:21 CET 2009 - werner@suse.de + +- Update to 2009-12-18 beta test of ksh93t+ for bug fixes + + 09-12-18 A bug with the SHOPT_BGX option set which disabled traps for signals + < SIGCHLD when a trap for a signal > SIGCHLD was set has been fixed. + 09-12-18 A bug where [[ -v var ]] was incorrect for some variables (including + LC_* vars) has been fixed. + 09-12-15 A bug that produced a syntax error when a multibyte character + straddled a buffer boundary has been fixed. + 09-12-11 A bug where the subscript of an unset variable was not evaluated has + been fixed. + 09-12-09 A bug where shcomp dumped core on certain syntax errors has been fixed. + 09-12-07 A bug where a parent shell environment var reset in a subshell removed + the value in subsequent children of the parent shell has been fixed. + +------------------------------------------------------------------- +Wed Dec 9 18:01:09 CET 2009 - werner@suse.de + +- Update to 2009-12-06 beta test of ksh93t+ for bug fixes + + 09-12-04 A bug in which in some cases a trap in a function executed in + a subshell could trigger twice has been fixed. + 09-12-03 A bug in which SHLVL exported with some attributes could cause + the shell to abort at startup has been fixed. + 09-12-02 A bug with pipefail in which the shell could hang waiting for the + writer to complete before the last reader command has been fixed. + +------------------------------------------------------------------- +Wed Dec 3 10:54:02 CET 2009 - werner@suse.de + +- Update to 2009-11-30 beta test of ksh93t+ for bug fixes + + 09-11-30 A bug in which a trap could be inherited by the first element of + a pipeline when the command had more than 63 arguments that did + not contain any macro expansions has been fixed. + 09-11-19 When read from a terminal was called from with a while or foo loop, + and an edit mode was on, a backspace or erase no longer will + overwrite the prompt. + 09-11-17 Change .paths parse to handle BUILTIN_LIB=foo BUILTIN_LIB=foo-1.2. + 09-11-17 Inside a function, typeset foo.bar will bind foo to global variable + foo if local variable foo does not exist, instead of creating a + local variable. + 09-11-17 "read -n1" from the terminal has been fixed to read exactly one character. + 09-11-11 Job control now works for subshell commands, (...). + 09-11-11 If set -e is on for an interractive shell errors in special builtins + now cause the shell to exit. + 09-11-11 A bug in which an interrupt handler processed during the read builtin + when IFS did not contain a new line has been fixed. + 09-11-09 A bug in which a variable that has been unset in a subshell and then + exported from that subshell does not show up in the environment + has been fixed. + 09-11-02 ",2" is now a valid numeric constant for locales with + decimal_point=','. + 09-11-02 A bug where "return" in .profile did not restore the shell state + has been fixed. + 09-10-31 A bug that corrupted saved exit status when pids wrapped around has + been fixed. + 09-10-26 A bug in { LANG LC_ALL LC_category } ordering has been fixed in -last. + +------------------------------------------------------------------- +Fri Oct 30 16:23:36 CET 2009 - werner@suse.de + +- Update to 2009-10-21 beta test of ksh93t+ for bug fixes + + 09-10-16 A bug where notification to libast that the environment has changed + has been fixed. + 09-10-12 A bug in which a function loaded in a subshell could leave side + effects in the parent shell has been fixed. + 09-10-12 A bug in converting a printf %d operand to a number when the operand + contains multiple subscripts for the same variable has been fixed. + 09-10-09 A bug in the handling of the escape character \ in directory prefixes + in command completion has been fixed. + 09-10-09 $PATH processing has been changed to delay dir stat() and .paths + lookup until the directory is needed in the path search. + 09-09-28 Call the ast setlocale() intercept on unset too. + 09-09-24 A bug in which LANG=foo; LC_ALL=foo; unset LC_ALL; did not revert + LC_CTYPE etc. to the LANG value has been fixed. + 09-09-17 A bug in which unsetting SVLVL could cause a script invoked by + name without #! to core dump has been fixed. + 09-09-16 A bug in which a pipeline in a here-document could hang when the + pipefail option was on has been fixed. + 09-09-09 A bug in the processing of line joining in here documents which + occurred when a buffer began with has been fixed. + 09-09-09 A leading ; with commands in a brace group or parenthesis group + no longer causes an error. It now is used for the "showme" option. + 09-09-09 A bug in which a subshell containing a background process could + block until the background process completed has been fixed. + 09-09-04 A bug in handing ${var[sub]}, where var is a nameref has been fixed. + 09-09-03 A bug which caused an index array to have the wrong number of elements + when it was converted from a compound variable by adding an another + element has been fixed. + 09-09-03 Specifying export for a compound variable now generates an error. + 09-09-02 $"..." localizations strings are no longer recognized inside `...`. + 09-09-01 A bug in the for loop optimizer in the handling of type static + variables has been fixed. + 09-09-01 An error message is not displayed when * and @ are used as subscripts. + 09-09-01 Several bugs in the processing for types that included an associative + array of another type has been fixed. + 09-09-01 A bug in the tracing of [[ a < b ]] and [[ a > b ]] has been fixed. + 09-08-26 The .sh.file variable was not being set for a script that was run + by name and didn't start with #! and this has been fixed. + 09-08-25 A bug in which a function called to deeply from command substitution + did not display an error message has been fixed. + 09-08-24 When processing profiles, ksh93 now violates the POSIX standard and + treats &> as a redirection operator similar to bash. + 09-08-23 A bug in the handling of the trap on SIGPIPE that could lead to a + memory fault has been fixed. + 09-08-21 A bug in the handling of the comma operator in arithmetic expressions + that could cause a core dump on some systems has been fixed. + 09-08-20 A bug in which a compound variable containing an array of a type + that doesn't have any elements now expands correctly. + 09-08-19 A bug which disabled function tracing inside a function after + a call to another function has been fixed. + 09-08-19 A bug in which initializing a compound variable instance to another + compound variable by name has been fixed. + 09-08-18 A bug in which compound variable instances could be lost after + an instance that invoked a type method discipline has been fixed. + 09-08-18 A bug in which a discipline function for a type applied to an + array instance when invoked in a function ignored the subscript + has been fixed. + 09-08-18 A scoping error with variables in arithmetic expression with + type variables when reference with a name reference has been fixed. + 09-08-10 Several memory leaks were fixed primarily related to subshells. + 09-08-06 A bug in which setting the trap on CHLD to ignore could cause + a script to hang has been fixed. + 09-07-08 A bug in the processing of name reference assignments when it + contained pattern expansions with quoting has been fixed. + +------------------------------------------------------------------- +Wed Aug 26 14:03:10 CEST 2009 - werner@suse.de + +- Add patch to avoid crash within pipes + +------------------------------------------------------------------- +Tue Aug 11 11:39:45 CEST 2009 - werner@suse.de + +- Add three patches from David Korn for bug bnc#520598 +- Use mapping of libast virtual memory management (bnc#523212) + +------------------------------------------------------------------- +Tue Aug 4 14:37:37 CEST 2009 - werner@suse.de + +- Work around three memory leaks (bnc#520598) +- Use workaround for bug in s390 for all architecture where named + pipes aka fifos are in blocking mode which cause read failures + in some sort of shell code test cases +- Update to 2009-06-30 beta test of ksh93t+ for bug fixes + + 09-06-22 The default width for typeset -X has been changed so that there + should be no loss of precision when converting to a string. + 09-06-19 A bug in the printing of array elements for binary variables with + printf %B has been fixed. + 09-06-19 A bug which caused a core dump with trap DEBUG set with an array + assignment with no elements has been fixed. + 09-06-19 A bug with read with typeset -b -Z has been fixed. + 09-06-19 Two bugs related to read -b for array variables has been fixed. + 09-06-19 A bug with typeset for compound variables containing arrays of + compound variables has been fixed. + 09-06-18 A bug in appending a compound variable to a an indexed array of + compound variables has been fixed. + 09-06-18 A bug which occurs when appending a compound variable to an indexed + array element has been fixed. + 09-06-17 A bug in typeset -m when moving a local compound variable to a + global compound variable via a name reference has been fixed. + 09-06-17 A bug in appending to nodes of an array of compound variables when + addressing them via nameref has been fixed. + 09-06-17 A bug in typeset -p var, when var is an array of compound variables + in which the output only contained on array element has been fixed. + 09-06-17 The prefix expansion ${!y.@} now works when y is a name + reference to an element of an array. + 09-06-12 A bug in vi edit mode in which hitting the up arrow key at the + end of a line longer than 40 characters which caused a core dump + has been fixed. + 09-06-11 A bug in which "eval non-builtin &" would create two processes, + one for the & and another for non-builtin has been fixed. + 09-06-08 When var is an identifier and is unset, ${var} no longer tries to + run command substitution on the command var. + 09-06-08 Process substitution arguments of the form <(command) can now be + used following the < redirection operator to redirect from command. + 09-05-13 A bug in which redirections of the form 2>&1 1>&5 inside command + substitution could cause the command substitution to hang has been + fixed. + 09-05-12 To conform with POSIX, the -u option only checks for unset variables + and subscript elements rather than checking for all parameters. + 09-05-12 A bug which could cause a core dump when a variable whose name + begins with a . was referenced as part of a name reference inside + a function has been fixed. + 09-05-01 A bug that caused a core dump when SIGWINCH was received and + both vi and emacs mode were off has been fixed. + 09-04-22 Default alias compound='typeset -C' added. + 09-04-15 A bug that caused ${...;} to hang for large files has ben fixed. + 09-04-08 A change was made in the -n option which printed out an incorrect + warning with <>. + 09-04-05 A bug in handling new-lines with read -n has been fixed. + 09-03-31 A bug in which a nested command substitution with redirections could + leave a file descriptor open has been fixed. + 09-03-17 The sleep(1) builtin now accept and ISO 8601 PnYnMnDTnHnMnS + duration or date(1) compatible date/time operand. + +------------------------------------------------------------------- +Fri Jun 19 10:35:46 CEST 2009 - coolo@novell.com + +- disable as-needed for this package as it fails to build with it + +------------------------------------------------------------------- +Mon May 25 15:00:58 CEST 2009 - werner@suse.de + +- Assigning to SECONDS in a subshell causes crash (bnc#502622) + +------------------------------------------------------------------- +Mon Feb 16 11:11:27 CET 2009 - werner@suse.de + +- Update to 2009-03-10 beta test of ksh93t+ for bug fixes + + 09-03-10 If a variable that was left or right justified or zero-filled was + changed with a typeset statement that was left or right justified + or zero-filled, then the original justification no longer affects + the result. + 09-03-10 A bug in the handling of traps when the last command in a script + is a subshell grouping command has been fixed. + 09-03-03 A bug in which an expansion of the form ${!prefix@} could generate + an exception after the return from a function has been fixed. + +------------------------------------------------------------------- +Mon Feb 16 11:11:27 CET 2009 - werner@suse.de + +- Update to 2009-02-02 beta test of ksh93t+ for bug fixes (bnc#472889): + + 09-02-02 A bug in restricted mode in which the value of ENV could be + changed from within a function has been fixed. + 09-02-02 A bug in which an erroneous message indicating that a process + terminated with a coredump has been fixed. + 09-02-02 The exit status when exit was called without an argument from + a signal handler was incorrect and has been fixed. + 09-02-02 A bug in which a function autoloaded in a subshell could cause + a core dump when the subshell completed has been fixed. + 09-02-02 A bug in which 2>&1 inside a command substitution wasn't working + correctly has been fixed. + 09-02-02 A bug in the call stack of arithmetic function with 2 args + returning int has been fixed. + 09-01-30 A bug in which 'eval print \$0' inside a function was giving the + wrong value for $0 has been fixed. + 09-01-28 A bug in which a command substitution could return an exit status + of 127 when the pipefail option is enabled has been fixed. + +------------------------------------------------------------------- +Tue Feb 10 18:57:26 CET 2009 - werner@suse.de + +- Update to 2009-01-20 beta test of ksh93t+ for bug fixes (bnc#472889): + + 09-01-20 A bug in which the exit status specified in an exit trap was + not used when a process terminated with a signal has been fixed. + 09-01-19 A bug in which a signal whose default action is to terminate + a process could be ingored when the process is running a sub-shell + has been fixed. + 09-01-19 A bug in which sending SIGWINCH to a process that reads from a pipe + could cause a memory fault has been fixed. + 09-01-13 A bug in which background jobs and pipelines that were not waited + for could, in rare instantes, cause the shell to go into an infinite + loop or fail has been fixed. + 09-01-06 A bug in indexed arrays of compound variables in which referencing + non-existant sub-variable in an arithmetic expression could cause + the sub-variable to be created has been fixed. + 09-01-05 A bug in which the \ character did not escape extened regular + expression pattern characters has been fixed. + 08-12-24 A bug in which killing the last element of a pipe did not cause + a write to the pipe to generate a SIGPIPE has been fixed. + 08-12-19 A bug which could cause command substitution to hang when the + last element of a pipeline in a command substitution was a built-in + and the output was more that PIPE_BUFF. + 08-12-18 A bug which occurs when a here documented marker embedded in a + command substitution occurs on a buffer boundary has been fixed. + 08-12-17 A bug in the output of typeset -p for variables that had attributes + but did not have a value has been fixed. + 08-12-16 A bug in which a name reference to a name reference variable that + references an array element has been fixed. + 08-12-16 A bug in which a variable given both the -A and -C attribute along + with an initial assignment didn't work correctly has been fixed. + +- Initialize flag variable for job handling + +------------------------------------------------------------------- +Wed Dec 17 15:16:32 CET 2008 - werner@suse.de + +- Add workaround for bug in s390 architecture where named pipes aka + fifos are in blocking mode which cause read failures in some sort + of shell code test cases + +------------------------------------------------------------------- +Wed Dec 17 13:25:33 CET 2008 - werner@suse.de + +- Add workaround for bug in glibc with signbit() macro that is that + the inlined part for long doubles does not work on IA64 + +------------------------------------------------------------------- +Mon Dec 15 11:25:24 CET 2008 - werner@suse.de + +- Switch to 2008-12-12 beta test of ksh93t+ for bug fixes: + + 08-12-10 The [[ -t fd ]] test was fixed to handle fd>9. + 08-12-10 A bug where function stack misalignment could cause a + bus error has been fixed. + 08-12-07 A bug in typeset -m which occured when the target node + was an associative array element has been fixed. + 08-12-04 The sign of floating point zero is preserved across + arithmetic function calls. + 08-12-04 A bug that caused print(1) to produce garbled + stdout/stderr output has been fixed. + 08-12-04 A bug in which printf "%d\n" "''" did not output + the numerical value of the EURO symbol has been fixed. + 08-11-20 A bug which could cause a core dump if a function + compiled with shcomp was found has been fixed. + 08-11-20 A bug in which jobs were not cleared from the jobs table + for interactive shells when the pipefail option is on + has been fixed. + 08-11-11 A bug in which running a simple command & inside a + function would not return the correct process id has + been fixed. + 08-11-06 A bug which could cause a core dump when the _ reference + variable was used as an embedded type with a compound + assignment has been fixed. + +------------------------------------------------------------------- +Fri Nov 4 11:06:16 CET 2008 - werner@suse.de + +- Switch to 2008-11-04 of ksh93t for a minor and minimal fix within + the shell syntax parser. + +------------------------------------------------------------------- +Fri Oct 31 11:07:06 CET 2008 - werner@suse.de + +- Switch to 2008-10-31 beta test of ksh93t to fix core dump + in scoping/initialization of variables and arrays. + +------------------------------------------------------------------- +Tue Oct 14 12:19:38 CEST 2008 - werner@suse.de + +- Switch to 2008-10-10 beta test of ksh93t to fix multibyte handle + in the read builtin and fix a bug in array type handle. + +------------------------------------------------------------------- +Mon Oct 13 13:57:27 CEST 2008 - werner@suse.de + +- Switch to 2008-10-09 beta test of ksh93t to fix a hang caused by + a subshell command substitution with redirection and a crash in + typeset with types that contain arrays of other types a members + +------------------------------------------------------------------- +Thu Oct 9 15:08:12 CEST 2008 - werner@suse.de + +- Switch to 2008-10-01 beta test of ksh93t to fix several crashes +- Do not install locale data as this do not work (bnc#433739) + +------------------------------------------------------------------- +Mon Sep 22 11:52:33 CEST 2008 - werner@suse.de + +- Switch to 2008-09-21 beta test of ksh93t as this fix a crash +- Change manual page: ksh uses socketpair(2) for pipes (bnc#422675) + +------------------------------------------------------------------- +Fri Sep 19 16:02:05 CEST 2008 - werner@suse.de + +- Switch to 2008-09-17 beta test of ksh93t as this fix a crash +- Install the shell functions pushd, popd, and dirs +- Set FPATH accordingly to last change + +------------------------------------------------------------------- +Fri Sep 12 15:45:45 CEST 2008 - werner@suse.de + +- Add compiler flags -fno-delete-null-pointer-checks and -fno-tree-vrp + to avoid miss-compile at least of strdup(ast3) maybe caused by a + missing volatile modifier +- Update to release 2008-07-25 of ksh93t + Changes in ksh + 08-07-09 The typeset -C option can be used with arrays to indicate that + each element should default to a compound variable. + 08-07-08 The %B format now outputs compound variables and arrays. The + alternate flag # can be used to cause output into a single line. + 08-06-23 KSH_VERSION added as a name reference to .sh.version. + 08-06-20 type now outputs 'special builtin' for special builtins. + 08-06-16 When typeset -p is followed by variable names, it now displays + the attributes names and values for the specific names. + 08-06-13 The .sh.lineno variable has been added. When .sh.level is changed + inside a DEBUG trap, the .sh.lineno contains the calling line number + for the specified stack frame. + 08-06-13 The .sh.level variable has been documented and now works. + 08-06-11 The -C option has been added to read for reading compound command + definitions from a file. + 08-06-11 The . command is now permitted inside a compound command definition. + The dot script can contain declaration commands and dot commands. + 08-06-09 Add -C option to typeset so that typeset -C foo, is equivalent + to foo=(). + 08-06-09 Added -n warning message for typeset option orderings that are valid + with ksh88 but not valid with ksh93, for example Lx5. + 08-06-02 When defining a type, the typeset -r attribute causes this field + to be required to be specified for each instance of the type and + does not allow a default value. + 08-05-22 The ceil function has been added to the math functions. + 08-05-19 The array expansions ${array[sub1..sub2]} and ${!array[sub1..sub2]} + to expand to the value (or subscripts) for array between sub1 and + sub2 inclusive. For associative arrays, the range is based on + location in the POSIX locale. The .. must be explicit and cannot + result from an expansion. + 08-05-15 The trap on SIGCLD is no longer triggered by the completion of + the foreground job as with ksh88. + 08-05-12 The unset built-in now returns non-zero when deleting an array + subscript that is not set. + 08-05-08 Changing the value of HISTFILE or HISTSIZE will cause the old + history file to be close and reopened with the new name or size. + 08-05-08 When FPATH is changed functions that were found via a path search + will be searched for again. + 08-05-07 The typeset -S option was added for variables outside type + definitions to provide a storage class similar to C static + inside a function defined with function name. + 08-05-01 In multiline edit mode, the refresh operation will now clear + the remaining portion of the last line. + 08-04-30 The emacs and vi editors have been modified to handle window + change commands as soon as they happen rather than waiting for + the next command. + 08-04-04 Choose the name _ as the sub-variable that holds type or instance + specific data used by discipline functions. + 08-03-20 Associative array assignments of the form ([name]=value ...) + now allow ; as well as space tab and new line to separate elements. + 08-03-17 --default option added to set(1) to handle set +o POSIX semantics. + set --state added as a long name alias for set +o. + 08-03-10 The new ${...} command substitution will treat the trailing } + as a reserved word even if it is not at the beginning of a command, + for example, ${ date }. + 08-03-10 If the name of the ENV begins with /./ or ././ then the + /etc/ksh.kshrc file will not be executed on systems that support + this interactive initialization file. + 08-02-29 The redirection operator >; has been added which for non-special + files, generates the output in a temporary file and writes the + specified file only of the command has completed successfully. + 08-02-14 The typeset -a option can now optionally be followed by the name + of an enumerication type which allows subscripts to be enumerations. + 08-02-14 The enum builtin which creates enumeration types has been added. + 08-02-12 The backoff logic when there are no more processes has been fixed. + 08-02-07 The -X option has been added to typeset. The -X option creates + a double precision number that gets displayed using the C99 %a + format. It can be used along with -l for long double. + 08-01-31 The -T option to typeset has been added for creating typed + variables. Also the -h and -S options have been added to + typeset that are only applicable when defining a type. + 08-01-31 The prefix expansion operator @ has been added. ${@name} + expandes to the type of name or yields the attributes. + 07-09-19 In both emacs and vi edit mode, the escape sequence \E[A (usually + cursor up, when the cursor is at the end of the line will fetch + the most recent line starting with the current line. + 07-09-18 The value of ${!var} was correct when var was a reference to an + array instance. + 07-09-18 The value of ${!var[sub]} was not expanding to var[sub] and this + was fixed. It also fixed ${name} where name is a name reference + to var[sub]. + 07-09-18 It is now legal to create a name reference without an initialization. + It will be bound to a variable on the first assignment. + 07-08-30 A discipline function can be invoked as ${x.foo} and is equivalent + to ${ x.foo;} and can be invoked as x.foo inside ((...)). + 07-07-03 The command substitution ${ command;} has been added. It behaves + like $(command) except that command is executed in the current + shell environment. The ${ must be followed by a blank or an + operator. + +------------------------------------------------------------------- +Mon May 5 13:23:13 CEST 2008 - werner@suse.de + +- Fix patch for option handling of echo builtin (bnc#385986) + +------------------------------------------------------------------- +Tue Mar 25 12:22:48 CET 2008 - werner@suse.de + +- Add missing link to file list + +------------------------------------------------------------------- +Mon Mar 17 14:30:03 CET 2008 - werner@suse.de + +- Work around a bug in former postun script + +------------------------------------------------------------------- +Thu Feb 14 13:04:13 CET 2008 - werner@suse.de + +- Add locale for ksh and libraries in ast format +- Update to official bugfix release 2008-02-02 of ksh93s+ + * A bug in which command substitution inside ((...)) could cause + syntax errors or lead to core dumps has been fixed. + * A bug in which discipline functions could be deleted when invoked + from a subshell has been fixed. + * A bug in which a command substitution consisting only of + assignments was treated as a noop has been fixed. + * A bug in which discipline functions invoked from withing a + compound assignment could fail has been fixed. + * Incomplete arithmetic assigments, for example ((x += )), now + generate an error message. + * A bug in which a set discipline defined for a variable before + an array assignment could cause a core dump has been fixed. + * A bug in on some systems in which exit status 0 is incorrectly + returned by a process that catches the SIGCONT signal is stopped + and then continued. + * libast: string/strmatch.c: fix str="" pat="" sub values + * libast: comp/conf.sh,conf.tab: handle /bin/sh \ in read data, redir subshell + * libast: misc/magic.tab: amd-x68, 64-bit => x86-64 + * libast: string/strnton.c,strntonll.c: add + * libcmd: expr.c: fix <=0 type that broke substr * 1 * + +------------------------------------------------------------------- +Sun Jan 27 21:33:50 CET 2008 - coolo@suse.de + +- fix changelog + +------------------------------------------------------------------- +Tue Jan 8 16:14:39 CET 2008 - werner@suse.de + +- Update to private bugfix release 2008-01-06 ksh93s+ + * A bug in on some systems in which exit status 0 is incorrectly + returned by a process that catches the SIGCONT signal is stopped + and then continued. + +------------------------------------------------------------------- +Fri Dec 21 14:05:34 CET 2007 - werner@suse.de + +- Update to private bugfix release 2007-12-15 of ksh93s+ + * A race condition in which a program that has been stopped and then + continued could loose the exit status has been fixed. + * Code to check for file system out of space write errors for all + writes has been added. + * A bug in the macro expander for multibyte characters in which + part of the character contains a file pattern byte has been fixed. + * A bug in the emacs edit mode when multiline was set that output + a backspace before the newline to the screen has been fixed. + * A bug in which using TAB after a variable name listing expansion + in the edit modes would cause the $ to disappear has been fixed. + * A bug in which setting IFS to readonly could cause a subsequent + command substitution to fail has been fixed. + * A work around for a gcc 4.* C99 "feature" that could cause a job + control shell to go into an infinite loop by adding the volatile + attribute to some auto vars in functions that call setjmp(). + * A bug in which the shell could read ahead on a pipe causing the + standard input to be incorrectly positioned has been fixed. + * A bug in which compound variable UTF-8 multibyte values were not + expanded or traced properly has been fixed. + * A bug where an unbalanced '[' in a command argument was not treated + properly has been fixed. + * A bug in which compatibility mode (no long option names) getopts(1) + incorrectly set the value of OPTARG for flag options has been fixed. + * A bug in which "hash -- name" treated "--" as an invalid name operand + has been fixed. + * typeset now handles "-t -- [-r] [--]" for s5r4 hash(1) compatibility. + * A bug in which the umask builtin mis-handled symbolic mode operands + has been fixed. + * Bugs in which shell arithmetic and the printf builtin mis-handled the + signs of { -NaN -Inf -0.0 } have been fixed. + * The full { SIGRTMIN SIGRTMIN+1 ... SIGRTMAX-1 SIGRTMAX } range + of signals, determined at runtime, are now supported. + * A bug in which creating an index array with only subscript 0 created + only a simple variable has been fixed. + * A bug in which appending to an indexed array using the form + name+=([sub]=value) could cause the array to become an associative + array has been fixed. + * A bug in which typeset without arguments could coredump if a + variable is declared as in indexed array and has no elements has + been fixed. + * A bug in which creating a local SECONDS variable with typeset in + a function could corrupt memory has been fixed. + * A bug which could cause a core dump when a script invoked by name + from a function used compound variables has been fixed. + * A bug in which printf %d "'AB" did not diagnose unconverted + characters has been fixed. + * printf %g "'A" support added for all floating point formats. + * A bug in which typeset -f fun did not display the function + definition when invoked in a subshell has been fixed. + * The sleep builtin was fixed so that all floating point + constants are valid operands. + * A bug in which the locale was not being restored after + LANG=value command has been fixed. + * A bug in which a nameref to a compound variable that was + local to the calling function would not expand correctly + when displaying is value has been fixed. + * A bug which cause cause a core dump if .sh.edchar returned + 80 characters or more from a keyboard trap has been fixed. + * A bug in which could cause a core dump when more than 8 file + descriptors were in use has been fixed. + * A bug in which creating a name reference to an instance of an + array when the array name is itself a reference has been fixed. + * The file completion code has been modified so that after an + `=' in any word, each : will be considered a path delimiter. + * A bug in which subprocess cleanup could corrupt the malloc() + heap has been fixed. + * A bug in which a name reference to an associatve array + instance could cause the subscript to be evaluated as an + arithmetic expression has been fixed. + * A bug in which the value of an array instance was of a + compound variable was not expanded correctly has been fixed. + * A bug which could cause a core dump when a compound assignment + was made to a compound variable element with a typeset -a + attribute has been fixed. + * A bug in which a trap ignored in a subshell caused it to be + ignored by the parent has been fixed. + * A bug in which the set command would generated erroneous + output for a variable with the -RZ attribute if the variable + name had been passed to a function has been fixed. + * A bug in which read x[1] could core dump has been fixed. + * A second bug in which after read x[sub] into an associative + array of an element that hasn't been assigned could lead to + a core dump has been fixed. + * A bug in which a pipeline that completed correctly could have + an exit status of 127 when pipefail was enabled has been fixed. + * The SHOPT_AUDIT compile option has been added for keyboard + logging. + * libast: string/strelapsed.c: "0" is a valid elapsed time! + * libast: sfio/sfreserve.c: preserve SF_SHARE sfrd() via sfreserve(f,0,0) + * libast: comp/setlocale.c: add sjis_mbtowc() to work around [\~] translation + * libast: features/signal.c: RT(1) .. RT(MAX-1) => RTMIN+1 .. RTMAX-1 + * libast: features/float: favor sscanf() due to gnu strto[l]d() nan bugs + * libast: regex/regcomp.c: fix REX_COLL_CLASS node allocation + size + * libast: sfio/sfcvt.c: use signbit() if available + * libast: features/isoc99: _ISOC99_SOURCE tests + * libast: port/astmath.c: add -DN=8 for signbit() + * libast: sfio/sfstrtod.h: don't forget about -0.0 + * libast: features/map.c: add { optopt optarg optind opterr } + * libast: features/stdio: add _filbuf => _ast__filbuf + * libast: comp/getsubopt.c: fix #undef that interfered with + + * libast: regex/regcomp.c: fix bug that missed ')' in ~(F)... + * libast: port/astconf.c: fix CONF_ALLOC 16 bit overflow + * libast: misc/fts.c: fix fts_close() to free the handle + * libast: comp/setlocale.c: second and subsequent + setlocale(*,"") reverts to previous + * libast: path/pathprobe.c: add vfs ST_NOSUID check + * libast: comp/conf.tab: add a few more xpg6 deferrals + * libast: astsa: update to share with mainline src via + _PACKAGE_astsa + * libast: sfio/sfgetr.c: no limit on string stream line size + * libast: sfio/sfextern.c: increase _Sfmaxr to 256*1024 + * libast: misc/procopen.c: tighten up SIGCHLD logic between + parent/child + * libast: misc/signal.c: unblock SIG_DFL after setting handler, + sig<0 => don't unblock + * libast: misc/fs3d.c: no $LD_PRELOAD => no 3d and avoids + invalid mount(2) call + * libast: vmalloc: vmstat(0,0)==1 => region in use, drop + VM_primary|VM_secondary + * libast: misc/recstr.c: handle [lL] gobbled by strtol() + * libast: path/pathprobe.c: handle '\r' in VERSION string + * libast: regex/regcache.c: regcache(0,n,0) extends cache to + size n (no shrinking) + * libast: tm/tmdata.c: add 2005-12-31, drop 1999-12-31 + * libcmd: cp.c: fix builtin state reinitialization + * libcmd: rev.c: honor multibyte locales + * libcmd: cp.c: open non-existent destination with O_EXCL + * libcmd: stty.c: add -t,--terminal-group to list tty pgrp + * libcmd: cksum.c: --silent -s => -S, -s == -x sys5 for gnu compatibility + * libcmd: tee.c: drop ancient bsd compatibility "-" operand => SIGINT + * libcmd: cksum.c: add SUM_LEGACY for -r + * libcmd: cp.c: plug usage string memory leak by using + per-builtin state + * libcmd: cksum.c: add sumprint() default scale arg, + --scale, --bsd for solaris + * libcmd: chmod.c: add --show,-n + * libcmd: wclib.c: bias checks for modern unix + * libcmd: cat.c: fix --squeeze-blank to reduce multiple blank + lines to *one* + * libsum: sum.h, sumlib.c: add SUM_LEGACY for legacy output + format + * libsum: sum-sha1.c: reinstate Steve Reid's public domain + implementation + * libsum: sumlib.c: drop GPL sum-sha1.c + +------------------------------------------------------------------- +Fri Nov 23 13:55:12 CET 2007 - werner@suse.de + +- Add missed limit patch +- Fix problem with endless loop due missing reset of the SIGTSTP + singal handler after a failed program execution (bug #343111) + +------------------------------------------------------------------- +Tue Nov 20 14:13:58 CET 2007 - werner@suse.de + +- Fix bug in mbchar() macro to be able to run test for bug #341594 +- Make option -n for echo builtin work even for AT&T universe + +------------------------------------------------------------------- +Fri Nov 16 17:16:36 CET 2007 - werner@suse.de + +- Fix the bug fix, that is decrement current size (bug #341594) + +------------------------------------------------------------------- +Fri Nov 16 15:13:36 CET 2007 - werner@suse.de + +- Enable signal handling for non-interactive mode (bug #339875) +- Ignore signal QUIT always (bug #339875) +- Ignore signal INT in case of waiting on a job (bug #339875) +- Handle multibyte chars in variable expansion (bug #341594) + +------------------------------------------------------------------- +Mon Oct 29 15:11:30 CET 2007 - werner@suse.de + +- Work around a double -g problem which breaks debugging builds + +------------------------------------------------------------------- +Mon Sep 17 13:16:53 CEST 2007 - werner@suse.de + +- Update to bugfix version 2007-06-28 of ksh93s+ (bug #263053) + * In vi insert mode, ksh no longer emits a backspace character + before the carriage return when the newline is entered + * A bug in which pipefail would cause a command to return 0 + when the pipeline was the last command and the failure + happened on a component other than the last has been fixed + * A bug in the expansion of ${var/pattern/rep} when pattern + or rep contained a left parenthesis in single quotes has + been fixed + * The braces for a subscripted variable with ${var[sub]} are + now optional when inside [[...]], ((...)) or as a subscript + * A bug in brace expansion in which single and double quotes + did not treat the comma as a literal character has been fixed + * The -p option of whence now disables -v + * Several bug fixes in compound variables and arrays of arrays + have been made + * A bug in which the %B format of printf was affected by the + locale has been fixed + * A bug in which \ was not removed in the replacement pattern + with ${var/pattern/rep} when it was not followed by \ or a + digit has been fixed + * A bug in which ksh -R file core dumped if no script was + specified has been fixed, it now displays an error message + * Added additional Solaris signals to signal table + * A bug in which a pipeline with command substitution inside + a function could cause a pipeline that invokes this function + to hang when the pipefail option is on has been fixed + * Added -q to whence + * A small memory leak with each redirection of a non-builtin + has been fixed +- Fix many wrong detected limits for Linux like INT_MAX +- Adapt FS3D file system: mount(2) of Linux uses five arguments +- Fix bug in pointer arithmetic: after reallocation the addresses + of the old area of an pointer array are changed (bug #300653) +- Overflow in keytrap(): strncpy(3) does not append ASCII 0 if + buffer is fully used +- This updated version includes fix for bug #268488 +- Enable the AT&T UNIVERSE for ksh as pdksh does, see bug #249783 + +------------------------------------------------------------------- +Wed Jun 20 15:15:28 CEST 2007 - werner@suse.de + +- Fix pointer arithmetics within sh_trim() (bug #284611) + +------------------------------------------------------------------- +Tue Jun 19 16:01:40 CEST 2007 - werner@suse.de + +- Correct bug ID (bug #284580) + +------------------------------------------------------------------- +Fri May 25 10:25:51 CEST 2007 - werner@suse.de + +- Minor issuse like file permissions + +------------------------------------------------------------------- +Thu May 3 15:22:49 CEST 2007 - werner@suse.de + +- Fix string conversion for high unsigned numbers (bug #268488) + +------------------------------------------------------------------- +Wed Apr 4 12:07:04 CEST 2007 - werner@suse.de + +- Minor correction for builtin uname -i + +------------------------------------------------------------------- +Mon Apr 2 17:46:01 CEST 2007 - werner@suse.de + +- Update to ksh93s+ (bug #239215) +- Be sure that iffe can handle option -n even if bash is used + +------------------------------------------------------------------- +Fri Mar 30 13:27:27 CEST 2007 - werner@suse.de + +- Disable AT&T UNIVERSE change + +------------------------------------------------------------------- +Wed Mar 28 14:15:25 CEST 2007 - werner@suse.de + +- Reset exit status in case of catching SIGCONT (bug #254649) +- Use the AT&T UNIVERSE for ksh as pdksh does (bug #249783) + +------------------------------------------------------------------- +Fri Jan 12 14:08:55 CET 2007 - werner@suse.de + +- Do not use binary OR instead of a logic OR (#233299) +- Help the compile time and run time linker (#233299) + +------------------------------------------------------------------- +Mon Nov 20 14:58:06 CET 2006 - werner@suse.de + +- Avoid that a sub shell close required file descriptors (#222411) + +------------------------------------------------------------------- +Fri Nov 10 17:00:07 CET 2006 - werner@suse.de + +- On ia64 a cast of an integer to a character pointer and back to + an long integer may results into an unaligned access, fix this + in the SIGWINCH handler (bug #209643) + +------------------------------------------------------------------- +Tue Nov 7 01:07:46 CET 2006 - ro@suse.de + +- fix permissions for manpages + +------------------------------------------------------------------- +Mon Jul 10 11:32:18 CEST 2006 - werner@suse.de + +- Don't trim backslash part of a multibyte character away (#189239) + +------------------------------------------------------------------- +Tue Jul 4 12:53:42 CEST 2006 - werner@suse.de + +- Builtin cut: allow last line without newline (#189231) +- Utility shcomp: fix segfault and install it (#189778) + +------------------------------------------------------------------- +Tue Jun 27 12:07:21 CEST 2006 - werner@suse.de + +- No segmentation fault if ksh uses shared command libray (#188404) + +------------------------------------------------------------------- +Tue Jun 20 16:23:49 CEST 2006 - werner@suse.de + +- Make it build even on new beta with new glibc headers + +------------------------------------------------------------------- +Wed May 31 17:18:43 CEST 2006 - werner@suse.de + +- Fix segmentation fault in vi command line mode (bug #179917) + +------------------------------------------------------------------- +Mon May 29 15:16:03 CEST 2006 - werner@suse.de + +- Make -i and -p option of uname builtin work (bug #178962) + +------------------------------------------------------------------- +Tue May 9 11:39:59 CEST 2006 - werner@suse.de + +- Change PreRequire /bin/bash to /etc/bash.bashrc (bug #172633) + +------------------------------------------------------------------- +Mon May 8 12:54:39 CEST 2006 - werner@suse.de + +- Correct order of souring order of the users profile and the + system kshrc files (bug #172753) + +------------------------------------------------------------------- +Wed Apr 19 19:24:50 CEST 2006 - werner@suse.de + +- Do not source system rc files if ksh is not interactive +- Correct string from GMT to UTC for Universal Time Coordinates + +------------------------------------------------------------------- +Wed Apr 19 12:32:27 CEST 2006 - werner@suse.de + +- Fix the patch for the multi byte characters (bug #163665) + +------------------------------------------------------------------- +Tue Apr 18 18:10:56 CEST 2006 - werner@suse.de + +- Fix multi byte handling even for command line mode emacs/vi + +------------------------------------------------------------------- +Thu Apr 6 16:42:10 CEST 2006 - werner@suse.de + +- Handle multi byte characters within macro expansion (bug #163665) + +------------------------------------------------------------------- +Mon Mar 27 16:23:05 CEST 2006 - werner@suse.de + +- Update to ksh 93r + +------------------------------------------------------------------- +Wed Jan 25 21:37:15 CET 2006 - mls@suse.de + +- converted neededforbuild to BuildRequires + +------------------------------------------------------------------- +Tue Dec 20 11:46:03 CET 2005 - werner@suse.de + +- Move manual pages of libast to an own subsection 3ast (#140295) + +------------------------------------------------------------------- +Fri Dec 16 18:31:22 CET 2005 - werner@suse.de + +- Make it build even with bash 3.1 and gcc 4.1.0 + +------------------------------------------------------------------- +Thu Nov 17 13:01:47 CET 2005 - uli@suse.de + +- disabled some tests on ARM (occasionally hang QEMU) + +------------------------------------------------------------------- +Mon Oct 24 17:46:03 CEST 2005 - werner@suse.de + +- PreReqire the bash to get the system wide bash.bashrc + +------------------------------------------------------------------- +Mon Sep 19 17:26:30 CEST 2005 - werner@suse.de + +- Make it compatible with parallel installed pdksh (bug #105126) + +------------------------------------------------------------------- +Mon Sep 19 16:01:55 CEST 2005 - werner@suse.de + +- Avoid useless gcc warning of autogenerated sources + +------------------------------------------------------------------- +Tue Aug 16 15:57:40 CEST 2005 - werner@suse.de + +- Move to group System/Shells (bug #104920) + +------------------------------------------------------------------- +Wed Apr 13 18:10:15 CEST 2005 - werner@suse.de + +- Make it compile with gcc4 + +------------------------------------------------------------------- +Thu Mar 24 16:48:37 CET 2005 - werner@suse.de + +- Correct initialization for got_sigwinch variable + +------------------------------------------------------------------- +Wed Mar 23 17:35:12 CET 2005 - werner@suse.de + +- Update to release date 2005-02-02 (bug #18698, bug #74348) + +------------------------------------------------------------------- +Wed Mar 9 11:24:08 CET 2005 - werner@suse.de + +- Fix dead link in documentation (bug #71733) + +------------------------------------------------------------------- +Fri Feb 4 15:46:53 CET 2005 - werner@suse.de + +- More on winsize changes: now it works after a new prompt + just like in the pdksh. + +------------------------------------------------------------------- +Fri Feb 4 00:30:21 CET 2005 - schwab@suse.de + +- Workaround broken build system and enable building shared libraries on + x86-64. + +------------------------------------------------------------------- +Thu Feb 3 18:28:51 CET 2005 - werner@suse.de + +- Do not build shared version on x64_86 the ELF macro R_X64_86_32S + breaks that a local symbol +- Make it work on s390x + +------------------------------------------------------------------- +Thu Feb 3 13:30:44 CET 2005 - werner@suse.de + +- Make winsize changes work +- Enable /etc/ksh.kshrc support +- lchmod is not implemented under Linux +- error_exit does never return +- Enable shared libraries instead of the static ones +- Add a warning about CPL versus GPL + +------------------------------------------------------------------- +Wed Feb 2 19:14:49 CET 2005 - werner@suse.de + +- Initial version of the AT&T ksh now under CPL1.0 (bug #3698) + +------------------------------------------------------------------- diff --git a/ksh.spec b/ksh.spec new file mode 100644 index 0000000..c3465b7 --- /dev/null +++ b/ksh.spec @@ -0,0 +1,904 @@ +# +# spec file for package ksh +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +Name: ksh +%global date 2012-08-01 +%global use_suid_exe 0 +%global use_opt_bins 1 +%if !0%{?qemu_user_space_build:1} +%global do_tests 1 +%else +%global do_tests 0 +%endif +%global use_locale 0 +%if 0%{?suse_version} >= 1550 +%define libdir %{_libdir} +%define bindir %{_bindir} +%else +%define libdir /%{_lib} +%define bindir /bin +%endif +BuildRequires: bind-utils +BuildRequires: bison +BuildRequires: flex +BuildRequires: gdbm-devel +BuildRequires: glibc-devel +BuildRequires: groff +BuildRequires: libbz2-devel +BuildRequires: ncurses-devel +BuildRequires: procps +BuildRequires: psmisc +BuildRequires: update-alternatives +BuildRequires: zlib-devel +# /bin/ex and /bin/ed required for build +BuildRequires: awk +BuildRequires: ed +BuildRequires: strace +BuildRequires: vim +URL: http://www.research.att.com/~gsf/download/ +Requires(post): /bin/ln /bin/rm /etc/bash.bashrc /bin/true +Requires(postun):/bin/ln /bin/rm /etc/bash.bashrc /bin/true +Requires(post): update-alternatives +Requires(preun):update-alternatives +%if %use_suid_exe +PreReq: permissions +%endif +Version: 93vu +Release: 0 +Summary: Korn Shell +License: CPL-1.0 AND EPL-1.0 +Group: System/Shells +BuildRoot: %{_tmppath}/%{name}-%{version}-build +Source: INIT.%{date}.tar.bz2 +Source1: ast-base.%{date}.tar.bz2 +Source3: EPL +Source4: CPL +Source10: leak1.sh +Source11: leak2.sh +Source12: ifs-crash.sh +Source13: ulimit.sh +Source14: leak3.sh +Source20: Agreement +Source21: Warning +Source30: ksh-rpmlintrc +Source31: vmbalance +Source42: sigexec.c +Patch0: ksh93.dif +Patch1: workaround-stupid-build-system.diff +Patch2: ksh93-no-posix_spawn.dif +Patch3: ksh93-shift_ijs.dif +Patch4: ksh93-gmt2utc.dif +Patch5: ksh93-uname.dif +Patch6: ksh93-vi.dif +Patch7: ksh93-profile.dif +Patch8: ksh93-test.dif +Patch9: ksh93-compat.dif +Patch10: ksh93-suid_exec.dif +Patch11: ksh93-signals.dif +Patch12: ksh93-limits.dif +Patch13: ksh93-unset-f.dif +Patch14: ksh93-ia64.dif +Patch15: ksh93-s390.dif +Patch16: ksh93-gcc.dif +Patch17: ksh93-heredoc.dif +Patch18: ksh93-jobs.dif +Patch19: ksh93-reg.dif +Patch20: ksh93-aso.dif +Patch21: ksh93-vm.dif +Patch22: ksh93-limit-name-len.dif +Patch23: ksh93-foreground-prgrp.dif +Patch24: ksh93-builtin.dif +# PATCH-FIX-UPSTREAM ksh93-read-dont-ignore-esc.dif [bnc#765171] +# is part of ksh93u+ 2012-06-28 +# PATCH-EXTEND-UPSTREAM astksh_builtin_poll20120806_001.diff [bnc#779888] +Patch27: astksh_builtin_poll20120806_001.diff +# PATCH-FIX-UPSTREAM ksh93-env.dif [bnc#785266, bnc#803613] +Patch28: ksh93-env.dif +# PATCH-FIX-UPSTREAM ksh93-typedef.dif +Patch29: ksh93-typedef.dif +# PATCH-EXTEND-UPSTREAM ksh93-pathtemp.dif [bnc#786134] +# the fix is part of ksh93u+ 2012-06-28 +# nevertheless the /dev/shm extension is useful +Patch30: ksh93-pathtemp.dif +# PATCH-FIX-UPSTREAM ksh93-dttree-crash.dif [bnc#795324] +Patch31: ksh93-dttree-crash.dif +# PATCH-FIX-UPSTREAM ksh93-heredoclex.dif [bnc#804998] +Patch32: ksh93-heredoclex.dif +# PATCH-FIX-UPSTREAM ksh93-fdstatus.dif [bnc#808449, bnc#814135] +# this is a backport from the alpha version ksh93v-2013-04-22 +Patch33: ksh93-fdstatus.dif +# PATCH-FIX-UPSTREAM ksh93-alias-k.dif [bnc#824187] +Patch34: ksh93-alias-k.dif +# PATCH-FIX-SUSE Reduce warnings about uninitialized varaibles (most of them are handled correct) +Patch35: ksh93-uninitialized.dif +# PATCH-FIX-UPSTREAM Ouch ... use memmove instead of memcopy on overlapping areas +Patch36: ksh93-sfio.dif +# [bnc#899014] +Patch37: ksh93-path-skip.dif +Patch38: ksh93-fs3d.dif +# [bnc#852160] +Patch39: ksh93-subshellpwd.dif +# [bnc#867401] +Patch40: ksh93-cdpwd.dif +# [bnc#893031] +Patch41: ksh93-longenv.dif +Patch42: ksh93-malloc-hook.dif +Patch43: ksh93-disable-vfork.dif +Patch44: ksh93-joblock.dif +Patch45: ksh93-stkfreeze.dif +Patch46: ksh93-stkset-abort.dif +Patch47: ksh93-stkalias.dif +Patch48: ksh93-backtick.dif +Patch49: ksh93-nvtree-free.dif +Patch50: ksh93-int16double.dif +Patch51: ksh93-jpold.dif +Patch52: ksh93-redirectleak.dif +Patch53: ksh93-optimizeleak.dif +Patch54: ksh93-edpredict.dif +Patch55: ksh93-spawnlock.dif +Patch56: ksh93-filedefined.dif +Patch57: ksh93-no-sysctl.dif +Patch58: ksh93-putval.dif +Patch59: ksh93-untrustedenv.dif +Patch62: ksh-locale.patch +Patch63: cpp.patch + +%description +The original Korn Shell. The ksh is an sh-compatible command +interpreter that executes commands read from standard input or from a +file. + + + +Authors: +-------- + David Korn + Glenn Fowler + Phong Vo + +%package -n ksh-devel +Summary: Korn Shell development environment +License: CPL-1.0 +Group: Development/Libraries/C and C++ +Requires: ksh = %{version}-%{release} + +%description -n ksh-devel +The package includes C header files and the static libraries together +with the shared libraries for linking with other projects. Please be +aware that the CPL licensed code can not be used within GPL licensed +project. + + + +Authors: +-------- + David Korn + Glenn Fowler + Phong Vo + +%prep +chmod +x %{S:31} +%setup -q -n ksh93 -T -c -a 0 +tar --use-compress-program=bzcat -xf %{S:1} \ + lib/package/ \ + src/cmd/ksh93/ src/lib/libast/ src/lib/libcmd/ src/lib/libcoshell/ src/lib/libdll/ src/lib/libsum/ \ + src/cmd/builtin/ src/cmd/msgcc/ src/lib/libpp/ src/lib/libuu/ +if test -d share ; then + find share/ \( -name chef -o -name fudd -o -name piglatin -o -name valley \) -a -type d |\ + xargs -r rm -vrf + find share/ ! \( -name libast -o -name libcmd -o -name libdll -o -name libshell \) -a -type f |\ + xargs -r rm -vf + find share/ -type d -a -empty | xargs -r rm -vrf + find share/ -type d -a -empty | xargs -r rm -vrf +fi +%patch -P 0 +%patch -P 62 +%patch -P 1 +%patch -P 2 +%patch -P 3 +%patch -P 4 +%patch -P 5 +%patch -P 6 +%patch -P 7 +%patch -P 8 +%patch -P 9 +%patch -P 10 +%patch -P 11 +%patch -P 12 +%patch -P 13 +%ifarch ia64 +%patch -P 14 +%endif +%patch -P 15 +%patch -P 16 +%patch -P 17 +%patch -P 18 +%patch -P 19 +%patch -P 20 +%patch -P 21 +%patch -P 22 +%patch -P 23 +%patch -P 24 +%patch -P 27 +%patch -P 28 +%patch -P 29 +%patch -P 30 +%patch -P 31 +%patch -P 32 +%patch -P 33 +%patch -P 34 +%patch -P 35 +%patch -P 36 +%patch -P 37 +%patch -P 38 +%patch -P 39 +%patch -P 40 +%patch -P 41 +%patch -P 42 +%if 0%{?ksh_no_vfork} +%patch -P 43 +%endif +%patch -P 44 +%patch -P 45 +%patch -P 46 +%patch -P 47 +%patch -P 48 +%patch -P 49 +%patch -P 50 +%patch -P 51 +%patch -P 52 +%patch -P 53 +%patch -P 54 +%patch -P 55 +%patch -P 56 +%patch -P 57 +%patch -P 58 +%patch -P 59 + +%patch -P 63 -p 1 + +%build +%global _lto_cflags %{_lto_cflags} -ffat-lto-objects + + # + # Check for a clean signal environment for runtime tests + # + typeset -i IGNORED=0x$(ps --no-headers -o ignored $$) + typeset -i SIGMASK=0x0 + typeset -i usesigexec=0 + + let "SIGMASK|=(1<<($(kill -l PIPE)-1))" + let "SIGMASK|=(1<<($(kill -l URG) -1))" + let "SIGMASK|=(1<<($(kill -l XFSZ)-1))" + + ((IGNORED & SIGMASK)) && let ++usesigexec || true + test -t 0 || let ++usesigexec + +%if 0%{?qemu_user_space_build:1} + # agraf: In a qemu user space build, ps can not find the actual sigmask + # of processes, so we run into an endless loop. Disable sigexec. + usesigexec=0 +%endif + + if ((usesigexec > 0)) ; then + ${CC:-gcc} ${RPM_OPT_FLAGS} -o sigexec %{S:42} -lutil + for fd in /proc/$$/fd/*; do + test -s $fd -a ! -c $fd && break || true + done + set -- $(readlink $fd) + exec ./sigexec $SHELL ${1+"$@"} + fi + IGNORED=0x$(ps --no-headers -o ignored $$) + + AR="ar" + CC=gcc + PATH=${PWD}:$PATH + LANG=POSIX + TMPDIR=$(mktemp -d /tmp/ksh-build.XXXXXX) || exit 1 + SUSE_ASNEEDED=0 + export AR CC PATH LANG TMPDIR SUSE_ASNEEDED + # + # Remove optimizer which cause runtime leaks in ksh + # + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-funwind-tables/}" + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-fasynchronous-unwind-tables/}" + # This package failed when testing with -Wl,-as-needed being default. + # So we disable it here, if you want to retest, just delete this + # comment and the line below. + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-as-needed/-no-as-needed/}" + # Use POSIX as environment + test -n "${!LC_*}" && unset "${!LC_*}" + # ksh currently does not build with -Werror=return-type + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-Werror=return-type/}" + cflags () + { + set +x + local flag=$1; shift + local var=$1; shift + test -n "${flag}" -a -n "${var}" || return + case "${!var}" in + *${flag}*) return + esac + set -o noclobber + case "$flag" in + -Wl,*) + if echo 'int main () { return 0; }' | \ + ${CC:-gcc} -Werror $flag -o /dev/null -xc - > /dev/null 2>&1 ; then + eval $var=\${$var:+\$$var\ }$flag + fi + ;; + *) + if ${CC:-gcc} -Werror $flag -S -o /dev/null -xc /dev/null > /dev/null 2>&1 ; then + eval $var=\${$var:+\$$var\ }$flag + fi + esac + set +o noclobber + set -x + } + relink () + { + set +x + local search=$1; shift + local target=$1; shift + test -n "${search}" -a -n "${target}" || exit 1 + local object=$(find ${root:-/tmp}/src/cmd/ -name ${search}.o) + local cmd=$( + grep -e "-o $search" ${log:-/dev/null} | tail -n 1 | \ + sed -r -e "s@\+ g?cc@${CC:-gcc}@" \ + -e "s@-o $search@-o ${root:-/tmp}$target@" \ + -e "s@[[:blank:]]${search}.o[[:blank:]]@ $object @" \ + -e "s@[[:blank:]](/[^[:blank:]]*)?lib([[:alnum:]]+)\.a@ -l\2@g" \ + -e "s@'@@g") + set -x + $cmd ${1+"$@"} + } + # + # If _you_ are knowing how to fix this in the autogenerated + # sources of ksh/ast without breaking them, then let me know. + # + cflags -Wno-missing-braces IGNORE + cflags -Wno-unknown-pragmas IGNORE + cflags -Wno-parentheses IGNORE + cflags -Wno-char-subscripts IGNORE + cflags -Wno-uninitialized IGNORE + cflags -Wno-implicit IGNORE + cflags -Wno-unused-value IGNORE + cflags -Wno-type-limits IGNORE + cflags -Wclobbered RPM_OPT_FLAGS + # + # Do not use -DSHOPT_SPAWN=1 and/or -DSHOPT_AMP=1 this would cause + # errors due race conditions while executing the test suite. + # + feature=${PWD}/.feature.h + set -C + (cat > $feature)<<-'EOF' + #define SHOPT_FS_3D 0 + #define SHOPT_SYSRC 1 + #define SHOPT_REMOTE 1 + #define SHOPT_CMDLIB_BLTIN 1 + #define SHOPT_CMDLIB_HDR + #define SHOPT_CMDLIB_DIR "%{libdir}/ast/bin" + #define SH_CMDLIB_DIR "%{libdir}/ast/bin" + #define THISPROG "%{libdir}/ast/bin/suid_exec" + #define _AST_std_malloc 0 + #define _map_malloc 1 + EOF + set +C + FEATURE="-include $feature" + cat $feature + # + # + LARGEFILE="$(getconf LFS_CFLAGS)" + case "$RPM_ARCH" in + i[3456]86) + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-O[s0-9]/-O2}" + cflags -m32 RPM_OPT_FLAGS + HOSTTYPE=linux.i386 + ;; + x86_64) + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-O[s0-9]/-O2}" + cflags -m64 RPM_OPT_FLAGS + HOSTTYPE=linux.i386-64 + ;; + ia64) + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-O[s0-9]/-O}" + cflags -mlp64 RPM_OPT_FLAGS + cflags -mno-volatile-asm-stop RPM_OPT_FLAGS + HOSTTYPE=linux.ia64 + ;; + s390) + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-O[s0-9]/-O}" + cflags -m31 RPM_OPT_FLAGS + HOSTTYPE=linux.s390 + ;; + s390*) + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-O[s0-9]/-O}" + cflags -m64 RPM_OPT_FLAGS + HOSTTYPE=linux.s390-64 + ;; + ppc|powerpc) + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-O[s0-9]/-O}" + cflags -mno-powerpc64 RPM_OPT_FLAGS + HOSTTYPE=linux.powerpc + _PACKAGE_HOSTTYPE_=linux.powerpc + export _PACKAGE_HOSTTYPE_ + ;; + ppc64le|powerpc64le) + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-O[s0-9]/-O}" + # -mpowerpc64 is correct, the compiler defaults to + # little endian anyway + cflags -mpowerpc64 RPM_OPT_FLAGS + HOSTTYPE=linux.powerpc64le + ;; + ppc64|powerpc64) + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-O[s0-9]/-O}" + cflags -mpowerpc64 RPM_OPT_FLAGS + HOSTTYPE=linux.powerpc64 + ;; + *) + RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-O[s0-9]/-O}" + HOSTTYPE=linux.$RPM_ARCH + ;; + esac + MEMORY=execve + for mm in mmap mmap2 mmap64 munmap munmap2 munmap64 ; do + if strace -e $mm /bin/true > /dev/null 2>&1 ; then + MEMORY="${MEMORY:+${MEMORY},}$mm" + fi + done + MEMORY="-s 128 ${MEMORY:+-e ${MEMORY}}" + RPM_OPT_FLAGS=$(echo "${RPM_OPT_FLAGS}"|sed -r 's/([[:blank:]]+)-g[[:digit:]]+/\1-g2/g;s/([[:blank:]]+)-g([[:blank:]]+|$)/\1-g2\2/g') + UNIVERSE=att + LDFLAGS="-lm" + LDSOFLG="" + cflags -std=gnu99 RPM_OPT_FLAGS + cflags -fPIC RPM_OPT_FLAGS + cflags -fno-strict-aliasing RPM_OPT_FLAGS + cflags -fno-zero-initialized-in-bss RPM_OPT_FLAGS + cflags -fno-delete-null-pointer-checks RPM_OPT_FLAGS + cflags -fno-unsafe-loop-optimizations RPM_OPT_FLAGS + cflags -fsigned-bitfields RPM_OPT_FLAGS + cflags -fsigned-chars RPM_OPT_FLAGS + cflags -fsigned-zeros RPM_OPT_FLAGS + case "$(gcc --version | head -n 1)" in + *4.[012345].*) + cflags -fno-tree-sink RPM_OPT_FLAGS ;; + *) cflags -ftree-loop-linear RPM_OPT_FLAGS ;; + esac + cflags -g2 RPM_OPT_FLAGS + cflags -pipe RPM_OPT_FLAGS + cflags -Wl,-O2 LDFLAGS + cflags -Wl,--hash-size=16699 LDFLAGS + cflags -Wl,-O2 LDSOFLG + cflags -Wl,-warn-common LDSOFLG + cflags -Wl,--as-needed LDSOFLG + cflags -Wl,--hash-size=8599 LDSOFLG + cflags -Wl,-Bsymbolic-functions LDSOFLG + cflags -Wl,-rpath,%{libdir}/ast LDSOFLG + RPM_OPT_FLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE $LARGEFILE" + RPM_OPT_FLAGS="$RPM_OPT_FLAGS $IGNORE $FEATURE" + mam_cc_L=use + mam_cc_OPTIMIZE=-pipe + export mam_cc_L mam_cc_OPTIMIZE HOSTTYPE LDFLAGS RPM_OPT_FLAGS UNIVERSE + printenv + getconf PAGESIZE + + # + # Build libast first and then determine the library functions used + # by this library simply to avoid that gcc will overwrites those with + # its own builtin functions. + # + bin/package view + root=$(echo ${PWD}/arch/linux*) + bin/package make ast-ast CCFLAGS="$RPM_OPT_FLAGS -fno-builtin -I${root}/include" HOSTTYPE="$HOSTTYPE" AR="$AR" CC="$CC" + test -d $root || exit 1 + log=${root}/lib/package/gen/make.out + test -s $log || exit 1 + for lib in libast ; do + test -s ${root}/lib/${lib}.a || exit 1 + obj=$(ar t ${root}/lib/${lib}.a) + test $? -eq 0 || exit 1 + case "$lib" in + libast) + base=src/lib/$lib + vers=$(grep :LIBRARY: ${base}/Makefile | sed "s@.*\([0-9]\+\.[0-9]\+\).*@\1@") + link="-L${root}/lib/ -Wl,-rpath-link,${root}/lib -Wl,-rpath,%{libdir}/ast $LDSOFLG" + ;; + esac + soname="-Wl,-soname,${lib}.so.${vers%.*},-stats" + pushd ${root}/${base} + $CC -shared $soname -o ${root}/lib/${lib}.so.${vers} ${obj} $link + ln -sf ${lib}.so.${vers} ${root}/lib/${lib}.so.${vers%.*} + ln -sf ${lib}.so.${vers} ${root}/lib/${lib}.so + popd + done + nobuiltin=${PWD}/.nobuiltin + nm -D ${root}/lib/libast.so | \ + grep -E 'T[[:blank:]](_ast_)?(str|mem|(get|put|set)env|free|(c|m|re|v|vm)alloc)' | \ + sed -r 's/[[:xdigit:]]+[[:blank:]]+T[[:blank:]]+(_ast_)?([^[:blank:]]*)/-fno-builtin-\2/' | \ + sort -u > $nobuiltin + rm -rf $root + case "$(gcc --version | head -n 1)" in + *4.[01].*) + set +x + for opt in $(cat $nobuiltin) ; do + cflags $opt RPM_OPT_FLAGS + done + set -x + ;; + *) cflags @$nobuiltin RPM_OPT_FLAGS + esac + + export | grep -vE 'PROFILEREAD|PWD|MAIL|HOME|HOST|HIST|LESS|TMP' > .env + bin/package make CCFLAGS="$RPM_OPT_FLAGS -I${root}/include" HOSTTYPE="$HOSTTYPE" AR="$AR" CC="$CC" + root=$(echo ${PWD}/arch/linux*) + test -d $root || exit 1 + log=${root}/lib/package/gen/make.out + test -s $log || exit 1 + for lib in libast libcmd libdll libshell ; do + test -s ${root}/lib/${lib}.a || exit 1 + obj=$(ar t ${root}/lib/${lib}.a) + test $? -eq 0 || exit 1 + case "$lib" in + libshell) + base=src/cmd/ksh93 + vers=$(grep ^VERSION ${base}/Makefile | sed "s@.*\([0-9]\+\.[0-9]\+\).*@\1@") + link="-L${root}/lib/ -Wl,-rpath-link,${root}/lib -Wl,-rpath,%{libdir}/ast $LDSOFLG $LDFLAGS -ldll -lcmd -last -lm -ldl" + ;; + libdll) + base=src/lib/$lib + vers=$(grep :LIBRARY: ${base}/Makefile | sed "s@.*\([0-9]\+\.[0-9]\+\).*@\1@") + link="-L${root}/lib/ -Wl,-rpath-link,${root}/lib -Wl,-rpath,%{libdir}/ast $LDSOFLG -ldl -last" + ;; + libcmd) + base=src/lib/$lib + vers=$(grep :LIBRARY: ${base}/Makefile | sed "s@.*\([0-9]\+\.[0-9]\+\).*@\1@") + link="-L${root}/lib/ -Wl,-rpath-link,${root}/lib -Wl,-rpath,%{libdir}/ast $LDSOFLG -last" + ;; + libast) + base=src/lib/$lib + vers=$(grep :LIBRARY: ${base}/Makefile | sed "s@.*\([0-9]\+\.[0-9]\+\).*@\1@") + link="-L${root}/lib/ -Wl,-rpath-link,${root}/lib -Wl,-rpath,%{libdir}/ast $LDSOFLG" + ;; + esac + soname="-Wl,-soname,${lib}.so.${vers%.*},-stats" + pushd ${root}/${base} + $CC -shared $soname -o ${root}/lib/${lib}.so.${vers} ${obj} $link + ln -sf ${lib}.so.${vers} ${root}/lib/${lib}.so.${vers%.*} + ln -sf ${lib}.so.${vers} ${root}/lib/${lib}.so + popd + done + base=src/cmd/ksh93 + test=${PWD}/${base}/tests + OPATH=$PATH + OSHELL=$SHELL + PATH=$PATH:${root}/bin + SHELL=${root}/bin/ksh + SHCOMP=${root}/bin/shcomp + export PATH SHCOMP SHELL +%if %do_tests + pushd ${test} + typeset -i failed=0 + ln -sf ${root}/lib ${test}/../ + sed -ri '/^L[[:blank:]]/a \t 8000' pty.sh + sed -ri 's/(SECONDS[[:blank:]]*>[[:blank:]]*)([[:digit:]]+)/\18/' signal.sh + unset ${!LESS*} + printf '\033[1m' + grep -E '^(model name|flags)[[:blank:]]*:' /proc/cpuinfo | sort -ur | fold -s + printf '\033(B\033[m' + ${SHELL} shtests + result=$(${SHELL} -k -c 'd=`/bin/echo x y=z`; echo $d x y=z') + test "$result" = 'x x' || exit 1 + result=$(${SHELL} -c 'echo | echo "x`/bin/echo y`"') + test "$result" = xy || exit 1 + result=$(${SHELL} -c 'echo | echo "x$(/bin/echo y)"') + test "$result" = xy || exit 1 + exec 3> ${TMPDIR:-/tmp}/log + LANG=POSIX + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:10} 400 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:10} 4000 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:11} 400 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:11} 4000 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:12} 4 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:12} 40 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:13} 400 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:13} 4000 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:14} 400 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:14} 4000 + if test $((IGNORED & SIGPIPE)) -eq 0 ; then + ${SHELL} -c 'g="false"; trap "print -u2 PIPED; \$g && exit 0 ; g=true" PIPE ; while true ; do echo hello ; done' | head -n 10 + fi + LANG=en_US.UTF-8 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:10} 400 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:10} 4000 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:11} 400 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:11} 4000 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:12} 4 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:12} 40 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:13} 400 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:13} 4000 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:14} 400 + strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:14} 4000 + if test $((IGNORED & SIGPIPE)) -eq 0 ; then + ${SHELL} -c 'g="false"; trap "print -u2 PIPED; \$g && exit 0 ; g=true" PIPE ; while true ; do echo hello ; done' | head -n 10 + fi + LANG=POSIX + exec 3>&- + printf '\033[1m' + uniq -c ${TMPDIR:-/tmp}/log + printf '\033(B\033[m' + killall -q -s 9 ${SHELL} || true + popd +%endif + pushd ${root}/${base} + rm -f libshell.a + rm -f ${root}/bin/ksh + rm -f ${root}/bin/shcomp + for bin in ksh shcomp pty what mime asa dlls suid_exec ; do + relink $bin /bin/$bin -Wl,-rpath-link,${root}/lib -Wl,-rpath,%{libdir}/ast + done + popd + LD_LIBRARY_PATH=${root}/lib + export LD_LIBRARY_PATH + mkdir -p share/locale/C/LC_MESSAGES + includes="-I$(cpp -print-search-dirs | sed -rn 's@^install:[[:blank:]]@@p')include" + includes="$includes $(find $root -name FEATURE -printf ' -I%h')" + includes="$includes -I/usr/include/linux" + sed -rn "\@mamake -C cmd/ksh93@,\@mamake -C@ { + s@^\+ g?cc@$SHELL msgcc -M-set=ast $includes@ + s@[[:blank:]]-c[[:blank:]]([^[:blank:]\.]+/([^[:blank:]\.\/]+))\.c@ -c \1\.c -o msgs/\2\.mso@p + }" ${root}/lib/package/gen/make.out > src/cmd/ksh93/doit + pushd src/cmd/ksh93 + mkdir msgs + ${root}/lib/probe/C/pp/probe $(type -p gcc) > pp_default.h + $SHELL ./doit + $SHELL msgcc -o libshell.msg msgs/*.mso + rm -rf msgs/ + popd + msggen share/locale/C/LC_MESSAGES/libshell src/cmd/ksh93/libshell.msg + pushd ${root}/bin + PATH=$PATH:. + set -- $(shcomp --version 2>&1) + eval version=\${$#} + for bin in shcomp pty what mime asa dlls ; do + $bin --nroff 2>&1 | sed 's/\(\.TH .*\)/\1 "%{date}" "" "Korn shell utilities"/' > ../man/man1/$bin.1ast + done + popd + test -d /tmp -a /tmp -ef ${TMPDIR} || rm -rf ${TMPDIR} + SHELL=$OSHELL + PATH=$OPATH + +%install + root=$(echo ${PWD}/arch/linux*) + test -d $root || exit 1 + pushd $root || exit 1 + mkdir -p %{buildroot}%{bindir} + mkdir -p %{buildroot}%{_bindir} + mkdir -p %{buildroot}%{libdir}/ast/bin + mkdir -p %{buildroot}%{_includedir}/ast + mkdir -p %{buildroot}%{_libdir}/ast + mkdir -p %{buildroot}%{_mandir} + mkdir %{buildroot}%{_mandir}/man1 + mkdir %{buildroot}%{_mandir}/man3 +%if %use_locale + mkdir -p %{buildroot}%{_datadir}/locale +%endif + mkdir -p %{buildroot}%{_datadir}/ksh/fun + mkdir -p %{buildroot}%{_sysconfdir}/permissions.d + install bin/ksh %{buildroot}%{bindir}/ksh93 + install bin/shcomp %{buildroot}%{_bindir}/shcomp +%if %use_opt_bins + for bin in pty what mime asa dlls ; do + install bin/$bin %{buildroot}/%{_bindir}/$bin + done +%endif +%if %use_suid_exe + install bin/suid_exec %{buildroot}%{libdir}/ast/bin/ +%endif + # create update-alternatives symlinks + mkdir -p %{buildroot}%{_sysconfdir}/alternatives/ + touch %{buildroot}/%{_sysconfdir}/alternatives/ksh +%if 0%{?suse_version} < 1550 + touch %{buildroot}/%{_sysconfdir}/alternatives/usr-bin-ksh + ln -sf %{_sysconfdir}/alternatives/usr-bin-ksh %{buildroot}%{_bindir}/ksh +%endif + touch %{buildroot}/%{_sysconfdir}/alternatives/ksh.1.gz + touch %{buildroot}/%{_sysconfdir}/alternatives/rksh.1.gz + ln -sf %{_sysconfdir}/alternatives/ksh %{buildroot}%{bindir}/ksh + ln -sf %{_sysconfdir}/alternatives/ksh.1.gz %{buildroot}/%{_mandir}/man1/ksh.1.gz + ln -sf %{_sysconfdir}/alternatives/rksh.1.gz %{buildroot}/%{_mandir}/man1/rksh.1.gz + ln -sf %{bindir}/ksh93 %{buildroot}%{_bindir}/rksh + ln -sf ../../bin/ksh93 %{buildroot}%{libdir}/ast/ksh + ln -sf ast %{buildroot}%{libdir}/ksh + cp -a lib/*.so* %{buildroot}%{libdir}/ast/ + cp -a fun/* %{buildroot}%{_datadir}/ksh/fun/ + if cmp -s %{buildroot}%{_datadir}/ksh/fun/pushd %{buildroot}%{_datadir}/ksh/fun/popd ; then + ln -sf pushd %{buildroot}%{_datadir}/ksh/fun/popd + fi +%if 0%{?suse_version} < 1550 + for so in %{buildroot}%{libdir}/ast/*.so.*.* ; do + so=${so##*/} + ln -sf %{libdir}/ast/$so %{buildroot}%{_libdir}/ast/${so%%%%.*}.so + done + rm -f %{buildroot}%{_libdir}/ast/*.so.* +%endif + sed -rn '/^\.de Af/,/^\.\./p;/^\.de aF/,/^\.\./p' man/man3/int.3 > af.man + for man in $(grep -l '\.}S' man/man[138]/*.[138]); do + sed -ri '1r af.man' $man + done + for man in man/man[138]/*.[138] ; do + sed -ri 's/\\f5/\\fB/g;s/^\.H/\.P\n\.H/g;s/\.}S/\.aF/;s/^\.LI/\.LR/;s/\\\(le/\\\(<=/' $man + done + install -m 0644 lib/*.a %{buildroot}%{_libdir}/ast/ + install -m 0644 man/man1/sh.1 %{buildroot}%{_mandir}/man1/ksh93.1 + install -m 0644 man/man1/shcomp.1ast %{buildroot}%{_mandir}/man1/shcomp.1ast +%if %use_opt_bins + for bin in pty what mime asa dlls ; do + install -m 0644 man/man1/$bin.1ast %{buildroot}%{_mandir}/man1/$bin.1ast + done +%endif + for man in man/man3/*.3 ; do + man=${man##*/} + ast=${man}ast + install -m 0644 man/man3/${man} %{buildroot}%{_mandir}/man3/${ast} + done + install -m 0644 include/ast/* %{buildroot}%{_includedir}/ast/ + if cmp -s %{buildroot}%{_includedir}/ast/namval.h %{buildroot}%{_includedir}/ast/ast_namval.h ; then + ln -sf ast_namval.h %{buildroot}%{_includedir}/ast/namval.h + fi + popd +%if %use_locale + for msg in share/locale/* ; do + test -d $msg || continue + mkdir -p %{buildroot}%{_datadir}/locale/${msg##*/}/LC_MESSAGES + cp -vp ${msg}/LC_MESSAGES/* %{buildroot}%{_datadir}/locale/${msg##*/}/LC_MESSAGES/ + done + echo %%dir %{_datadir}/locale/C > ksh.lang + echo %%dir %{_datadir}/locale/C/LC_MESSAGES >> ksh.lang +%endif + find %{buildroot}/ -type f -o -type l | sed -r ' + s:%{buildroot}:: + s:(%{_datadir}/locale/)([^/_]+)(.*$):%%lang\(\2\) \1\2\3: + s:^([^%%].*):: + s:%%lang\(C\) :: + /^ *$/d' >> ksh.lang + if test -s lib/package/LICENSES/ast ; then + cp lib/package/LICENSES/ast LICENSE + else + cp %{S:3} EPL-1.0 + cp %{S:4} CPL-1.0 + ln -sf EPL-1.0 LICENSE + fi + mv src/cmd/ksh93/OBSOLETE src/cmd/ksh93/OBSOLETE.mm + echo '.VERBON 22' > grep.mm + sed -rn '/function grep/,/^}/p' src/cmd/ksh93/tests/grep.sh >> grep.mm + echo '.VERBOFF' >> grep.mm + tdevice=ascii8 + troff -Tascii8 < /dev/null > /dev/null 2>&1 || tdevice=utf8 + cat src/cmd/ksh93/builtins.mm | sed 's/\\f5/\\fB/g;s/^\.H/\.P\n\.H/g' | troff -T$tdevice -t -mm | grotty -bou > Builtins + cat src/cmd/ksh93/PROMO.mm | sed 's/\\f5/\\fB/g;s/^\.H/\.P\n\.H/g' | troff -T$tdevice -t -mm | grotty -bou > PROMO + cat src/cmd/ksh93/OBSOLETE.mm | sed 's/\\f5/\\fB/g;s/^\.H/\.P\n\.H/g' | troff -T$tdevice -t -mm | grotty -bou > OBSOLETE + cat src/cmd/ksh93/sh.memo | sed 's/\\f5/\\fB/g;s/^\.H/\.P\n\.H/g' | troff -T$tdevice -t -mm | grotty -bou > MEMORANDUM + cp %{S:21} . +%if %use_suid_exe + set -C + (cat > %{buildroot}%{_sysconfdir}/permissions.d/ksh) <<-EOF + %{libdir}/ast/bin/suid_exec root:root 4755 + EOF + (cat > %{buildroot}%{_sysconfdir}/permissions.d/ksh.paranoid) <<-EOF + %{libdir}/ast/bin/suid_exec root:root 0755 + EOF + set +C +%endif + +%if %use_suid_exe +%if %{defined verify_permissions} +%verifyscript +%verify_permissions -e %{libdir}/ast/bin/suid_exec +%endif +%endif + +%post +test -e etc/bash.bashrc && ln -sf bash.bashrc etc/ksh.kshrc || true +%if %use_suid_exe +%if %{defined set_permissions} +%set_permissions %{libdir}/ast/bin/suid_exec +%endif +%endif +if test -x %{libdir}/ast/bin/ksh ; then + %{_sbindir}/update-alternatives \ + --quiet \ + --force \ + --remove ksh %{libdir}/ast/bin/ksh + rm -f %{libdir}/ast/bin/ksh + rm -f %{libdir}/ast/bin/shcomp +fi +%{_sbindir}/update-alternatives \ + --install %{bindir}/ksh ksh %{bindir}/ksh93 20 \ +%if 0%{?suse_version} < 1550 + --slave %{_bindir}/ksh usr-bin-ksh /bin/ksh93 \ +%endif + --slave %{_mandir}/man1/ksh.1.gz ksh.1.gz %{_mandir}/man1/ksh93.1.gz \ + --slave %{_mandir}/man1/rksh.1.gz rksh.1.gz %{_mandir}/man1/ksh93.1.gz + +%postun +if test $1 -eq 0 -a ! -x bin/ksh ; then + if test ! -x bin/pdksh ; then + rm -f etc/ksh.kshrc + fi +fi +if [ ! -f %{bindir}/ksh93 ] ; then + %{_sbindir}/update-alternatives --quiet --remove ksh %{bindir}/ksh93 +fi + +%posttrans +if test -x bin/ksh -o -x bin/pdksh ; then + test -e etc/bash.bashrc && ln -sf bash.bashrc etc/ksh.kshrc || true +fi + +%files -f ksh.lang +%defattr(-,root,root) +%if %use_suid_exe +%config %attr(0644,root,root) %{_sysconfdir}/permissions.d/ksh +%config %attr(0644,root,root) %{_sysconfdir}/permissions.d/ksh.paranoid +%endif +%doc LICENSE EPL-1.0 CPL-1.0 src/cmd/ksh93/COMPATIBILITY src/cmd/ksh93/RELEASE* +%doc Builtins PROMO OBSOLETE MEMORANDUM +%{_bindir}/ksh +%doc %{_mandir}/man1/ksh.1.gz +%doc %{_mandir}/man1/rksh.1.gz +%doc %{_mandir}/man1/ksh93.1.gz +%ghost %{_sysconfdir}/alternatives/ksh +%if 0%{?suse_version} < 1550 +/bin/ksh93 +/bin/ksh +%ghost %{_sysconfdir}/alternatives/usr-bin-ksh +%endif +%ghost %{_sysconfdir}/alternatives/ksh.1.gz +%ghost %{_sysconfdir}/alternatives/rksh.1.gz +%doc %{_mandir}/man1/shcomp.1ast.gz +%if %use_opt_bins +%doc %{_mandir}/man1/pty.1ast.gz +%doc %{_mandir}/man1/what.1ast.gz +%doc %{_mandir}/man1/mime.1ast.gz +%doc %{_mandir}/man1/asa.1ast.gz +%doc %{_mandir}/man1/dlls.1ast.gz +%endif +%{_bindir}/* +%dir %{libdir}/ast +%dir %{libdir}/ast/bin +%if %use_suid_exe +%attr(4755,root,root) %{libdir}/ast/bin/suid_exec +%endif +%{libdir}/ast/*.so* +%{libdir}/ast/ksh +%{libdir}/ksh +%dir %{_datadir}/ksh +%dir %{_datadir}/ksh/fun +%{_datadir}/ksh/fun/* + +%files -n ksh-devel +%defattr(-,root,root) +%doc LICENSE Warning +%dir %{_libdir}/ast/ +%{_libdir}/ast/*.so +%{_libdir}/ast/*.a +%doc %{_mandir}/man3/* +%{_includedir}/ast/ + +%changelog diff --git a/ksh93-alias-k.dif b/ksh93-alias-k.dif new file mode 100644 index 0000000..10fae7b --- /dev/null +++ b/ksh93-alias-k.dif @@ -0,0 +1,13 @@ +--- src/cmd/ksh93/data/builtins.c ++++ src/cmd/ksh93/data/builtins.c 2013-06-11 16:24:46.269439322 +0000 +@@ -78,8 +78,8 @@ const struct shtable3 shtab_builtins[] = + #if _bin_newgrp || _usr_bin_newgrp + "newgrp", NV_BLTIN|BLT_ENV|BLT_SPC, Bltin(login), + #endif /* _bin_newgrp || _usr_bin_newgrp */ +- "alias", NV_BLTIN|BLT_SPC, bltin(alias), +- "hash", NV_BLTIN|BLT_SPC, bltin(alias), ++ "alias", NV_BLTIN|BLT_SPC|BLT_DCL, bltin(alias), ++ "hash", NV_BLTIN|BLT_SPC|BLT_DCL, bltin(alias), + "enum", NV_BLTIN|BLT_ENV|BLT_SPC|BLT_DCL,bltin(enum), + "eval", NV_BLTIN|BLT_ENV|BLT_SPC|BLT_EXIT,bltin(eval), + "exit", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(return), diff --git a/ksh93-aso.dif b/ksh93-aso.dif new file mode 100644 index 0000000..3cca437 --- /dev/null +++ b/ksh93-aso.dif @@ -0,0 +1,25 @@ +--- src/lib/libast/features/aso ++++ src/lib/libast/features/aso 2012-02-20 12:09:41.065934089 +0100 +@@ -5,7 +5,10 @@ if aso note{ gcc 4.1+ 64 bit memory atom + int main() + { + uint64_t i = 0; +- return __sync_fetch_and_add(&i,7); ++ uint32_t j = 0; ++ uint16_t l = 0; ++ uint8_t m = 0; ++ return __sync_fetch_and_add(&i,7)+__sync_fetch_and_add(&j,7)+__sync_fetch_and_add(&l,7)+__sync_fetch_and_add(&m,7); + } + }end && { + #define _aso_cas8(p,o,n) __sync_val_compare_and_swap(p,o,n) +@@ -31,7 +34,9 @@ elif aso note{ gcc 4.1+ 32 bit memory at + int main() + { + uint32_t i = 0; +- return __sync_fetch_and_add(&i,7); ++ uint16_t j = 0; ++ uint8_t l = 0; ++ return __sync_fetch_and_add(&i,7)+__sync_fetch_and_add(&j,7)+__sync_fetch_and_add(&l,7); + } + }end && { + #define _aso_cas8(p,o,n) __sync_val_compare_and_swap(p,o,n) diff --git a/ksh93-backtick.dif b/ksh93-backtick.dif new file mode 100644 index 0000000..f9e20c6 --- /dev/null +++ b/ksh93-backtick.dif @@ -0,0 +1,151 @@ +--- ./src/cmd/ksh93/sh/io.c.orig 2015-12-09 11:17:56.993309654 +0000 ++++ ./src/cmd/ksh93/sh/io.c 2015-12-09 11:20:10.671805470 +0000 +@@ -692,7 +692,7 @@ int sh_close(register int fd) + } + if(fd >= shp->gd->lim.open_max) + sh_iovalidfd(shp,fd); +- if(!(sp=shp->sftable[fd]) || sfclose(sp) < 0) ++ if(!(sp=shp->sftable[fd]) || sffileno(sp) != fd || sfclose(sp) < 0) + { + int err=errno; + if(fdnotify) +--- ./src/cmd/ksh93/sh/jobs.c.orig 2015-11-27 12:18:44.168204649 +0000 ++++ ./src/cmd/ksh93/sh/jobs.c 2015-11-27 14:49:54.255529119 +0000 +@@ -1630,6 +1630,8 @@ int job_wait(register pid_t pid) + } + sfsync(sfstderr); + job.waitsafe = 0; ++ if (pw && !job.savesig && shp->subshell) ++ sh_readpipedata(); + nochild = job_reap(job.savesig); + if(job.waitsafe) + continue; +--- ./src/cmd/ksh93/sh/macro.c.orig 2015-08-11 12:00:52.454212675 +0000 ++++ ./src/cmd/ksh93/sh/macro.c 2015-11-27 14:02:27.493074974 +0000 +@@ -2183,7 +2183,7 @@ static void comsubst(Mac_t *mp,register + stkseek(stkp,soff+foff+64); + stkseek(stkp,soff); + } +- if(foff > IOBSIZE) ++ if(sffileno(sp)>=0 && foff>(Sfoff_t)IOBSIZE) + sfsetbuf(sp,NULL,SF_UNBOUND); + while((str=(char*)sfreserve(sp,SF_UNBOUND,0)) && (c=bufsize=sfvalue(sp))>0) + { +--- ./src/cmd/ksh93/sh/subshell.c.orig 2015-08-11 11:59:29.030528394 +0000 ++++ ./src/cmd/ksh93/sh/subshell.c 2015-12-09 11:20:38.614700038 +0000 +@@ -105,11 +105,23 @@ static struct subshell + #if SHOPT_COSHELL + void *coshell; + #endif /* SHOPT_COSHELL */ ++ char *pipedata; ++ size_t pipedatalen; + } *subshell_data; + + static long subenv; + + ++static void sh_addtopipedata(struct subshell *sp, void *buf, size_t len) ++{ ++ if (!sp->pipedata) ++ sp->pipedata = malloc(len); ++ else ++ sp->pipedata = realloc(sp->pipedata, sp->pipedatalen + len); ++ memcpy(sp->pipedata + sp->pipedatalen, buf, len); ++ sp->pipedatalen += len; ++} ++ + /* + * This routine will turn the sftmp() file into a real /tmp file or pipe + * if the /tmp file create fails +@@ -146,7 +158,7 @@ void sh_subtmpfile(Shell_t *shp) + sh_fcntl(sp->pipefd,F_SETFD,FD_CLOEXEC); + /* write the data to the pipe */ + if(off = sftell(sfstdout)) +- write(fds[1],sfsetbuf(sfstdout,(Void_t*)sfstdout,0),(size_t)off); ++ sh_addtopipedata(sp, sfsetbuf(sfstdout,(Void_t*)sfstdout,0),(size_t)off); + sfclose(sfstdout); + if((sh_fcntl(fds[1],F_DUPFD, 1)) != 1) + errormsg(SH_DICT,ERROR_system(1),e_file+4); +@@ -173,6 +185,50 @@ void sh_subtmpfile(Shell_t *shp) + } + } + ++void sh_readpipedata() ++{ ++ register struct subshell *sp = subshell_data; ++ fd_set rfd; ++ if (sp) ++ sp = sp->pipe; ++ if (!sp || sp->pipefd < 0 || sp->pipefd >= FD_SETSIZE) ++ return; ++ sigset_t sigsaved, sigchld; ++ sigemptyset(&sigchld); ++ sigaddset(&sigchld, SIGCHLD); ++ /* block sigchild */ ++ sigprocmask(SIG_BLOCK, &sigchld, &sigsaved); ++ FD_ZERO(&rfd); ++ FD_SET(sp->pipefd, &rfd); ++ while (!job.savesig) { ++ int i = pselect(sp->pipefd + 1, &rfd, 0, 0, 0, &sigsaved); ++ if (i > 0) { ++ char buf[4096]; ++ i = read(sp->pipefd, buf, 4096); ++ if (i == 0 || (i < 0 && errno != EINTR)) ++ break; ++ sh_addtopipedata(sp, buf, i); ++ } ++ } ++ sigprocmask(SIG_SETMASK, &sigsaved, 0); ++} ++ ++void sh_emptypipe(struct subshell *sp, int pipefd) ++{ ++ int i; ++ char buf[4096]; ++ if (!sp || pipefd < 0) ++ return; ++ for (;;) { ++ i = read(pipefd, buf, 4096); ++ if (i < 0 && errno == EINTR) ++ continue; ++ if (i <= 0) ++ break; ++ sh_addtopipedata(sp, buf, i); ++ } ++} ++ + + /* + * This routine creates a temp file if necessary and creates a subshell. +@@ -614,7 +670,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + sp->tmpfd = -1; + sp->pipefd = -1; + /* use sftmp() file for standard output */ +- if(!(iop = sftmp(comsub==1?PIPE_BUF:IOBSIZE))) ++ if(!(iop = sftmp(comsub==1?SF_UNBOUND:IOBSIZE))) + { + sfswap(sp->saveout,sfstdout); + errormsg(SH_DICT,ERROR_system(1),e_tmpcreate); +@@ -822,6 +878,22 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + sh_argfree(shp,argsav,0); + if(shp->topfd != buff.topfd) + sh_iorestore(shp,buff.topfd|IOSUBSHELL,jmpval); ++ ++ /* empty the pipe and move all data into iop */ ++ if (comsub && sp->pipefd>=0) ++ { ++ sh_emptypipe(sp, sffileno(iop)); ++ sfclose(iop); ++ sp->pipefd = -1; ++ iop = sftmp(SF_UNBOUND); ++ if (sp->pipedatalen) ++ sfwrite(iop, sp->pipedata, sp->pipedatalen); ++ if (sp->pipedata) ++ free(sp->pipedata); ++ sp->pipedata = 0; ++ sp->pipedatalen = 0; ++ } ++ + if(sp->sig) + { + if(sp->prev) diff --git a/ksh93-builtin.dif b/ksh93-builtin.dif new file mode 100644 index 0000000..c8d9591 --- /dev/null +++ b/ksh93-builtin.dif @@ -0,0 +1,187 @@ +--- src/cmd/builtin/pty.c ++++ src/cmd/builtin/pty.c 2013-02-01 15:59:52.697952156 +0000 +@@ -216,27 +216,64 @@ mkpty(int* master, int* slave) + #if !_lib_openpty + char* sname; + #endif ++#ifdef __linux__ ++ sigset_t blckttou, oldset; ++ (void)sigemptyset(&blckttou); ++ (void)sigaddset(&blckttou, SIGTTOU); ++ sigprocmask(SIG_BLOCK, &blckttou, &oldset); ++#endif + /* + * some systems hang hard during the handshake + * if you know why then please let us know + */ + +- alarm(4); +- if (tcgetattr(STDERR_FILENO, &tty) >= 0) +- ttyp = &tty; +- else ++ alarm(6); ++ if (tcgetattr(sffileno(sfstderr), &tty) < 0) + { ++ if (errno != ENOTTY) ++ error(-1, "unable to get standard error terminal attributes"); ++ cfmakeraw(&tty); + ttyp = 0; +- error(-1, "unable to get standard error terminal attributes"); + } ++ tty.c_lflag |= ICANON | IEXTEN | ISIG | ECHO|ECHOE|ECHOK|ECHOKE; ++ tty.c_oflag |= (ONLCR | OPOST); ++ tty.c_oflag &= ~(OCRNL | ONLRET); ++ tty.c_iflag |= BRKINT; ++ tty.c_iflag &= ~IGNBRK; ++ tty.c_lflag |= ISIG; ++ tty.c_cc[VTIME] = 0; ++ tty.c_cc[VMIN] = CMIN; ++#ifdef B115200 ++ cfsetispeed(&tty, B115200); ++ cfsetospeed(&tty, B115200); ++#elif defined(B57600) ++ cfsetispeed(&tty, B57600); ++ cfsetospeed(&tty, B57600); ++#elif defined(B38400) ++ cfsetispeed(&tty, B38400); ++ cfsetospeed(&tty, B38400); ++#endif ++ ttyp = &tty; + #ifdef TIOCGWINSZ +- if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) >= 0) +- winp = &win; +- else ++ if (ioctl(sffileno(sfstderr), TIOCGWINSZ, &win) < 0) + { ++ if (errno != ENOTTY) ++ error(-1, "unable to get standard error window size"); ++ win.ws_row = 0; ++ win.ws_col = 0; + winp = 0; +- error(-1, "unable to get standard error window size"); + } ++ if (win.ws_row < 24) ++ win.ws_row = 24; ++ if (win.ws_col < 80) ++ win.ws_col = 80; ++ winp = &win; ++#endif ++#ifdef __linux__ ++# if !_lib_openpty ++# undef _lib_openpty ++# define _lib_openpty 1 ++# endif + #endif + #if _lib_openpty + if (openpty(master, slave, NULL, ttyp, winp) < 0) +@@ -279,6 +316,9 @@ mkpty(int* master, int* slave) + #if !O_cloexec + fcntl(*slave, F_SETFD, FD_CLOEXEC); + #endif ++#ifdef __linux__ ++ sigprocmask(SIG_SETMASK, &oldset, NULL); ++#endif + alarm(0); + return 0; + } +@@ -317,9 +357,13 @@ process(Sfio_t* mp, Sfio_t* lp, int dela + char* s; + Sfio_t* ip; + Sfio_t* sps[2]; ++ struct stat dst; ++ struct stat fst; + + ip = sfstdin; +- for (;;) ++ if (!fstat(sffileno(ip), &dst) && !stat("/dev/null", &fst) && dst.st_dev == fst.st_dev && dst.st_ino == fst.st_ino) ++ ip = 0; ++ do + { + i = 0; + t = timeout; +@@ -336,39 +380,39 @@ process(Sfio_t* mp, Sfio_t* lp, int dela + { + if (n < 0) + error(ERROR_SYSTEM|2, "poll failed"); +- if (t < 0) +- break; ++ break; + } +- else +- for (i = 0; i < n; i++) ++ for (i = t = 0; i < n; i++) ++ { ++ if (!(sfvalue(sps[i]) & SF_READ)) ++ /*skip*/; ++ else if (sps[i] == mp) + { +- if (!(sfvalue(sps[i]) & SF_READ)) +- /*skip*/; +- else if (sps[i] == mp) ++ t++; ++ if (!(s = (char*)sfreserve(mp, SF_UNBOUND, -1))) + { +- if (!(s = (char*)sfreserve(mp, SF_UNBOUND, -1))) +- { +- sfclose(mp); +- mp = 0; +- } +- else if ((r = sfvalue(mp)) > 0 && (sfwrite(sfstdout, s, r) != r || sfsync(sfstdout))) +- { +- error(ERROR_SYSTEM|2, "output write failed"); +- goto done; +- } ++ sfclose(mp); ++ mp = 0; + } +- else ++ else if ((r = sfvalue(mp)) > 0 && (sfwrite(sfstdout, s, r) != r || sfsync(sfstdout))) + { +- if (!(s = sfgetr(ip, '\n', 1))) +- ip = 0; +- else if (sfputr(mp, s, '\r') < 0 || sfsync(mp)) +- { +- error(ERROR_SYSTEM|2, "write failed"); +- goto done; +- } ++ error(ERROR_SYSTEM|2, "output write failed"); ++ goto done; + } + } +- } ++ else ++ { ++ t++; ++ if (!(s = sfgetr(ip, '\n', 1))) ++ ip = 0; ++ else if (sfputr(mp, s, '\r') < 0 || sfsync(mp)) ++ { ++ error(ERROR_SYSTEM|2, "write failed"); ++ goto done; ++ } ++ } ++ } ++ } while (t); + done: + if (mp) + sfclose(mp); +--- src/cmd/builtin/what.c ++++ src/cmd/builtin/what.c 2012-02-13 11:02:18.645933606 +0000 +@@ -68,7 +68,7 @@ static struct + int match; + int single; + size_t skip[UCHAR_MAX+1]; +- unsigned char prev[3]; ++ unsigned char prev[4]; + } state; + + static void +@@ -99,7 +99,7 @@ what(const char* file, Sfio_t* ip, Sfio_ + { + next: + s = state.prev; +- s[0] = s[1] = s[2] = 0; ++ s[0] = s[1] = s[2] = s[3] = 0; + switch (mid) + { + default: diff --git a/ksh93-cdpwd.dif b/ksh93-cdpwd.dif new file mode 100644 index 0000000..1471237 --- /dev/null +++ b/ksh93-cdpwd.dif @@ -0,0 +1,19 @@ +--- ./src/cmd/ksh93/bltins/cd_pwd.c.orig 2014-11-13 16:07:38.336318883 +0000 ++++ ./src/cmd/ksh93/bltins/cd_pwd.c 2014-11-13 16:24:53.323415375 +0000 +@@ -116,9 +116,14 @@ int b_cd(int argc, char *argv[],Shbltin_ + char *sp; + for(dp=dir; *dp=='.'; dp++) + { +- if(*++dp=='.' && (*++dp=='/' || *dp==0)) ++ if (dp[1]=='.' && (dp[2]=='/' || dp[2]==0)) ++ { + n++; +- else if(*dp && *dp!='/') ++ dp += 2; ++ } ++ else if (dp[1]=='/' || dp[1]==0) ++ dp++; ++ else + break; + if(*dp==0) + break; diff --git a/ksh93-compat.dif b/ksh93-compat.dif new file mode 100644 index 0000000..b2292f7 --- /dev/null +++ b/ksh93-compat.dif @@ -0,0 +1,83 @@ +--- src/lib/libast/astsa/ast.h ++++ src/lib/libast/astsa/ast.h 2012-02-21 12:03:33.000000000 +0000 +@@ -93,6 +93,12 @@ typedef struct + #define pointerof(x) ((void*)((char*)0+(x))) + #define roundof(x,y) (((x)+(y)-1)&~((y)-1)) + ++#ifdef __GNUC__ ++#if (__GNUC__ >= 4) && !defined(offsetof) ++#define offsetof(type,member) __builtin_offsetof(type,member) ++#endif ++#endif ++ + #ifndef offsetof + #define offsetof(type,member) ((unsigned long)&(((type*)0)->member)) + #endif +--- src/lib/libast/features/libpath.sh ++++ src/lib/libast/features/libpath.sh 2007-03-30 16:45:55.000000000 +0000 +@@ -21,7 +21,7 @@ + ######################################################################## + ok=0 + for i in \ +- -x /lib/ld.so /lib/ld-*.so /usr/lib/ld.so /lib/rld \ ++ -x /lib64/ld.so /lib/ld.so /lib64/ld-*.so /lib/ld-*.so /usr/lib/ld.so /lib/rld \ + -f /usr/shlib/libc.so /shlib/libc.so /usr/lib/libc.so \ + -r /usr/shlib/libc.so /shlib/libc.so + do case $i in +--- src/lib/libast/features/map.c ++++ src/lib/libast/features/map.c 2009-12-09 11:13:24.000000000 +0000 +@@ -67,10 +67,14 @@ main() + #define _map_malloc 1 + printf("\n"); + printf("#define _map_libc 1\n"); ++#endif ++#if _map_libc || defined(__linux__) + printf("#undef basename\n"); + printf("#define basename _ast_basename\n"); + printf("#undef dirname\n"); + printf("#define dirname _ast_dirname\n"); ++#endif ++#if _map_libc + #if !_lib_eaccess + printf("#undef eaccess\n"); + printf("#define eaccess _ast_eaccess\n"); +--- src/lib/libast/features/sys ++++ src/lib/libast/features/sys 2012-02-21 12:04:43.000000000 +0000 +@@ -134,7 +134,7 @@ tst typ_signed_size_t output{ + } + }end + +-define offsetof (type,member) ((size_t)&(((type*)0)->member)) ++define offsetof (type,member) __builtin_offsetof(type,member) + define EXIT_FAILURE 1 + define EXIT_SUCCESS 0 + define MB_CUR_MAX 1 +--- src/lib/libdll/features/dll ++++ src/lib/libdll/features/dll 2007-03-30 16:40:59.000000000 +0000 +@@ -15,7 +15,7 @@ tst dll_DYNAMIC link{ + }end + tst run{ + lib= +- for d in /shlib /usr/shlib /lib /usr/lib ++ for d in /lib64 /usr/lib64 /lib /usr/lib + do if test -d $d + then for s in "*.*" "*[!a]*" + do for b in libc +@@ -52,7 +52,7 @@ tst run{ + "") lib=/lib/libc.so.1 ;; + esac + case $lib in +- /usr/lib/*) ++ /usr/lib64/*|/usr/lib/*) + case `package` in + sgi.mips3) + abi=/lib32 +@@ -65,7 +65,7 @@ tst run{ + esac + case $abi in + ?*) if test -d $abi +- then lib=`echo $lib | sed 's,/usr/lib/,,'` ++ then lib=`echo $lib | sed 's,/usr/lib\(64\)\?/,,'` + lib=$abi/$lib + fi + ;; diff --git a/ksh93-disable-vfork.dif b/ksh93-disable-vfork.dif new file mode 100644 index 0000000..e99e7e5 --- /dev/null +++ b/ksh93-disable-vfork.dif @@ -0,0 +1,11 @@ +--- src/lib/libast/features/lib.orig 2014-11-19 13:03:58.009305098 +0000 ++++ src/lib/libast/features/lib 2014-11-19 13:23:05.010183379 +0000 +@@ -221,7 +221,7 @@ tst lib_vfork unistd.h stdlib.h vfork.h + _exit(2); + } + status = 1; +- _exit(wait(&status) < 0 || status != 0); ++ _exit(wait(&status) < 0 || status != 0 || 1); + } + }end + diff --git a/ksh93-dttree-crash.dif b/ksh93-dttree-crash.dif new file mode 100644 index 0000000..68fb9ba --- /dev/null +++ b/ksh93-dttree-crash.dif @@ -0,0 +1,960 @@ +--- src/cmd/ksh93/bltins/typeset.c ++++ src/cmd/ksh93/bltins/typeset.c 2013-10-25 13:20:42.799733785 +0000 +@@ -579,7 +579,7 @@ static int setall(char **argv,regist + np = sh_fsearch(shp,name,NV_ADD|HASH_NOSCOPE); + else + #endif /* SHOPT_NAMESPACE */ +- np = nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE); ++ np = nv_open(name,sh_subfuntree(shp,1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE); + } + else + { +@@ -1168,14 +1168,14 @@ static int unall(int argc, char **argv, + { + name = sh_optunalias; + if(shp->subshell) +- troot = sh_subaliastree(0); ++ troot = sh_subaliastree(shp,0); + } + else + name = sh_optunset; + while(r = optget(argv,name)) switch(r) + { + case 'f': +- troot = sh_subfuntree(1); ++ troot = sh_subfuntree(shp,1); + break; + case 'a': + all=1; +--- src/cmd/ksh93/include/defs.h ++++ src/cmd/ksh93/include/defs.h 2013-10-25 13:20:42.799733785 +0000 +@@ -423,10 +423,10 @@ extern void sh_printopts(Shopt_t,int,Sh + extern int sh_readline(Shell_t*,char**,volatile int,int,ssize_t,long); + extern Sfio_t *sh_sfeval(char*[]); + extern void sh_setmatch(Shell_t*,const char*,int,int,int[],int); +-extern Dt_t *sh_subaliastree(int); ++extern Dt_t *sh_subaliastree(Shell_t*,int); + extern void sh_scope(Shell_t*, struct argnod*, int); + extern Namval_t *sh_scoped(Shell_t*, Namval_t*); +-extern Dt_t *sh_subfuntree(int); ++extern Dt_t *sh_subfuntree(Shell_t*,int); + extern void sh_subjobcheck(pid_t); + extern int sh_subsavefd(int); + extern void sh_subtmpfile(Shell_t*); +--- src/cmd/ksh93/sh/arith.c ++++ src/cmd/ksh93/sh/arith.c 2013-10-25 13:20:42.799733785 +0000 +@@ -180,7 +180,10 @@ static Namval_t *scope(register Namval_t + { + ap = nv_arrayptr(np); + if(ap && !ap->table) ++ { + ap->table = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(ap->table,shp,1); ++ } + if(ap && ap->table && (nq=nv_search(nv_getsub(np),ap->table,NV_ADD))) + nq->nvenv = (char*)np; + if(nq && nv_isnull(nq)) +--- src/cmd/ksh93/sh/array.c ++++ src/cmd/ksh93/sh/array.c 2013-10-25 13:20:42.800733693 +0000 +@@ -79,6 +79,7 @@ struct assoc_array + + static Namarr_t *array_scope(Namval_t *np, Namarr_t *ap, int flags) + { ++ Shell_t *shp = sh_getinterp(); + Namarr_t *aq; + #if SHOPT_FIXEDARRAY + struct fixed_array *fp; +@@ -95,6 +96,7 @@ static Namarr_t *array_scope(Namval_t *n + if(is_associative(aq)) + { + aq->scope = (void*)dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(aq->scope,shp,1); + dtview((Dt_t*)aq->scope,aq->table); + aq->table = (Dt_t*)aq->scope; + return(aq); +@@ -271,6 +273,7 @@ int nv_arrayisset(Namval_t *np, Namarr_t + */ + static Namval_t *array_find(Namval_t *np,Namarr_t *arp, int flag) + { ++ Shell_t *shp=sh_getinterp(); + register struct index_array *ap = (struct index_array*)arp; + register union Value *up; + Namval_t *mp; +@@ -373,7 +376,10 @@ static Namval_t *array_find(Namval_t *np + { + char *cp; + if(!ap->header.table) ++ { + ap->header.table = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(ap->header.table,shp,1); ++ } + sfprintf(sh.strbuf,"%d",ap->cur); + cp = sfstruse(sh.strbuf); + mp = nv_search(cp, ap->header.table, NV_ADD); +@@ -402,6 +408,7 @@ static Namval_t *array_find(Namval_t *np + #if SHOPT_TYPEDEF + int nv_arraysettype(Namval_t *np, Namval_t *tp, const char *sub, int flags) + { ++ Shell_t *shp = sh_getinterp(); + Namval_t *nq; + char *av[2]; + int rdonly = nv_isattr(np,NV_RDONLY); +@@ -410,7 +417,10 @@ int nv_arraysettype(Namval_t *np, Namval + av[1] = 0; + sh.last_table = 0; + if(!ap->table) ++ { + ap->table = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(ap->table,shp,1); ++ } + if(nq = nv_search(sub, ap->table, NV_ADD)) + { + if(!nq->nvfun && nq->nvalue.cp && *nq->nvalue.cp==0) +@@ -485,6 +495,7 @@ static Namfun_t *array_clone(Namval_t *n + if(ap->table) + { + ap->table = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(ap->table,shp,1); + if(ap->scope && !(flags&NV_COMVAR)) + { + ap->scope = ap->table; +@@ -854,7 +865,9 @@ static struct index_array *array_grow(Na + np->nvalue.cp=0; + if(nv_hasdisc(np,&array_disc) || (nv_type(np) && nv_isvtree(np))) + { ++ Shell_t *shp = sh_getinterp(); + ap->header.table = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(ap->header.table,shp,1); + mp = nv_search("0", ap->header.table,NV_ADD); + if(mp && nv_isnull(mp)) + { +@@ -1169,6 +1182,7 @@ int nv_nextsub(Namval_t *np) + */ + Namval_t *nv_putsub(Namval_t *np,register char *sp,register long mode) + { ++ Shell_t *shp = sh_getinterp(); + register struct index_array *ap = (struct index_array*)nv_arrayptr(np); + register int size = (mode&ARRAY_MASK); + #if SHOPT_FIXEDARRAY +@@ -1180,7 +1194,6 @@ Namval_t *nv_putsub(Namval_t *np,registe + { + if(sp) + { +- Shell_t *shp = sh_getinterp(); + if(ap && ap->xp && !strmatch(sp,"+([0-9])")) + { + Namval_t *mp = nv_namptr(ap->xp,0); +@@ -1258,7 +1271,10 @@ Namval_t *nv_putsub(Namval_t *np,registe + char *cp; + Namval_t *mp; + if(!ap->header.table) ++ { + ap->header.table = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(ap->header.table,shp,1); ++ } + sfprintf(sh.strbuf,"%d",ap->cur); + cp = sfstruse(sh.strbuf); + mp = nv_search(cp, ap->header.table, NV_ADD); +@@ -1666,6 +1682,7 @@ int nv_aimax(register Namval_t* np) + */ + void *nv_associative(register Namval_t *np,const char *sp,int mode) + { ++ Shell_t *shp = sh_getinterp(); + register struct assoc_array *ap = (struct assoc_array*)nv_arrayptr(np); + register int type; + switch(mode) +@@ -1674,6 +1691,7 @@ void *nv_associative(register Namval_t * + if(ap = (struct assoc_array*)calloc(1,sizeof(struct assoc_array))) + { + ap->header.table = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(ap->header.table,shp,1); + ap->cur = 0; + ap->pos = 0; + ap->header.hdr.disc = &array_disc; +@@ -1742,7 +1760,6 @@ void *nv_associative(register Namval_t * + case NV_ANAME: + if(ap->cur) + { +- Shell_t *shp = sh_getinterp(); + if(!shp->instance && nv_isnull(ap->cur)) + return(NIL(void*)); + return((void*)ap->cur->nvname); +--- src/cmd/ksh93/sh/init.c ++++ src/cmd/ksh93/sh/init.c 2013-10-25 13:20:42.800733693 +0000 +@@ -1909,9 +1909,13 @@ static Init_t *nv_init(Shell_t *shp) + (OPTINDNOD)->nvalue.lp = (&shp->st.optindex); + /* set up the seconds clock */ + shp->alias_tree = inittree(shp,shtab_aliases); ++ dtuserdata(shp->alias_tree,shp,1); + shp->track_tree = dtopen(&_Nvdisc,Dtset); ++ dtuserdata(shp->track_tree,shp,1); + shp->bltin_tree = inittree(shp,(const struct shtable2*)shtab_builtins); ++ dtuserdata(shp->bltin_tree,shp,1); + shp->fun_tree = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(shp->fun_tree,shp,1); + dtview(shp->fun_tree,shp->bltin_tree); + nv_mount(DOTSHNOD, "type", shp->typedict=dtopen(&_Nvdisc,Dtoset)); + nv_adddisc(DOTSHNOD, shdiscnames, (Namval_t**)0); +@@ -1954,6 +1958,7 @@ static Dt_t *inittree(Shell_t *shp,const + nbltins = n; + } + base_treep = treep = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(treep,shp,1); + treep->user = (void*)shp; + for(tp=name_vals;*tp->sh_name;tp++,np++) + { +--- src/cmd/ksh93/sh/macro.c ++++ src/cmd/ksh93/sh/macro.c 2013-10-25 13:20:42.801733601 +0000 +@@ -2742,7 +2742,10 @@ static char *sh_tilde(Shell_t *shp,regis + skip: + #endif /* _WINIX */ + if(!logins_tree) ++ { + logins_tree = dtopen(&_Nvdisc,Dtbag); ++ dtuserdata(logins_tree,shp,1); ++ } + if(np=nv_search(string,logins_tree,NV_ADD)) + { + c = shp->subshell; +--- src/cmd/ksh93/sh/name.c ++++ src/cmd/ksh93/sh/name.c 2013-10-25 13:20:42.802733508 +0000 +@@ -821,6 +821,7 @@ Namval_t *nv_create(const char *name, D + { + Dt_t *dp = dtview(shp->var_tree,(Dt_t*)0); + rp->sdict = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(rp->sdict,shp,1); + dtview(rp->sdict,dp); + dtview(shp->var_tree,rp->sdict); + } +@@ -1170,7 +1171,10 @@ Namval_t *nv_create(const char *name, D + ap = nv_arrayptr(np); + } + if(n && ap && !ap->table) ++ { + ap->table = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(ap->table,shp,1); ++ } + if(ap && ap->table && (nq=nv_search(sub,ap->table,n))) + nq->nvenv = (char*)np; + if(nq && nv_isnull(nq)) +@@ -1391,7 +1395,7 @@ Namval_t *nv_open(const char *name, Dt_t + while((c= *(unsigned char*)cp++) && (c!='=') && (c!='/') && + (c>=0x200 || !(c=sh_lexstates[ST_NORM][c]) || c==S_EPAT || c==S_COLON)); + if(shp->subshell && c=='=') +- root = sh_subaliastree(1); ++ root = sh_subaliastree(shp,1); + if(c= *--cp) + *cp = 0; + np = nv_search(name, root, (flags&NV_NOADD)?0:NV_ADD); +@@ -2350,6 +2354,7 @@ void sh_scope(Shell_t *shp, struct argno + newroot = nv_dict(shp->namespace); + #endif /* SHOPT_NAMESPACE */ + newscope = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(newscope,shp,1); + if(envlist) + { + dtview(newscope,(Dt_t*)shp->var_tree); +@@ -3334,7 +3339,10 @@ int nv_rename(register Namval_t *np, int + if(ap=nv_arrayptr(np)) + { + if(!ap->table) ++ { + ap->table = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(ap->table,shp,1); ++ } + if(ap->table) + mp = nv_search(nv_getsub(np),ap->table,NV_ADD); + nv_arraychild(np,mp,0); +--- src/cmd/ksh93/sh/nvdisc.c ++++ src/cmd/ksh93/sh/nvdisc.c 2013-10-25 13:20:42.802733508 +0000 +@@ -246,6 +246,7 @@ static void chktfree(register Namval_t * + */ + static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle) + { ++ Shell_t *shp = sh_getinterp(); + int type = (flags&NV_APPEND)?APPEND:ASSIGN; + register struct vardisc *vp = (struct vardisc*)handle; + register Namval_t *nq = vp->disc[type]; +@@ -330,7 +331,7 @@ static void assign(Namval_t *np,const ch + } + else if(!nq || !isblocked(bp,type)) + { +- Dt_t *root = sh_subfuntree(1); ++ Dt_t *root = sh_subfuntree(shp,1); + int n; + Namarr_t *ap; + block(bp,type); +@@ -1296,6 +1297,7 @@ static Namfun_t *clone_table(Namval_t* n + Dt_t *oroot=tp->dict,*nroot=dtopen(&_Nvdisc,Dtoset); + if(!nroot) + return(0); ++ dtuserdata(nroot,dtuserdata(oroot,0,0),1); + memcpy((void*)ntp,(void*)fp,sizeof(struct table)); + ntp->dict = nroot; + ntp->parent = nv_lastdict(); +@@ -1493,6 +1495,6 @@ Namval_t *sh_fsearch(Shell_t *shp, const + sfputr(stkp,nv_name(shp->namespace),'.'); + sfputr(stkp,fname,0); + fname = stkptr(stkp,offset); +- return(nv_search(fname,sh_subfuntree(add&NV_ADD),add)); ++ return(nv_search(fname,sh_subfuntree(shp,add&NV_ADD),add)); + } + #endif /* SHOPT_NAMESPACE */ +--- src/cmd/ksh93/sh/path.c ++++ src/cmd/ksh93/sh/path.c 2013-10-25 13:20:42.803733416 +0000 +@@ -592,7 +592,7 @@ static void funload(Shell_t *shp,int fno + pname = path_fullname(shp,stakptr(PATH_OFFSET)); + if(shp->fpathdict && (rp = dtmatch(shp->fpathdict,(void*)pname))) + { +- Dt_t *funtree = sh_subfuntree(1); ++ Dt_t *funtree = sh_subfuntree(shp,1); + while(1) + { + rpfirst = dtprev(shp->fpathdict,rp); +@@ -868,13 +868,13 @@ Pathcomp_t *path_absolute(Shell_t *shp,r + if(isfun && f>=0 && (cp = strrchr(name,'.'))) + { + *cp = 0; +- if(nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE)) ++ if(nv_open(name,sh_subfuntree(shp,1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE)) + f = -1; + *cp = '.'; + } + if(isfun && f>=0) + { +- nv_onattr(nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE),NV_LTOU|NV_FUNCTION); ++ nv_onattr(nv_open(name,sh_subfuntree(shp,1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE),NV_LTOU|NV_FUNCTION); + funload(shp,f,name); + close(f); + f = -1; +--- src/cmd/ksh93/sh/subshell.c ++++ src/cmd/ksh93/sh/subshell.c 2013-10-25 13:20:42.803733416 +0000 +@@ -379,7 +379,7 @@ static void nv_restore(struct subshell * + * return pointer to alias tree + * create new one if in a subshell and one doesn't exist and create is non-zero + */ +-Dt_t *sh_subaliastree(int create) ++Dt_t *sh_subaliastree(Shell_t *shp,int create) + { + register struct subshell *sp = subshell_data; + if(!sp || sp->shp->curenv==0) +@@ -387,6 +387,7 @@ Dt_t *sh_subaliastree(int create) + if(!sp->salias && create) + { + sp->salias = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(sp->salias,shp,1); + dtview(sp->salias,sp->shp->alias_tree); + sp->shp->alias_tree = sp->salias; + } +@@ -397,7 +398,7 @@ Dt_t *sh_subaliastree(int create) + * return pointer to function tree + * create new one if in a subshell and one doesn't exist and create is non-zero + */ +-Dt_t *sh_subfuntree(int create) ++Dt_t *sh_subfuntree(Shell_t *shp,int create) + { + register struct subshell *sp = subshell_data; + if(!sp || sp->shp->curenv==0) +@@ -405,6 +406,7 @@ Dt_t *sh_subfuntree(int create) + if(!sp->sfun && create) + { + sp->sfun = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(sp->sfun,shp,1); + dtview(sp->sfun,sp->shp->fun_tree); + sp->shp->fun_tree = sp->sfun; + } +--- src/cmd/ksh93/sh/xec.c ++++ src/cmd/ksh93/sh/xec.c 2013-10-25 13:20:42.804733324 +0000 +@@ -2688,6 +2688,7 @@ int sh_exec(register const Shnode_t *t, + else + { + root = dtopen(&_Nvdisc,Dtoset); ++ dtuserdata(root,shp,1); + nv_mount(np, (char*)0, root); + np->nvalue.cp = Empty; + dtview(root,shp->var_base); +@@ -2729,7 +2730,7 @@ int sh_exec(register const Shnode_t *t, + np = sh_fsearch(shp,fname,NV_ADD|HASH_NOSCOPE); + if(!np) + #endif /* SHOPT_NAMESPACE */ +- np = nv_open(fname,sh_subfuntree(1),NV_NOASSIGN|NV_NOARRAY|NV_VARNAME|NV_NOSCOPE); ++ np = nv_open(fname,sh_subfuntree(shp,1),NV_NOASSIGN|NV_NOARRAY|NV_VARNAME|NV_NOSCOPE); + if(npv) + { + if(!shp->mktype) +@@ -2743,11 +2744,6 @@ int sh_exec(register const Shnode_t *t, + slp = (struct slnod*)np->nvenv; + sh_funstaks(slp->slchild,-1); + stakdelete(slp->slptr); +- if(shp->funload) +- { +- free((void*)np->nvalue.rp); +- np->nvalue.rp = 0; +- } + if(rp->sdict) + { + Namval_t *mp, *nq; +@@ -2761,6 +2757,12 @@ int sh_exec(register const Shnode_t *t, + dtclose(rp->sdict); + rp->sdict = 0; + } ++ if(shp->funload) ++ { ++ if(!shp->fpathdict) ++ free((void*)np->nvalue.rp); ++ np->nvalue.rp = 0; ++ } + } + if(!np->nvalue.rp) + { +@@ -2799,7 +2801,10 @@ int sh_exec(register const Shnode_t *t, + if(!shp->fpathdict) + shp->fpathdict = dtopen(&_Rpdisc,Dtobag); + if(shp->fpathdict) ++ { ++ dtuserdata(shp->fpathdict,shp,1); + dtinsert(shp->fpathdict,rp); ++ } + } + } + else +--- src/lib/libast/Mamfile ++++ src/lib/libast/Mamfile 2013-10-25 13:20:42.806733139 +0000 +@@ -3969,6 +3969,14 @@ meta dtopen.o %.c>%.o cdt/dtopen.c dtope + prev cdt/dtopen.c + exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtopen.c + done dtopen.o generated ++make dtstat.o ++make cdt/dtstat.c ++prev cdt/dthdr.h implicit ++done cdt/dtstat.c ++meta dtstat.o %.c>%.o cdt/dtstat.c dtstat ++prev cdt/dtstat.c ++exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtstat.c ++done dtstat.o generated + make dtstrhash.o + make cdt/dtstrhash.c + prev cdt/dthdr.h implicit +@@ -3985,6 +3993,14 @@ meta dttree.o %.c>%.o cdt/dttree.c dttre + prev cdt/dttree.c + exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dttree.c + done dttree.o generated ++make dtuser.o ++make cdt/dtuser.c ++prev cdt/dthdr.h implicit ++done cdt/dtuser.c ++meta dtuser.o %.c>%.o cdt/dtuser.c dtuser ++prev cdt/dtuser.c ++exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtuser.c ++done dtuser.o generated + make dtview.o + make cdt/dtview.c + prev cdt/dthdr.h implicit +@@ -6101,7 +6117,7 @@ exec - ${AR} rc libast.a state.o transit + exec - ${AR} rc libast.a streval.o strexpr.o strmatch.o strcopy.o modei.o modex.o strmode.o strlcat.o strlcpy.o strlook.o strncopy.o strsearch.o strpsearch.o stresc.o stropt.o strtape.o strpcmp.o strnpcmp.o strvcmp.o strnvcmp.o tok.o tokline.o tokscan.o pathaccess.o pathcat.o pathcanon.o pathcheck.o pathpath.o pathexists.o pathfind.o pathkey.o pathprobe.o pathrepl.o pathnative.o pathposix.o pathtemp.o pathtmp.o pathstat.o pathgetlink.o pathsetlink.o pathbin.o pathshell.o pathcd.o pathprog.o fs3d.o ftwalk.o ftwflags.o fts.o astintercept.o conformance.o getenv.o setenviron.o optget.o optjoin.o optesc.o optctx.o strsort.o struniq.o magic.o mime.o mimetype.o signal.o sigflag.o systrace.o error.o errorf.o errormsg.o errorx.o localeconv.o setlocale.o translate.o catopen.o iconv.o lc.o lctab.o mc.o base64.o recfmt.o recstr.o reclen.o fmtrec.o fmtbase.o fmtbuf.o fmtclock.o fmtdev.o fmtelapsed.o fmterror.o fmtesc.o fmtfmt.o fmtfs.o fmtident.o fmtint.o fmtip4.o fmtip6.o fmtls.o fmtmatch.o fmtmode.o fmtnum.o fmtperm.o fmtre.o fmttime.o + exec - ${AR} rc libast.a fmtuid.o fmtgid.o fmtsignal.o fmtscale.o fmttmx.o fmttv.o fmtversion.o strelapsed.o strperm.o struid.o strgid.o strtoip4.o strtoip6.o stack.o stk.o swapget.o swapmem.o swapop.o swapput.o sigdata.o sigcrit.o sigunblock.o procopen.o procclose.o procrun.o procfree.o tmdate.o tmequiv.o tmfix.o tmfmt.o tmform.o tmgoff.o tminit.o tmleap.o tmlex.o tmlocale.o tmmake.o tmpoff.o tmscan.o tmsleep.o tmtime.o tmtype.o tmweek.o tmword.o tmzone.o tmxdate.o tmxduration.o tmxfmt.o tmxgettime.o tmxleap.o tmxmake.o tmxscan.o tmxsettime.o tmxsleep.o tmxtime.o tmxtouch.o tvcmp.o tvgettime.o tvsettime.o tvsleep.o tvtouch.o cmdarg.o vecargs.o vecfile.o vecfree.o vecload.o vecstring.o univdata.o touch.o mnt.o debug.o memccpy.o memchr.o memcmp.o memcpy.o memdup.o memmove.o memset.o mkdir.o mkfifo.o mknod.o rmdir.o remove.o rename.o link.o unlink.o strdup.o strchr.o strrchr.o strstr.o strtod.o strtold.o strtol.o strtoll.o strtoul.o strtoull.o strton.o strtonll.o strntod.o strntold.o strnton.o + exec - ${AR} rc libast.a strntonll.o strntol.o strntoll.o strntoul.o strntoull.o strcasecmp.o strncasecmp.o strerror.o mktemp.o tmpnam.o fsync.o execlp.o execve.o execvp.o execvpe.o spawnveg.o vfork.o killpg.o hsearch.o tsearch.o getlogin.o putenv.o setenv.o unsetenv.o lstat.o statvfs.o eaccess.o gross.o omitted.o readlink.o symlink.o getpgrp.o setpgid.o setsid.o waitpid.o creat64.o fcntl.o open.o atexit.o getdents.o getwd.o dup2.o errno.o getpreroot.o ispreroot.o realopen.o setpreroot.o getgroups.o mount.o system.o iblocks.o modedata.o tmdata.o memfatal.o sfkeyprintf.o sfdcdio.o sfdcdos.o sfdcfilter.o sfdcseekable.o sfdcslow.o sfdcsubstr.o sfdctee.o sfdcunion.o sfdcmore.o sfdcprefix.o wc.o wc2utf8.o basename.o closelog.o dirname.o fmtmsglib.o fnmatch.o ftw.o getdate.o getsubopt.o glob.o nftw.o openlog.o re_comp.o resolvepath.o realpath.o regcmp.o regexp.o setlogmask.o strftime.o strptime.o swab.o syslog.o tempnam.o wordexp.o mktime.o regalloc.o regclass.o regcoll.o regcomp.o regcache.o regdecomp.o regerror.o regexec.o regfatal.o reginit.o +-exec - ${AR} rc libast.a regnexec.o regsubcomp.o regsubexec.o regsub.o regrecord.o regrexec.o regstat.o dtclose.o dtdisc.o dthash.o dtlist.o dtmethod.o dtopen.o dtstrhash.o dttree.o dtview.o dtwalk.o dtnew.o dtcomp.o sfclose.o sfclrlock.o sfdisc.o sfdlen.o sfexcept.o sfgetl.o sfgetu.o sfcvt.o sfecvt.o sffcvt.o sfextern.o sffilbuf.o sfflsbuf.o sfprints.o sfgetd.o sfgetr.o sfllen.o sfmode.o sfmove.o sfnew.o sfpkrd.o sfnotify.o sfnputc.o sfopen.o sfpeek.o sfpoll.o sfpool.o sfpopen.o sfprintf.o sfputd.o sfputl.o sfputr.o sfputu.o sfrd.o sfread.o sfreserve.o sfscanf.o sfseek.o sfset.o sfsetbuf.o sfsetfd.o sfsize.o sfsk.o sfstack.o sfstrtod.o sfsync.o sfswap.o sftable.o sftell.o sftmp.o sfungetc.o sfvprintf.o sfvscanf.o sfwr.o sfwrite.o sfpurge.o sfraise.o sfwalk.o sfgetm.o sfmutex.o sfputm.o sfresize.o _sfclrerr.o _sfeof.o _sferror.o _sffileno.o _sfopen.o _sfstacked.o _sfvalue.o _sfgetc.o _sfgetl.o _sfgetl2.o _sfgetu.o _sfgetu2.o _sfdlen.o _sfllen.o _sfslen.o _sfulen.o _sfputc.o _sfputd.o _sfputl.o _sfputm.o ++exec - ${AR} rc libast.a regnexec.o regsubcomp.o regsubexec.o regsub.o regrecord.o regrexec.o regstat.o dtclose.o dtdisc.o dthash.o dtlist.o dtmethod.o dtopen.o dtstat.o dtstrhash.o dttree.o dtuser.o dtview.o dtwalk.o dtnew.o dtcomp.o sfclose.o sfclrlock.o sfdisc.o sfdlen.o sfexcept.o sfgetl.o sfgetu.o sfcvt.o sfecvt.o sffcvt.o sfextern.o sffilbuf.o sfflsbuf.o sfprints.o sfgetd.o sfgetr.o sfllen.o sfmode.o sfmove.o sfnew.o sfpkrd.o sfnotify.o sfnputc.o sfopen.o sfpeek.o sfpoll.o sfpool.o sfpopen.o sfprintf.o sfputd.o sfputl.o sfputr.o sfputu.o sfrd.o sfread.o sfreserve.o sfscanf.o sfseek.o sfset.o sfsetbuf.o sfsetfd.o sfsize.o sfsk.o sfstack.o sfstrtod.o sfsync.o sfswap.o sftable.o sftell.o sftmp.o sfungetc.o sfvprintf.o sfvscanf.o sfwr.o sfwrite.o sfpurge.o sfraise.o sfwalk.o sfgetm.o sfmutex.o sfputm.o sfresize.o _sfclrerr.o _sfeof.o _sferror.o _sffileno.o _sfopen.o _sfstacked.o _sfvalue.o _sfgetc.o _sfgetl.o _sfgetl2.o _sfgetu.o _sfgetu2.o _sfdlen.o _sfllen.o _sfslen.o _sfulen.o _sfputc.o _sfputd.o _sfputl.o _sfputm.o + exec - ${AR} rc libast.a _sfputu.o clearerr.o fclose.o fdopen.o feof.o ferror.o fflush.o fgetc.o fgetpos.o fgets.o fileno.o fopen.o fprintf.o fpurge.o fputc.o fputs.o fread.o freopen.o fscanf.o fseek.o fseeko.o fsetpos.o ftell.o ftello.o fwrite.o flockfile.o ftrylockfile.o funlockfile.o getc.o getchar.o getw.o pclose.o popen.o printf.o putc.o putchar.o puts.o putw.o rewind.o scanf.o setbuf.o setbuffer.o setlinebuf.o setvbuf.o snprintf.o sprintf.o sscanf.o asprintf.o vasprintf.o tmpfile.o ungetc.o vfprintf.o vfscanf.o vprintf.o vscanf.o vsnprintf.o vsprintf.o vsscanf.o _doprnt.o _doscan.o _filbuf.o _flsbuf.o _stdfun.o _stdopen.o _stdprintf.o _stdscanf.o _stdsprnt.o _stdvbuf.o _stdvsnprnt.o _stdvsprnt.o _stdvsscn.o fgetwc.o fwprintf.o putwchar.o vfwscanf.o wprintf.o fgetws.o fwscanf.o swprintf.o vswprintf.o wscanf.o fputwc.o getwc.o swscanf.o vswscanf.o fputws.o getwchar.o ungetwc.o vwprintf.o fwide.o putwc.o vfwprintf.o vwscanf.o stdio_c99.o fcloseall.o fmemopen.o getdelim.o getline.o frexp.o frexpl.o astcopy.o + exec - ${AR} rc libast.a astconf.o astdynamic.o astlicense.o astquery.o astwinsize.o conftab.o aststatic.o getopt.o getoptl.o aso.o asolock.o asometh.o asorelax.o aso-sem.o aso-fcntl.o vmbest.o vmclear.o vmclose.o vmdcheap.o vmdebug.o vmdisc.o vmexit.o vmlast.o vmopen.o vmpool.o vmprivate.o vmprofile.o vmregion.o vmsegment.o vmset.o vmstat.o vmstrdup.o vmtrace.o vmwalk.o vmmopen.o malloc.o vmgetmem.o a64l.o acosh.o asinh.o atanh.o cbrt.o crypt.o erf.o err.o exp.o exp__E.o expm1.o gamma.o getpass.o lgamma.o log.o log1p.o log__L.o rand48.o random.o rcmd.o rint.o support.o sfstrtmp.o spawn.o + exec - (ranlib libast.a) >/dev/null 2>&1 || true +--- src/lib/libast/cdt/cdtlib.h ++++ src/lib/libast/cdt/cdtlib.h 2013-10-25 13:20:42.807733047 +0000 +@@ -58,9 +58,9 @@ + /* This struct holds private method data created on DT_OPEN */ + struct _dtdata_s + { unsigned int lock; /* general dictionary lock */ +- Dtuser_t user; /* application's data */ + unsigned int type; /* method type, control flags */ + ssize_t size; /* number of objects */ ++ Dtuser_t user; /* application's data */ + Dt_t dict; /* when DT_INDATA is requested */ + }; + +@@ -123,7 +123,7 @@ typedef struct _dtlib_s + #endif /* _BLD_cdt */ + + /* these macros lock/unlock dictionaries. DTRETURN substitutes for "return" */ +-#define DTSETLOCK(dt) (((dt)->data->type&DT_SHARE) ? asolock(&(dt)->data->lock,1,ASO_SPINLOCK) : 0 ) ++#define DTSETLOCK(dt) (((dt)->data->type&DT_SHARE) ? asolock(&(dt)->data->lock,1,ASO_LOCK) : 0 ) + #define DTCLRLOCK(dt) (((dt)->data->type&DT_SHARE) ? asolock(&(dt)->data->lock,1,ASO_UNLOCK) : 0 ) + #define DTRETURN(ob,rv) do { (ob) = (rv); goto dt_return; } while(0) + #define DTERROR(dt, mesg) (!((dt)->disc && (dt)->disc->eventf) ? 0 : \ +--- src/lib/libast/cdt/dtcomp.c ++++ src/lib/libast/cdt/dtcomp.c 2013-10-25 13:20:42.807733047 +0000 +@@ -52,9 +52,3 @@ extern ssize_t dtsize(Dt_t* d) + { + return (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT); + } +- +-#undef dtstat +-extern ssize_t dtstat(Dt_t* d) +-{ +- return (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT); +-} +--- src/lib/libast/cdt/dthash.c ++++ src/lib/libast/cdt/dthash.c 2013-10-25 13:20:42.807733047 +0000 +@@ -52,11 +52,13 @@ static int htable(Dt_t* dt) + if((n = hash->tblz) > 0 && (hash->type&H_FIXED) ) + return 0; /* fixed size table */ + +- if(n == 0 && disc && disc->eventf) /* let user have input */ ++ if(disc && disc->eventf) /* let user have input */ + { if((*disc->eventf)(dt, DT_HASHSIZE, &n, disc) > 0 ) + { if(n < 0) /* fix table size */ + { hash->type |= H_FIXED; +- n = -n; ++ n = -n; /* desired table size */ ++ if(hash->tblz >= n ) /* table size is fixed now */ ++ return 0; + } + } + } +@@ -234,12 +236,13 @@ static Void_t* hstat(Dt_t* dt, Dtstat_t* + + for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t) + { for(n = 0, l = *t; l; l = l->_rght) ++ { if(n < DT_MAXSIZE) ++ st->lsize[n] += 1; + n += 1; ++ } + st->mlev = n > st->mlev ? n : st->mlev; + if(n < DT_MAXSIZE) /* if chain length is small */ +- { st->msize = n > st->msize ? n : st->msize; +- st->lsize[n] += n; +- } ++ st->msize = n > st->msize ? n : st->msize; + } + } + +@@ -310,7 +313,7 @@ int type; + hsh = _DTHSH(dt,key,disc); + + tbl = hash->htbl + (hsh & (hash->tblz-1)); +- pp = ll = NIL(Dtlink_t*); ++ pp = ll = NIL(Dtlink_t*); /* pp is the before, ll is the here */ + for(p = NIL(Dtlink_t*), l = *tbl; l; p = l, l = l->_rght) + { if(hsh == l->_hash) + { o = _DTOBJ(disc,l); k = _DTKEY(disc,o); +@@ -342,20 +345,41 @@ int type; + _dtfree(dt, ll, type); + DTRETURN(obj, _DTOBJ(disc,ll)); + } ++ else if(type & DT_INSTALL ) ++ { if(dt->meth->type&DT_BAG) ++ goto do_insert; ++ else if(!(lnk = _dtmake(dt, obj, type)) ) ++ DTRETURN(obj, NIL(Void_t*) ); ++ else /* replace old object with new one */ ++ { if(pp) /* remove old object */ ++ pp->_rght = ll->_rght; ++ else *tbl = ll->_rght; ++ o = _DTOBJ(disc,ll); ++ _dtfree(dt, ll, DT_DELETE); ++ DTANNOUNCE(dt, o, DT_DELETE); ++ ++ goto do_insert; ++ } ++ } + else + { /**/DEBUG_ASSERT(type&(DT_INSERT|DT_ATTACH|DT_APPEND|DT_RELINK)); +- if(!(dt->meth->type&DT_BAG) ) ++ if((dt->meth->type&DT_BAG) ) ++ goto do_insert; ++ else + { if(type&(DT_INSERT|DT_APPEND|DT_ATTACH) ) +- type |= DT_SEARCH; /* for announcement */ ++ type |= DT_MATCH; /* for announcement */ + else if(lnk && (type&DT_RELINK) ) ++ { /* remove a duplicate */ ++ o = _DTOBJ(disc, lnk); + _dtfree(dt, lnk, DT_DELETE); ++ DTANNOUNCE(dt, o, DT_DELETE); ++ } + DTRETURN(obj, _DTOBJ(disc,ll)); + } +- else goto do_insert; + } + } + else /* no matching object */ +- { if(!(type&(DT_INSERT|DT_APPEND|DT_ATTACH|DT_RELINK)) ) ++ { if(!(type&(DT_INSERT|DT_INSTALL|DT_APPEND|DT_ATTACH|DT_RELINK)) ) + DTRETURN(obj, NIL(Void_t*)); + + do_insert: /* inserting a new object */ +--- src/lib/libast/cdt/dtlist.c ++++ src/lib/libast/cdt/dtlist.c 2013-10-25 13:20:42.807733047 +0000 +@@ -142,9 +142,9 @@ int type; + } + + #if __STD_C +-static Void_t* liststat(Dt_t* dt, Dtstat_t* st) ++static Void_t* listat(Dt_t* dt, Dtstat_t* st) + #else +-static Void_t* liststat(dt, st) ++static Void_t* listat(dt, st) + Dt_t* dt; + Dtstat_t* st; + #endif +@@ -186,7 +186,7 @@ int type; + else if(type&DT_CLEAR) + DTRETURN(obj, lclear(dt)); + else if(type&DT_STAT ) +- DTRETURN(obj, liststat(dt, (Dtstat_t*)obj)); ++ DTRETURN(obj, listat(dt, (Dtstat_t*)obj)); + + h = list->here; /* save finger to last search object */ + list->here = NIL(Dtlink_t*); +@@ -202,8 +202,9 @@ int type; + { r = (Dtlink_t*)obj; + goto do_insert; + } +- else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH)) +- { if(!(r = _dtmake(dt, obj, type)) ) ++ else if(type&(DT_INSERT|DT_INSTALL|DT_APPEND|DT_ATTACH)) ++ { dt_insert: ++ if(!(r = _dtmake(dt, obj, type)) ) + DTRETURN(obj, NIL(Void_t*)); + dt->data->size += 1; + +@@ -290,7 +291,7 @@ int type; + } + r = h ? h : r; + } +- if(!r) ++ if(!r) /* not found */ + DTRETURN(obj, NIL(Void_t*)); + + if(type&(DT_DELETE|DT_DETACH|DT_REMOVE)) +--- src/lib/libast/cdt/dtopen.c ++++ src/lib/libast/cdt/dtopen.c 2013-10-25 13:20:42.808732955 +0000 +@@ -153,25 +153,3 @@ void _dtfree(Dt_t* dt, Dtlink_t* l, int + if(disc->link < 0) /* free holder */ + (void)(*dt->memoryf)(dt, (Void_t*)l, 0, disc); + } +- +-int dtuserlock(Dt_t* dt, unsigned int key, int type) +-{ +- if(type > 0) +- return asolock(&dt->data->user.lock, key, ASO_LOCK); +- else if(type < 0) +- return asolock(&dt->data->user.lock, key, ASO_UNLOCK); +- else return asolock(&dt->data->user.lock, key, ASO_TRYLOCK); +-} +- +-Void_t* dtuserdata(Dt_t* dt, Void_t* data, unsigned int key) +-{ +- if(key == 0) +- return dt->data->user.data; +- else if(dtuserlock(dt, key, 1) < 0 ) +- return NIL(Void_t*); +- else +- { dt->data->user.data = data; +- dtuserlock(dt, key, -1); +- return data; +- } +-} +--- src/lib/libast/cdt/dtstat.c ++++ src/lib/libast/cdt/dtstat.c 2013-10-25 13:20:42.808732955 +0000 +@@ -0,0 +1,54 @@ ++/*********************************************************************** ++* * ++* This software is part of the ast package * ++* Copyright (c) 1985-2012 AT&T Intellectual Property * ++* and is licensed under the * ++* Eclipse Public License, Version 1.0 * ++* by AT&T Intellectual Property * ++* * ++* A copy of the License is available at * ++* http://www.eclipse.org/org/documents/epl-v10.html * ++* (with md5 checksum b35adb5213ca9657e911e9befb180842) * ++* * ++* Information and Software Systems Research * ++* AT&T Research * ++* Florham Park NJ * ++* * ++* Glenn Fowler * ++* David Korn * ++* Phong Vo * ++* * ++***********************************************************************/ ++#include "dthdr.h" ++ ++/* Get statistics for a dictionary ++** ++** Written by Kiem-Phong Vo ++*/ ++ ++ssize_t dtstat(Dt_t* dt, Dtstat_t* dtst) ++{ ++ ssize_t sz, k, maxk; ++ char *str; ++ char *end; ++ ++ sz = (ssize_t)(*dt->meth->searchf)(dt, (Void_t*)dtst, DT_STAT); ++ ++ str = dtst->mesg; ++ end = &dtst->mesg[sizeof(dtst->mesg)] - 1; ++ str += sfsprintf(str, end - str, "Objects=%d Levels=%d(Largest:", dtst->size, dtst->mlev+1); ++ ++ /* print top 3 levels */ ++ for(k = maxk = 0; k <= dtst->mlev; ++k) ++ if(dtst->lsize[k] > dtst->lsize[maxk]) ++ maxk = k; ++ if(maxk > 0) ++ maxk -= 1; ++ for(k = 0; k < 3 && maxk <= dtst->mlev; ++k, ++maxk) ++ str += sfsprintf(str, end - str, " lev[%d]=%d", maxk, dtst->lsize[maxk] ); ++ if (str < end) ++ *str++ = ')'; ++ *str = 0; ++ ++ return sz; ++} +--- src/lib/libast/cdt/dtstrhash.c ++++ src/lib/libast/cdt/dtstrhash.c 2013-10-25 13:20:42.808732955 +0000 +@@ -22,40 +22,38 @@ + #include "dthdr.h" + + /* Hashing a string into an unsigned integer. +-** The basic method is to continuingly accumulate bytes and multiply +-** with some given prime. The length n of the string is added last. +-** The recurrent equation is like this: +-** h[k] = (h[k-1] + bytes)*prime for 0 <= k < n +-** h[n] = (h[n-1] + n)*prime +-** The prime is chosen to have a good distribution of 1-bits so that +-** the multiplication will distribute the bits in the accumulator well. +-** The below code accumulates 2 bytes at a time for speed. +-** +-** Written by Kiem-Phong Vo (02/28/03) ++** This is the FNV (Fowler-Noll-Vo) hash function. ++** Written by Kiem-Phong Vo (01/10/2012) + */ + + #if __STD_C + uint dtstrhash(uint h, Void_t* args, ssize_t n) + #else + uint dtstrhash(h,args,n) +-reg uint h; ++uint h; + Void_t* args; + ssize_t n; + #endif + { + unsigned char *s = (unsigned char*)args; + +- if(n <= 0) +- { for(; *s != 0; s += s[1] ? 2 : 1) +- h = (h + (s[0]<<8) + s[1])*DT_PRIME; +- n = s - (unsigned char*)args; ++#if _ast_sizeof_int == 8 /* 64-bit hash */ ++#define FNV_PRIME ((1<<40) + (1<<8) + 0xb3) ++#define FNV_OFFSET 14695981039346656037 ++#else /* 32-bit hash */ ++#define FNV_PRIME ((1<<24) + (1<<8) + 0x93) ++#define FNV_OFFSET 2166136261 ++#endif ++ h = (h == 0 || h == ~0) ? FNV_OFFSET : h; ++ if(n <= 0) /* see discipline key definition for == 0 */ ++ { for(; *s != 0; ++s ) ++ h = (h ^ s[0]) * FNV_PRIME; + } + else + { unsigned char* ends; +- for(ends = s+n-1; s < ends; s += 2) +- h = (h + (s[0]<<8) + s[1])*DT_PRIME; +- if(s <= ends) +- h = (h + (s[0]<<8))*DT_PRIME; ++ for(ends = s+n; s < ends; ++s) ++ h = (h ^ s[0]) * FNV_PRIME; + } +- return (h+n)*DT_PRIME; ++ ++ return h; + } +--- src/lib/libast/cdt/dttree.c ++++ src/lib/libast/cdt/dttree.c 2013-10-25 13:20:42.808732955 +0000 +@@ -545,7 +545,14 @@ int type; + } + else goto no_root; + } +- else if(type&DT_REMOVE) /* remove a particular element in the tree */ ++ else if(type&(DT_DELETE|DT_DETACH)) ++ { dt_delete: /* remove an object from the dictionary */ ++ obj = _DTOBJ(disc,root); ++ _dtfree(dt, root, type); ++ dt->data->size -= 1; ++ goto no_root; ++ } ++ else if(type&DT_REMOVE) /* remove a particular object */ + { if(_DTOBJ(disc,root) == obj) + goto dt_delete; + else +@@ -555,28 +562,32 @@ int type; + DTRETURN(obj, NIL(Void_t*)); + } + } +- else if(type&(DT_DELETE|DT_DETACH)) +- { dt_delete: /* remove an object from the dictionary */ +- obj = _DTOBJ(disc,root); +- _dtfree(dt, root, type); +- dt->data->size -= 1; +- goto no_root; +- } + else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH)) + { if(dt->meth->type&DT_OSET) +- { type |= DT_SEARCH; /* for announcement */ ++ { type |= DT_MATCH; /* for announcement */ + goto has_root; + } +- else ++ else /* if(dt->meth->type&DT_OBAG) */ + { root->_left = NIL(Dtlink_t*); + root->_rght = link._left; + link._left = root; + goto dt_insert; + } + } ++ else if(type&DT_INSTALL) ++ { /* remove old object before insert new one */ ++ o = _DTOBJ(disc, root); ++ _dtfree(dt, root, DT_DELETE); ++ DTANNOUNCE(dt, o, DT_DELETE); ++ goto dt_insert; ++ } + else if(type&DT_RELINK) /* a duplicate */ + { if(dt->meth->type&DT_OSET) ++ { /* remove object */ ++ o = _DTOBJ(disc, me); + _dtfree(dt, me, DT_DELETE); ++ DTANNOUNCE(dt, o, DT_DELETE); ++ } + else + { me->_left = NIL(Dtlink_t*); + me->_rght = link._left; +@@ -612,7 +623,7 @@ int type; + { obj = NIL(Void_t*); + goto no_root; + } +- else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH)) ++ else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH|DT_INSTALL)) + { dt_insert: + if(!(root = _dtmake(dt, obj, type)) ) + { obj = NIL(Void_t*); +--- src/lib/libast/cdt/dtuser.c ++++ src/lib/libast/cdt/dtuser.c 2013-10-25 13:20:42.808732955 +0000 +@@ -0,0 +1,59 @@ ++/*********************************************************************** ++* * ++* This software is part of the ast package * ++* Copyright (c) 1985-2012 AT&T Intellectual Property * ++* and is licensed under the * ++* Eclipse Public License, Version 1.0 * ++* by AT&T Intellectual Property * ++* * ++* A copy of the License is available at * ++* http://www.eclipse.org/org/documents/epl-v10.html * ++* (with md5 checksum b35adb5213ca9657e911e9befb180842) * ++* * ++* Information and Software Systems Research * ++* AT&T Research * ++* Florham Park NJ * ++* * ++* Glenn Fowler * ++* David Korn * ++* Phong Vo * ++* * ++***********************************************************************/ ++#include "dthdr.h" ++ ++/* Perform various functions on the user's behalf. ++** ++** Written by Kiem-Phong Vo (01/05/2012) ++*/ ++ ++/* managing the lock dt->data->user.lock */ ++int dtuserlock(Dt_t* dt, unsigned int key, int type) ++{ ++ if(key == 0) ++ return -1; ++ else if(type > 0) ++ return asolock(&dt->data->user.lock, key, ASO_LOCK); ++ else if(type < 0) ++ return asolock(&dt->data->user.lock, key, ASO_UNLOCK); ++ else return asolock(&dt->data->user.lock, key, ASO_TRYLOCK); ++} ++ ++/* managing the user data slot dt->data->user.data */ ++Void_t* dtuserdata(Dt_t* dt, Void_t* data, int set) ++{ ++ if(set == 0) /* just return current value */ ++ return asogetptr(&dt->data->user.data); ++ else while(1) ++ { Void_t *current = dt->data->user.data; ++ if(asocasptr(&dt->data->user.data, current, data) == current) ++ return current; ++ } ++} ++ ++/* announcing an event on the user's behalf */ ++int dtuserevent(Dt_t* dt, int flags, Void_t* data) ++{ ++ if(!dt->disc->eventf) ++ return 0; ++ else return (*dt->disc->eventf)(dt, DT_ANNOUNCE|DT_USER|flags, data, dt->disc); ++} +--- src/lib/libast/include/cdt.h ++++ src/lib/libast/include/cdt.h 2013-10-25 13:20:42.809732863 +0000 +@@ -164,6 +164,7 @@ struct _dtstat_s + ssize_t msize; /* max #defined elts in below arrays */ + ssize_t lsize[DT_MAXSIZE]; /* #objects by level */ + ssize_t tsize[DT_MAXSIZE]; /* #tables by level */ ++ char mesg[256]; /* digest of top level statistics */ + }; + + /* supported storage methods */ +@@ -199,7 +200,8 @@ struct _dtstat_s + #define DT_ATLEAST 0000040000 /* find the least elt >= object */ + #define DT_ATMOST 0000100000 /* find the biggest elt <= object */ + #define DT_REMOVE 0002000000 /* remove a specific object */ +-#define DT_TOANNOUNCE (DT_INSERT|DT_DELETE|DT_SEARCH|DT_NEXT|DT_PREV|DT_FIRST|DT_LAST|DT_MATCH|DT_ATTACH|DT_DETACH|DT_APPEND|DT_ATLEAST|DT_ATMOST|DT_REMOVE) ++#define DT_INSTALL 0004000000 /* install a new object */ ++#define DT_TOANNOUNCE (DT_INSERT|DT_DELETE|DT_SEARCH|DT_NEXT|DT_PREV|DT_FIRST|DT_LAST|DT_MATCH|DT_ATTACH|DT_DETACH|DT_APPEND|DT_ATLEAST|DT_ATMOST|DT_REMOVE|DT_INSTALL) + + #define DT_RELINK 0000002000 /* re-inserting (dtdisc,dtmethod...) */ + #define DT_FLATTEN 0000000040 /* flatten objects into a list */ +@@ -216,6 +218,7 @@ struct _dtstat_s + /* the actual event will be this bit */ + /* combined with the operation bit */ + #define DT_OPTIMIZE 0100000000 /* optimizing data structure */ ++#define DT_USER 0200000000 /* an announcement on user's behalf */ + + /* events for discipline and method event-handling functions */ + #define DT_OPEN 1 /* a dictionary is being opened */ +@@ -277,7 +280,8 @@ extern int dtwalk _ARG_((Dt_t*, int(*)( + extern int dtcustomize _ARG_((Dt_t*, int, int)); + extern unsigned int dtstrhash _ARG_((unsigned int, Void_t*, ssize_t)); + extern int dtuserlock _ARG_((Dt_t*, unsigned int, int)); +-extern Void_t* dtuserdata _ARG_((Dt_t*, Void_t*, unsigned int)); ++extern Void_t* dtuserdata _ARG_((Dt_t*, Void_t*, int)); ++extern int dtuserevent _ARG_((Dt_t*, int, Void_t*)); + + /* deal with upward binary compatibility (operation bit translation, etc.) */ + extern Dt_t* _dtopen _ARG_((Dtdisc_t*, Dtmethod_t*, unsigned long)); +@@ -334,6 +338,7 @@ _END_EXTERNS_ + #define dtsearch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH) + #define dtmatch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_MATCH) + #define dtinsert(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_INSERT) ++#define dtinstall(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_INSTALL) + #define dtappend(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_APPEND) + #define dtdelete(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DELETE) + #define dtremove(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_REMOVE) +@@ -345,7 +350,6 @@ _END_EXTERNS_ + #define dtextract(d) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_EXTRACT) + #define dtrestore(d,l) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(l),DT_RESTORE) + +-#define dtstat(d,s) (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(s),DT_STAT) + #define dtsize(d) (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT) + + #define DT_PRIME 17109811 /* 2#00000001 00000101 00010011 00110011 */ diff --git a/ksh93-edpredict.dif b/ksh93-edpredict.dif new file mode 100644 index 0000000..36b9434 --- /dev/null +++ b/ksh93-edpredict.dif @@ -0,0 +1,40 @@ +--- src/cmd/ksh93/edit/edit.c.orig 2016-02-18 10:33:20.604776826 +0000 ++++ src/cmd/ksh93/edit/edit.c 2016-02-18 10:34:02.019627077 +0000 +@@ -628,8 +628,8 @@ void ed_setup(register Edit_t *ep, int f + ep->hoff = 0; + #endif /* SHOPT_EDPREDICT */ + #if KSHELL +- ep->e_stkptr = stakptr(0); + ep->e_stkoff = staktell(); ++ ep->e_stkptr = stakfreeze(0); + if(!(last = shp->prompt)) + last = ""; + shp->prompt = 0; +--- src/cmd/ksh93/edit/emacs.c.orig 2016-02-18 10:33:27.144753171 +0000 ++++ src/cmd/ksh93/edit/emacs.c 2016-02-18 10:34:33.289514039 +0000 +@@ -721,10 +721,8 @@ process: + draw(ep,FINAL); + tty_cooked(ERRIO); + if(ed->e_nlist) +- { + ed->e_nlist = 0; +- stakset(ed->e_stkptr,ed->e_stkoff); +- } ++ stakset(ed->e_stkptr,ed->e_stkoff); + if(c == '\n') + { + out[eol++] = '\n'; +--- src/cmd/ksh93/edit/vi.c.orig 2016-02-18 10:33:35.772722001 +0000 ++++ src/cmd/ksh93/edit/vi.c 2016-02-18 10:36:15.506143712 +0000 +@@ -608,10 +608,8 @@ int ed_viread(void *context, int fd, reg + /* to cause the shell to process the line */ + tty_cooked(ERRIO); + if(ed->e_nlist) +- { + ed->e_nlist = 0; +- stakset(ed->e_stkptr,ed->e_stkoff); +- } ++ stakset(ed->e_stkptr,ed->e_stkoff); + if( vp->addnl ) + { + virtual[++last_virt] = '\n'; diff --git a/ksh93-env.dif b/ksh93-env.dif new file mode 100644 index 0000000..89b679a --- /dev/null +++ b/ksh93-env.dif @@ -0,0 +1,22 @@ +--- src/cmd/ksh93/sh/init.c ++++ src/cmd/ksh93/sh/init.c 2013-02-15 13:29:57.129444048 +0000 +@@ -336,6 +336,8 @@ static void put_restricted(register Namv + int path_scoped = 0, fpath_scoped=0; + Pathcomp_t *pp; + char *name = nv_name(np); ++ if (!shp) ++ shp = sh_getinterp(); + if(!(flags&NV_RDONLY) && sh_isoption(SH_RESTRICTED)) + errormsg(SH_DICT,ERROR_exit(1),e_restricted,nv_name(np)); + if(np==PATHNOD || (path_scoped=(strcmp(name,PATHNOD->nvname)==0))) +--- src/cmd/ksh93/sh/name.c ++++ src/cmd/ksh93/sh/name.c 2012-10-16 12:12:43.000000000 +0000 +@@ -2162,7 +2162,7 @@ static void attstore(register Namval_t * + if((flag&(NV_UTOL|NV_LTOU|NV_INTEGER)) == (NV_UTOL|NV_LTOU)) + { + data = (void*)nv_mapchar(np,0); +- if(strcmp(data,e_tolower) && strcmp(data,e_toupper)) ++ if(data && strcmp(data,e_tolower) && strcmp(data,e_toupper)) + return; + } + flag &= (NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER); diff --git a/ksh93-fdstatus.dif b/ksh93-fdstatus.dif new file mode 100644 index 0000000..f8a8be5 --- /dev/null +++ b/ksh93-fdstatus.dif @@ -0,0 +1,1631 @@ +| Fix for bnc#814135, bnc#808449, bnc#835885, and bnc#844071 +| - crash in bestreclaim() after traversing a memory block with a very large size (ksh) +| - set -k does not work properly with ksh-93t-13.17 and higher +| - Problem after update of ksh from ksh-93u-0.14.1 to ksh-93u-0.22.1 +| - Regression: Fix crash in sfio code of libast +| This is a backport from the beta version ksh93v-2013-10-10 +--- src/cmd/ksh93/bltins/enum.c ++++ src/cmd/ksh93/bltins/enum.c 2013-10-25 13:26:45.739248213 +0000 +@@ -266,7 +266,9 @@ int b_enum(int argc, char** argv, Shblti + optdisc.opt.infof = enuminfo; + optdisc.np = tp; + nv_addtype(tp, enum_type, &optdisc.opt, sizeof(optdisc)); ++ nv_onattr(np,NV_LTOU|NV_UTOL); + } ++ nv_open(0,shp->var_tree,0); + return error_info.errors != 0; + } + +--- src/cmd/ksh93/bltins/read.c ++++ src/cmd/ksh93/bltins/read.c 2013-10-25 13:26:45.740248120 +0000 +@@ -280,24 +280,25 @@ int sh_readline(register Shell_t *shp,ch + if(size || (flags>>D_FLAG)) /* delimiter not new-line or fixed size read */ + { + if((shp->fdstatus[fd]&IOTTY) && !keytrap) +- tty_raw(fd,1); ++ tty_raw(sffileno(iop),1); + if(!(flags&(N_FLAG|NN_FLAG))) + { + delim = ((unsigned)flags)>>D_FLAG; + ep->e_nttyparm.c_cc[VEOL] = delim; + ep->e_nttyparm.c_lflag |= ISIG; +- tty_set(fd,TCSADRAIN,&ep->e_nttyparm); ++ tty_set(sffileno(iop),TCSADRAIN,&ep->e_nttyparm); + } + #if defined(__linux__) + else if ((shp->fdstatus[fd]&(IOTTY|IONOSEEK))==0) + { + struct stat st; +- if ((fstat(fd, &st) == 0) && S_ISFIFO(st.st_mode)) ++ int fn = sffileno(iop); ++ if ((fstat(fn, &st) == 0) && S_ISFIFO(st.st_mode)) + { + int fdflg; +- if (((fdflg = fcntl(fd, F_GETFL)) != -1) && !(fdflg & O_NONBLOCK)) +- fcntl(fd, F_SETFL, fdflg|O_NONBLOCK); +- shp->fdstatus[fd] |= IONOSEEK; ++ if (((fdflg = fcntl(fn, F_GETFL)) != -1) && !(fdflg & O_NONBLOCK)) ++ fcntl(fn, F_SETFL, fdflg|O_NONBLOCK); ++ shp->fdstatus[fn] |= IONOSEEK; + } + } + #endif +@@ -342,7 +343,7 @@ int sh_readline(register Shell_t *shp,ch + size = nv_size(np); + } + was_write = (sfset(iop,SF_WRITE,0)&SF_WRITE)!=0; +- if(fd==0) ++ if(sffileno(iop)==0) + was_share = (sfset(iop,SF_SHARE,shp->redir0!=2)&SF_SHARE)!=0; + if(timeout || (shp->fdstatus[fd]&(IOTTY|IONOSEEK))) + { +@@ -366,7 +367,7 @@ int sh_readline(register Shell_t *shp,ch + else + end = var + sizeof(buf) - 1; + up = cur = var; +- if((sfset(iop,SF_SHARE,1)&SF_SHARE) && fd!=0) ++ if((sfset(iop,SF_SHARE,1)&SF_SHARE) && sffileno(iop)!=0) + was_share = 1; + if(size==0) + { +@@ -473,7 +474,7 @@ int sh_readline(register Shell_t *shp,ch + timerdel(timeslot); + if(binary && !((size=nv_size(np)) && nv_isarray(np) && c!=size)) + { +- if((c==size) && np->nvalue.cp && !nv_isarray(np)) ++ if((c==size) && np->nvalue.cp && !nv_isarray(np) && !np->nvfun) + memcpy((char*)np->nvalue.cp,var,c); + else + { +@@ -819,7 +820,7 @@ done: + sfset(iop,SF_SHARE,0); + nv_close(np); + if((shp->fdstatus[fd]&IOTTY) && !keytrap) +- tty_cooked(fd); ++ tty_cooked(sffileno(iop)); + if(flags&S_FLAG) + hist_flush(shp->gd->hist_ptr); + if(jmpval > 1) +--- src/cmd/ksh93/bltins/trap.c ++++ src/cmd/ksh93/bltins/trap.c 2013-10-25 13:26:45.740248120 +0000 +@@ -116,8 +116,7 @@ int b_trap(int argc,char *argv[],Shbltin + continue; + } + shp->st.otrap = 0; +- if(shp->st.trap[sig]) +- free(shp->st.trap[sig]); ++ arg = shp->st.trap[sig]; + shp->st.trap[sig] = 0; + if(!clear && *action) + shp->st.trap[sig] = strdup(action); +@@ -128,6 +127,8 @@ int b_trap(int argc,char *argv[],Shbltin + else + shp->trapnote = 0; + } ++ if(arg) ++ free(arg); + continue; + } + if(sig>shp->gd->sigmax) +--- src/cmd/ksh93/bltins/typeset.c ++++ src/cmd/ksh93/bltins/typeset.c 2013-10-25 13:26:45.741248028 +0000 +@@ -676,7 +676,7 @@ static int setall(char **argv,regist + } + if(!nv_isarray(np) && !strchr(name,'=') && !(shp->envlist && nv_onlist(shp->envlist,name))) + { +- if(comvar || (shp->last_root==shp->var_tree && (tp->tp || (!shp->st.real_fun && (nvflags&NV_STATIC)) || (!(flag&(NV_EXPORT|NV_RDONLY)) && nv_isattr(np,(NV_EXPORT|NV_IMPORT))==(NV_EXPORT|NV_IMPORT))))) ++ if(comvar || (shp->last_root==shp->var_tree && ((tp->tp && tp->tp!=nv_type(np)) || (!shp->st.real_fun && (nvflags&NV_STATIC)) || (!(flag&(NV_EXPORT|NV_RDONLY)) && nv_isattr(np,(NV_EXPORT|NV_IMPORT))==(NV_EXPORT|NV_IMPORT))))) + { + if((flag&(NV_HOST|NV_INTEGER))!=NV_HOST) + _nv_unset(np,0); +--- src/cmd/ksh93/include/defs.h ++++ src/cmd/ksh93/include/defs.h 2013-10-25 13:26:45.741248028 +0000 +@@ -182,6 +182,8 @@ struct shared + pid_t spid; /* subshell process id */ \ + pid_t pipepid; \ + pid_t outpipepid; \ ++ pid_t *procsub; /* pids for >() argument */ \ ++ int nprocsub; /* number of pids in procsub */ \ + int topfd; \ + int savesig; \ + unsigned char *sigflag; /* pointer to signal states */ \ +@@ -243,7 +245,7 @@ struct shared + char *cur_line; \ + int offsets[10]; \ + Sfio_t **sftable; \ +- unsigned char *fdstatus; \ ++ unsigned int *fdstatus; \ + const char *pwd; \ + void *jmpbuffer; \ + void *mktype; \ +--- src/cmd/ksh93/include/io.h ++++ src/cmd/ksh93/include/io.h 2013-10-25 13:26:45.741248028 +0000 +@@ -81,6 +81,7 @@ extern void sh_iosave(Shell_t *, int,in + extern int sh_iovalidfd(Shell_t*, int); + extern int sh_inuse(Shell_t*, int); + extern void sh_iounsave(Shell_t*); ++extern void sh_iounpipe(Shell_t*); + extern int sh_chkopen(const char*); + extern int sh_ioaccess(int,int); + extern int sh_devtofd(const char*); +--- src/cmd/ksh93/include/jobs.h ++++ src/cmd/ksh93/include/jobs.h 2013-10-25 13:26:45.741248028 +0000 +@@ -103,6 +103,7 @@ struct jobs + pid_t mypid; /* process id of shell */ + pid_t mypgid; /* process group id of shell */ + pid_t mytgid; /* terminal group id of shell */ ++ pid_t lastpost; /* last job posted */ + int curjobid; + unsigned int in_critical; /* >0 => in critical region */ + int savesig; /* active signal */ +@@ -152,11 +153,11 @@ extern struct jobs job; + #define job_lock() (job.in_critical++) + #define job_unlock() \ + do { \ +- int sig; \ +- if (!--job.in_critical && (sig = job.savesig)) \ ++ int _sig; \ ++ if (!--job.in_critical && (_sig = job.savesig)) \ + { \ + if (!job.in_critical++ && !vmbusy()) \ +- job_reap(sig); \ ++ job_reap(_sig); \ + job.in_critical--; \ + } \ + } while(0) +--- src/cmd/ksh93/sh/args.c ++++ src/cmd/ksh93/sh/args.c 2013-10-25 13:26:45.741248028 +0000 +@@ -32,6 +32,7 @@ + #include "builtins.h" + #include "terminal.h" + #include "edit.h" ++#include "jobs.h" + #include "FEATURE/poll" + #if SHOPT_KIA + # include "shlex.h" +@@ -57,6 +58,7 @@ + #define PRINT 2 + + static char *null; ++static pid_t *procsub; + + /* The following order is determined by sh_optset */ + static const char optksh[] = PFSHOPT BASHOPT "DircabefhkmnpstuvxBCGEl" HFLAG; +@@ -717,6 +719,7 @@ char **sh_argbuild(Shell_t *shp,int *nar + return(ap->dolval+ap->dolbot); + } + shp->lastpath = 0; ++ procsub = shp->procsub; + *nargs = 0; + if(ac) + { +@@ -737,6 +740,8 @@ char **sh_argbuild(Shell_t *shp,int *nar + } + argp = arghead; + } ++ if(procsub) ++ *procsub = 0; + } + { + register char **comargn; +@@ -782,8 +787,9 @@ struct argnod *sh_argprocsub(Shell_t *sh + { + /* argument of the form <(cmd) or >(cmd) */ + register struct argnod *ap; +- int monitor, fd, pv[3]; ++ int nn, monitor, fd, pv[3]; + int subshell = shp->subshell; ++ pid_t pid0; + ap = (struct argnod*)stkseek(shp->stk,ARGVAL); + ap->argflag |= ARG_MAKE; + ap->argflag &= ~ARG_RAW; +@@ -794,18 +800,33 @@ struct argnod *sh_argprocsub(Shell_t *sh + sfwrite(shp->stk,e_devfdNN,8); + pv[2] = 0; + sh_pipe(pv); ++ sfputr(shp->stk,fmtbase((long)pv[fd],10,0),0); + #else + pv[0] = -1; + shp->fifo = pathtemp(0,0,0,"ksh.fifo",0); + mkfifo(shp->fifo,S_IRUSR|S_IWUSR); + sfputr(shp->stk,shp->fifo,0); + #endif /* SHOPT_DEVFD */ +- sfputr(shp->stk,fmtbase((long)pv[fd],10,0),0); + ap = (struct argnod*)stkfreeze(shp->stk,0); + shp->inpipe = shp->outpipe = 0; + if(monitor = (sh_isstate(SH_MONITOR)!=0)) + sh_offstate(SH_MONITOR); + shp->subshell = 0; ++#if SHOPT_DEVFD ++ fcntl(pv[fd],F_SETFD,0); ++ shp->fdstatus[pv[fd]] &= ~IOCLEX; ++#endif /* SHOPT_DEVFD */ ++ pid0=shp->procsub?*shp->procsub:0; ++ if(!shp->procsub) ++ shp->procsub = procsub = newof(0,pid_t,shp->nprocsub=4,0); ++ else if((nn=procsub-shp->procsub) >= shp->nprocsub) ++ { ++ shp->nprocsub += 3; ++ shp->procsub = newof(shp->procsub,pid_t,shp->nprocsub,0); ++ procsub = shp->procsub + nn; ++ } ++ if(pid0) ++ *shp->procsub = 0; + if(fd) + { + shp->inpipe = pv; +@@ -816,11 +837,14 @@ struct argnod *sh_argprocsub(Shell_t *sh + shp->outpipe = pv; + sh_exec((Shnode_t*)argp->argchn.ap,(int)sh_isstate(SH_ERREXIT)); + } ++ if(pid0) ++ *shp->procsub = pid0; ++ *procsub++ = job.lastpost; + shp->subshell = subshell; + if(monitor) + sh_onstate(SH_MONITOR); + #if SHOPT_DEVFD +- close(pv[1-fd]); ++ sh_close(pv[1-fd]); + sh_iosave(shp,-pv[fd], shp->topfd, (char*)0); + #else + free(shp->fifo); +--- src/cmd/ksh93/sh/array.c ++++ src/cmd/ksh93/sh/array.c 2013-10-25 13:26:45.742247936 +0000 +@@ -438,10 +438,13 @@ int nv_arraysettype(Namval_t *np, Namval + nv_offattr(nq,NV_RDONLY); + if(!nv_isattr(tp,NV_BINARY)) + { ++ char *prefix = shp->prefix; + if(xtrace) + sh_offoption(SH_XTRACE); + ap->nelem &= ~ARRAY_SCAN; ++ shp->prefix = 0; + sh_eval(sh_sfeval(av),0); ++ shp->prefix = prefix; + ap->nelem |= ARRAY_SCAN; + free((void*)av[0]); + if(xtrace) +@@ -773,7 +776,10 @@ static void array_putval(Namval_t *np, c + free((void*)aq->xp); + } + if((nfp = nv_disc(np,(Namfun_t*)ap,NV_POP)) && !(nfp->nofree&1)) ++ { ++ ap = 0; + free((void*)nfp); ++ } + if(!nv_isnull(np)) + { + if(!np->nvfun) +@@ -785,7 +791,7 @@ static void array_putval(Namval_t *np, c + if(np->nvalue.cp==Empty) + np->nvalue.cp = 0; + } +- if(!string && (flags&NV_TYPE)) ++ if(!string && (flags&NV_TYPE) && ap) + array_unscope(np,ap); + } + +--- src/cmd/ksh93/sh/fault.c ++++ src/cmd/ksh93/sh/fault.c 2013-10-25 13:26:45.742247936 +0000 +@@ -518,6 +518,8 @@ void sh_exit(register int xno) + shp->exitval |= (sig=shp->lastsig); + if(pp && pp->mode>1) + cursig = -1; ++ if(shp->procsub) ++ *shp->procsub = 0; + #ifdef SIGTSTP + if(shp->trapnote&SH_SIGTSTP) + { +--- src/cmd/ksh93/sh/io.c ++++ src/cmd/ksh93/sh/io.c 2013-10-25 13:26:45.743247844 +0000 +@@ -407,7 +407,7 @@ int sh_iovalidfd(Shell_t *shp, int fd) + { + Sfio_t **sftable = shp->sftable; + int max,n, **fdptrs = shp->fdptrs; +- unsigned char *fdstatus = shp->fdstatus; ++ unsigned int *fdstatus = shp->fdstatus; + if(fd<0) + return(0); + if(fd < shp->gd->lim.open_max) +@@ -422,13 +422,13 @@ int sh_iovalidfd(Shell_t *shp, int fd) + if(n > max) + n = max; + max = shp->gd->lim.open_max; +- shp->sftable = (Sfio_t**)calloc((n+1)*(sizeof(int*)+sizeof(Sfio_t*)+1),1); ++ shp->sftable = (Sfio_t**)calloc((n+1)*(sizeof(int*)+sizeof(Sfio_t*)+sizeof(*fdstatus)),1); + if(max) + memcpy(shp->sftable,sftable,max*sizeof(Sfio_t*)); + shp->fdptrs = (int**)(&shp->sftable[n]); + if(max) + memcpy(shp->fdptrs,fdptrs,max*sizeof(int*)); +- shp->fdstatus = (unsigned char*)(&shp->fdptrs[n]); ++ shp->fdstatus = (unsigned int*)(&shp->fdptrs[n]); + if(max) + memcpy(shp->fdstatus,fdstatus,max); + if(sftable) +@@ -686,7 +686,10 @@ int sh_close(register int fd) + register Sfio_t *sp; + register int r = 0; + if(fd<0) ++ { ++ errno = EBADF; + return(-1); ++ } + if(fd >= shp->gd->lim.open_max) + sh_iovalidfd(shp,fd); + if(!(sp=shp->sftable[fd]) || sfclose(sp) < 0) +@@ -699,13 +702,15 @@ int sh_close(register int fd) + } + if(fd>2) + shp->sftable[fd] = 0; ++ if(r = (shp->fdstatus[fd]>>8)) ++ close(r); + shp->fdstatus[fd] = IOCLOSE; + if(shp->fdptrs[fd]) + *shp->fdptrs[fd] = -1; + shp->fdptrs[fd] = 0; + if(fd < 10) + shp->inuse_bits &= ~(1<= shp->gd->lim.open_max) + sh_iovalidfd(shp,fdold); +- if(fdold<0 || fdold>2) ++ if(fdold<0 || fdold>9) + return(fdold); +- fdnew = sh_iomovefd(dup(fdold)); ++ fdnew = sh_iomovefd(sh_fcntl(fdold,F_DUPFD,10)); + shp->fdstatus[fdnew] = (shp->fdstatus[fdold]&~IOCLEX); + close(fdold); + shp->fdstatus[fdold] = IOCLOSE; +@@ -964,7 +969,7 @@ int sh_pipe(register int pv[]) + while ((r=bind (pv[out], (struct sockaddr *) &sin, slen)) == -1 && errno==EADDRINUSE); + if(r<0 || listen(pv[out],5) <0) + { +- close(pv[out]); ++ sh_close(pv[out]); + errormsg(SH_DICT,ERROR_system(1),e_pipe); + } + fcntl(pv[out],F_SETFD,FD_CLOEXEC); +@@ -1079,7 +1084,7 @@ static char *io_usename(char *name, int + if((fd = sh_open(name,O_RDONLY,0)) >= 0) + { + r = fstat(fd,&statb); +- close(fd); ++ sh_close(fd); + if(r) + return(0); + if(!S_ISREG(statb.st_mode)) +@@ -1144,6 +1149,7 @@ int sh_redirect(Shell_t *shp,struct iono + char *tname=0, *after="", *trace = shp->st.trap[SH_DEBUGTRAP]; + Namval_t *np=0; + int isstring = shp->subshell?(sfset(sfstdout,0,0)&SF_STRING):0; ++ Sfio_t *sp; + + if(flag==2) + clexec = 1; +@@ -1245,16 +1251,35 @@ int sh_redirect(Shell_t *shp,struct iono + { + int dupfd,toclose= -1; + io_op[2] = '&'; +- if((fd=fname[0])>='0' && fd<='9') ++ if((fd=fname[0])>='0' && (fd=='{' || fd<='9')) + { + char *number = fname; +- dupfd = strtol(fname,&number,10); ++ int f; ++ if(fd=='{') ++ { ++ np = 0; ++ if(number=strchr(fname,'}')) ++ { ++ *number = 0; ++ np = nv_open(fname+1,shp->var_tree,NV_NOASSIGN|NV_VARNAME|NV_NOFAIL); ++ *number++ = '}'; ++ } ++ if(!np) ++ { ++ message = e_file; ++ goto fail; ++ } ++ dupfd = nv_getnum(np); ++ np = 0; ++ } ++ else ++ dupfd = strtol(fname,&number,10); + if(*number=='-') + { + toclose = dupfd; + number++; + } +- if(*number || dupfd > IOUFD) ++ if(*number) + { + message = e_file; + goto fail; +@@ -1267,8 +1292,23 @@ int sh_redirect(Shell_t *shp,struct iono + shp->subdup |= 1<sftable[dupfd]) ++ else if(sp=shp->sftable[dupfd]) ++ { ++ char *tmpname; ++ if((sfset(sp,0,0)&SF_STRING) && (tmpname = pathtemp(NiL ,NiL,NiL,"sf",&f))) ++ { ++ Sfoff_t last = sfseek(sp,(Sfoff_t)0,SEEK_END); ++ ++ unlink(tmpname); ++ free(tmpname); ++ write(f, sp->_data, (size_t)last); ++ lseek(f,(Sfoff_t)0,SEEK_SET); ++ ++ sfclose(sp); ++ sp = sfnew(sp,NULL,-1,f,SF_READ); ++ } + sfsync(shp->sftable[dupfd]); ++ } + if(dupfd!=1 && fn < 10) + shp->subdup &= ~(1<sftable[dupfd]) && sfset(sp,0,0)&SF_STRING) ++ { ++ char *cp; ++ Sfoff_t off = sftell(sp); ++ sfset(sp,SF_MALLOC,0); ++ cp = sfsetbuf(sp,(char*)sp,0); ++ sfset(sp,SF_MALLOC,1); ++ r = (int)(sfseek(sp,(Sfoff_t)0,SEEK_END)-off); ++ sfseek(sp,off,SEEK_SET); ++ fd = shp->gd->lim.open_max-1; ++ shp->sftable[fd] = sfnew(NIL(Sfio_t*),cp,r,-1,SF_READ|SF_STRING); ++ shp->fdstatus[fd] = shp->fdstatus[dupfd]; ++ } ++ else if((fd=sh_fcntl(dupfd,F_DUPFD,3))<0) + goto fail; + if(fd>= shp->gd->lim.open_max) + sh_iovalidfd(shp,fd); +- sh_iocheckfd(shp,dupfd); ++ if(!shp->sftable[dupfd]) ++ sh_iocheckfd(shp,dupfd); + shp->fdstatus[fd] = (shp->fdstatus[dupfd]&~IOCLEX); + if(toclose<0 && shp->fdstatus[fd]&IOREAD) + shp->fdstatus[fd] |= IODUP; +@@ -1496,7 +1550,8 @@ int sh_redirect(Shell_t *shp,struct iono + if(fn>9 || !(shp->inuse_bits&(1<sftable[fn],fn); + } +- sh_close(fn); ++ if(!(iof&IODOC)) ++ sh_close(fn); + } + if(flag==3) + return(fd); +@@ -1531,7 +1586,24 @@ int sh_redirect(Shell_t *shp,struct iono + shp->inuse_bits |= (1<2 && clexec) ++ else if(iof&IODOC) ++ { ++ Sfio_t *sp = &_Sfstderr; ++ if(fn==1) ++ sp = &_Sfstdout; ++ else if(fn==0) ++ sp = &_Sfstdin; ++ shp->sftable[fn] = shp->sftable[-1]; ++ shp->fdstatus[fn] = shp->fdstatus[-1]; ++ if(fn <=2) ++ { ++ sfswap(shp->sftable[fn],sp); ++ shp->sftable[fn] = sp; ++ } ++ shp->fdptrs[fn] = 0; ++ shp->sftable[-1] = 0; ++ } ++ if(fd >2 && clexec && !(shp->fdstatus[fd]&IOCLEX)) + { + fcntl(fd,F_SETFD,FD_CLOEXEC); + shp->fdstatus[fd] |= IOCLEX; +@@ -1619,12 +1691,12 @@ static int io_heredoc(Shell_t *shp,regis + sfclose(infile); + } + } ++ if(traceon && !(iop->iofile&IOSTRG)) ++ sfputr(sfstderr,iop->ioname,'\n'); + /* close stream outfile, but save file descriptor */ + fd = sffileno(outfile); + sfsetfd(outfile,-1); + sfclose(outfile); +- if(traceon && !(iop->iofile&IOSTRG)) +- sfputr(sfstderr,iop->ioname,'\n'); + lseek(fd,(off_t)0,SEEK_SET); + shp->fdstatus[fd] = IOREAD; + return(fd); +@@ -2059,9 +2131,11 @@ int sh_iocheckfd(Shell_t *shp, register + if(!(n&(IOSEEK|IONOSEEK))) + { + struct stat statb; ++ Sfio_t *sp = shp->sftable[fd]; + /* /dev/null check is a workaround for select bug */ + static ino_t null_ino; + static dev_t null_dev; ++ shp->sftable[fd] = 0; + if(null_ino==0 && stat(e_devnull,&statb) >=0) + { + null_ino = statb.st_ino; +@@ -2097,6 +2171,7 @@ int sh_iocheckfd(Shell_t *shp, register + n |= IONOSEEK; + else + n |= IOSEEK; ++ shp->sftable[fd] = sp; + } + if(fd==0) + n &= ~IOWRITE; +@@ -2143,6 +2218,7 @@ static int io_prompt(Shell_t *shp,Sfio_t + } + #endif /* TIOCLBIC */ + cp = sh_mactry(shp,nv_getval(sh_scoped(shp,PS1NOD))); ++ shp->exitval = 0; + for(;c= *cp;cp++) + { + if(c==HIST_CHAR) +@@ -2494,12 +2570,14 @@ skip: + */ + ssize_t sh_read(register int fd, void* buff, size_t n) + { ++ int r,err=errno; + Shell_t *shp = sh_getinterp(); + register Sfio_t *sp; + if(sp=shp->sftable[fd]) + return(sfread(sp,buff,n)); +- else +- return(read(fd,buff,n)); ++ while ((r=read(fd,buff,n))<0 && errno==EINTR) ++ errno = err; ++ return(r); + } + + #undef write +@@ -2508,12 +2586,14 @@ ssize_t sh_read(register int fd, void* b + */ + ssize_t sh_write(register int fd, const void* buff, size_t n) + { ++ int r,err=errno; + Shell_t *shp = sh_getinterp(); + register Sfio_t *sp; + if(sp=shp->sftable[fd]) + return(sfwrite(sp,buff,n)); +- else +- return(write(fd,buff,n)); ++ while ((r=write(fd,buff,n))<0 && errno==EINTR) ++ errno = err; ++ return(r); + } + + #undef lseek +--- src/cmd/ksh93/sh/jobs.c ++++ src/cmd/ksh93/sh/jobs.c 2013-10-25 13:26:45.744247751 +0000 +@@ -424,6 +424,8 @@ int job_reap(register int sig) + } + if(pid<=0) + break; ++ if(pid==shp->spid) ++ shp->spid = 0; + if(wstat==0) + job_chksave(pid); + flags |= WNOHANG; +@@ -520,7 +522,12 @@ int job_reap(register int sig) + { + shp->sigflag[SIGCHLD] |= SH_SIGTRAP; + if(sig==0) ++ { ++ int c = job.in_critical; ++ job.in_critical = 0; + job_chldtrap(shp,shp->st.trapcom[SIGCHLD],0); ++ job.in_critical = c; ++ } + else + shp->trapnote |= SH_SIGTRAP; + } +@@ -646,7 +653,7 @@ void job_init(Shell_t *shp, int lflag) + return; + while(close(JOBTTY)<0 && errno==EINTR) + errno = err; +- if((fd = open(ttynam,O_RDWR)) <0) ++ if((fd = sh_open(ttynam,O_RDWR)) <0) + return; + if(fd!=JOBTTY) + sh_iorenumber(shp,fd,JOBTTY); +@@ -1313,6 +1320,7 @@ int job_post(Shell_t *shp,pid_t pid, pid + return(0); + } + job_lock(); ++ job.lastpost = pid; + #ifdef SHOPT_BGX + if(join==1) + { +@@ -1635,9 +1643,21 @@ int job_wait(register pid_t pid) + if(intr && shp->trapnote) + shp->exitval = 1; + pwfg = 0; +- job_unlock(); + if(pid==1) ++ { ++ if(nochild) ++ { ++ for(pw=job.pwlist; pw; pw=px) ++ { ++ px = pw->p_nxtjob; ++ pw->p_flag |= P_DONE; ++ job_unpost(pw,1); ++ } ++ } ++ job_unlock(); + return(nochild); ++ } ++ job_unlock(); + exitset(); + if(pid==0) + goto done; +@@ -1800,7 +1820,7 @@ static struct process *job_unpost(regist + #endif /* DEBUG */ + pwtop = pw = job_byjid((int)pwtop->p_job); + #ifdef SHOPT_BGX +- if(pw->p_flag&P_BG) ++ if(!pw || pw->p_flag&P_BG) + return(pw); + #endif /* SHOPT_BGX */ + for(; pw && (pw->p_flag&P_DONE)&&(notify||!(pw->p_flag&P_NOTIFY)||pw->p_env); pw=pw->p_nxtproc); +--- src/cmd/ksh93/sh/lex.c ++++ src/cmd/ksh93/sh/lex.c 2013-10-25 13:26:45.744247751 +0000 +@@ -556,7 +556,7 @@ int sh_lex(Lex_t* lp) + lp->lexd.docword=1; + else if(n==LPAREN) + { +- if(lp->lex.intest) ++ if(lp->lex.intest || lp->comp_assign) + return(c); + lp->lexd.nest=1; + lp->lastline = shp->inlineno; +@@ -2468,7 +2468,7 @@ static int alias_exceptf(Sfio_t *iop,int + if(dp!=handle) + sfdisc(iop,dp); + } +- else if(type==SF_FINAL) ++ else if(type==SF_DPOP || type==SF_FINAL) + free((void*)ap); + goto done; + } +--- src/cmd/ksh93/sh/macro.c ++++ src/cmd/ksh93/sh/macro.c 2013-10-25 13:26:45.745247659 +0000 +@@ -392,7 +392,7 @@ void sh_machere(Shell_t *shp,Sfio_t *inf + break; + } + case S_PAR: +- comsubst(mp,(Shnode_t*)0,1); ++ comsubst(mp,(Shnode_t*)0,3); + break; + case S_EOF: + if((c=fcfill()) > 0) +@@ -447,6 +447,7 @@ static void copyto(register Mac_t *mp,in + int ansi_c = 0; + int paren = 0; + int ere = 0; ++ int dotdot = 0; + int brace = 0; + Sfio_t *sp = mp->sp; + Stk_t *stkp = mp->shp->stk; +@@ -846,7 +847,7 @@ e_badsubscript,*cp); + { + sfwrite(stkp,first,c); + sfputc(stkp,0); +- mp->dotdot = stktell(stkp); ++ dotdot = stktell(stkp); + cp = first = fcseek(c+2); + } + break; +@@ -854,6 +855,7 @@ e_badsubscript,*cp); + } + done: + mp->sp = sp; ++ mp->dotdot = dotdot; + mp->quote = oldquote; + } + +@@ -1010,7 +1012,6 @@ static int subcopy(Mac_t *mp, int flag) + mp->pattern = flag?4:0; + mp->arrayok=1; + mp->subcopy++; +- mp->dotdot = 0; + copyto(mp,RBRACT,0); + mp->subcopy = 0; + mp->pattern = xpattern; +@@ -1099,6 +1100,7 @@ static int varsub(Mac_t *mp) + Stk_t *stkp = mp->shp->stk; + retry1: + mp->zeros = 0; ++ mp->dotdot = 0; + idbuff[0] = 0; + idbuff[1] = 0; + c = fcmbget(&LEN); +@@ -1166,7 +1168,7 @@ retry1: + case S_PAR: + if(type) + goto nosub; +- comsubst(mp,(Shnode_t*)0,1); ++ comsubst(mp,(Shnode_t*)0,3); + return(1); + case S_DIG: + var = 0; +@@ -1349,7 +1351,7 @@ retry1: + ap = nv_arrayptr(np=nq); + if(ap) + { +- nv_putsub(np,v,ARRAY_SCAN); ++ np = nv_putsub(np,v,ARRAY_SCAN); + v = stkptr(stkp,mp->dotdot); + dolmax =1; + if(array_assoc(ap)) +@@ -2077,6 +2079,18 @@ static void comsubst(Mac_t *mp,register + fcrestore(&save); + return; + } ++ else if(type==2 && t && (t->tre.tretyp&COMMSK)==0 && t->com.comarg) ++ { ++ Namval_t *np; ++ str = NULL; ++ if(!(t->com.comtyp&COMSCAN)) ++ { ++ struct dolnod *ap = (struct dolnod*)t->com.comarg; ++ str = ap->dolval[ap->dolbot]; ++ } ++ else if(t->com.comarg->argflag&ARG_RAW) ++ str = t->com.comarg->argval; ++ } + } + else + { +@@ -2158,10 +2172,9 @@ static void comsubst(Mac_t *mp,register + mp->ifsp = nv_getval(np); + stkset(stkp,savptr,savtop); + newlines = 0; +- sfsetbuf(sp,(void*)sp,0); +- bufsize = sfvalue(sp); + /* read command substitution output and put on stack or here-doc */ + sfpool(sp, NIL(Sfio_t*), SF_WRITE); ++ sfset(sp, SF_WRITE|SF_PUBLIC|SF_SHARE,0); + sh_offstate(SH_INTERACTIVE); + if((foff = sfseek(sp,(Sfoff_t)0,SEEK_END)) > 0) + { +@@ -2170,6 +2183,8 @@ static void comsubst(Mac_t *mp,register + stkseek(stkp,soff+foff+64); + stkseek(stkp,soff); + } ++ if(foff > IOBSIZE) ++ sfsetbuf(sp,NULL,SF_UNBOUND); + while((str=(char*)sfreserve(sp,SF_UNBOUND,0)) && (c=bufsize=sfvalue(sp))>0) + { + #if SHOPT_CRNL +@@ -2291,6 +2306,13 @@ static void mac_copy(register Mac_t *mp, + Stk_t *stkp=mp->shp->stk; + int oldpat = mp->pattern; + nopat = (mp->quote||(mp->assign==1)||mp->arith); ++ if(size>512) ++ { ++ /* pre-allocate to improve performance */ ++ c = stktell(stkp); ++ stkseek(stkp,c+size+(size>>4)); ++ stkseek(stkp,c); ++ } + if(mp->zeros) + { + /* prevent leading 0's from becomming octal constants */ +--- src/cmd/ksh93/sh/main.c ++++ src/cmd/ksh93/sh/main.c 2013-10-25 13:26:45.745247659 +0000 +@@ -309,7 +309,7 @@ int sh_main(int ac, char *av[], Shinit_f + int isdir = 0; + if((fdin=sh_open(name,O_RDONLY,0))>=0 &&(fstat(fdin,&statb)<0 || S_ISDIR(statb.st_mode))) + { +- close(fdin); ++ sh_close(fdin); + isdir = 1; + fdin = -1; + } +--- src/cmd/ksh93/sh/name.c ++++ src/cmd/ksh93/sh/name.c 2013-10-25 13:26:45.746247567 +0000 +@@ -421,6 +421,8 @@ void nv_setlist(register struct argnod * + if(array&NV_ARRAY) + { + nv_setarray(np,nv_associative); ++ if(typ) ++ nv_settype(np,typ,0); + } + else + { +@@ -436,7 +438,7 @@ void nv_setlist(register struct argnod * + #endif /* SHOPT_TYPEDEF */ + } + /* check for array assignment */ +- if(tp->tre.tretyp!=TLST && tp->com.comarg && !tp->com.comset && ((array&NV_IARRAY) || !((mp=tp->com.comnamp) && nv_isattr(mp,BLT_DCL)))) ++ if((tp->tre.tretyp&COMMSK)==TCOM && tp->com.comarg && !tp->com.comset && ((array&NV_IARRAY) || !((mp=tp->com.comnamp) && nv_isattr(mp,BLT_DCL)))) + { + int argc; + Dt_t *last_root = shp->last_root; +@@ -509,6 +511,7 @@ void nv_setlist(register struct argnod * + if(!(array&NV_IARRAY) && !(tp->com.comset->argflag&ARG_MESSAGE)) + nv_setarray(np,nv_associative); + } ++ shp->typeinit = 0; + nv_setlist(tp->com.comset,flags&~NV_STATIC,0); + shp->prefix = prefix; + if(tp->com.comset->argval[1]!='[') +@@ -1292,8 +1295,9 @@ void nv_delete(Namval_t* np, Dt_t *root, + if(rp->sub) + free(rp->sub); + rp->sub = 0; +- rp = dtdelete(Refdict,(void*)rp); +- rp->np = &NullNode; ++ rp = dtremove(Refdict,(void*)rp); ++ if(rp) ++ rp->np = &NullNode; + } + } + } +@@ -1345,10 +1349,12 @@ Namval_t *nv_open(const char *name, Dt_t + struct Cache_entry *xp; + #endif + +- sh_stats(STAT_NVOPEN); + memset(&fun,0,sizeof(fun)); + shp->openmatch = 0; + shp->last_table = 0; ++ if(!name) ++ return(0); ++ sh_stats(STAT_NVOPEN); + if(!root) + root = shp->var_tree; + shp->last_root = root; +@@ -2470,6 +2476,8 @@ static void table_unset(Shell_t *shp, re + } + } + npnext = (Namval_t*)dtnext(root,np); ++ if(nv_arrayptr(np)) ++ nv_putsub(np,NIL(char*),ARRAY_SCAN); + _nv_unset(np,flags); + nv_delete(np,root,0); + } +@@ -2552,9 +2560,11 @@ void _nv_unset(register Namval_t *np,int + /* This function contains disc */ + if(!nv_local) + { ++ Dt_t *last_root = shp->last_root; + nv_local=1; + nv_putv(np,NIL(char*),flags,np->nvfun); + nv_local=0; ++ shp->last_root = last_root; + return; + } + /* called from disc, assign the actual value */ +@@ -2575,7 +2585,7 @@ void _nv_unset(register Namval_t *np,int + { + + if(np->nvalue.nrp->root) +- dtdelete(Refdict,(void*)np->nvalue.nrp); ++ dtremove(Refdict,(void*)np->nvalue.nrp); + if(np->nvalue.nrp->sub) + free(np->nvalue.nrp->sub); + free((void*)np->nvalue.nrp); +@@ -3577,7 +3587,7 @@ void nv_unref(register Namval_t *np) + { + if(np->nvalue.nrp->sub) + free(np->nvalue.nrp->sub); +- dtdelete(Refdict,(void*)np->nvalue.nrp); ++ dtremove(Refdict,(void*)np->nvalue.nrp); + } + free((void*)np->nvalue.nrp); + np->nvalue.cp = strdup(nv_name(nq)); +--- src/cmd/ksh93/sh/nvtree.c ++++ src/cmd/ksh93/sh/nvtree.c 2013-10-25 13:26:45.747247475 +0000 +@@ -144,8 +144,9 @@ static Namfun_t *nextdisc(Namval_t *np) + + void *nv_diropen(Namval_t *np,const char *name) + { +- char *next,*last; +- int c,len=strlen(name); ++ const char *last; ++ char *next; ++ size_t c=0,len=strlen(name); + struct nvdir *save, *dp = new_of(struct nvdir,len+1); + Namval_t *nq=0,fake; + Namfun_t *nfp=0; +@@ -1031,9 +1032,18 @@ static char *walk_tree(register Namval_t + shp->var_tree = dp; + if(nq && mq) + { ++ register struct nvdir *odir=0,*dp = (struct nvdir*)dir; ++ if(dp->table==nq) ++ { ++ dp = dp->prev; ++ odir = dir; ++ dir = dp; ++ } + nv_clone(nq,mq,flags|NV_RAW); + if(flags&NV_MOVE) + nv_delete(nq,walk.root,0); ++ if(odir) ++ free(odir); + } + continue; + } +--- src/cmd/ksh93/sh/nvtype.c ++++ src/cmd/ksh93/sh/nvtype.c 2013-10-25 13:26:45.747247475 +0000 +@@ -484,7 +484,10 @@ static Namfun_t *clone_type(Namval_t* np + } + } + if(nv_isattr(mp,NV_BINARY)) ++ { + mp->nvalue.cp = dp->data; ++ nv_onattr(mp,NV_NOFREE); ++ } + if(pp->strsize<0) + dp->strsize = -pp->strsize; + return(&dp->fun); +--- src/cmd/ksh93/sh/parse.c ++++ src/cmd/ksh93/sh/parse.c 2013-10-25 13:26:45.748247383 +0000 +@@ -1722,6 +1722,7 @@ static struct ionod *inout(Lex_t *lexp,s + lexp->digits=0; + iop=(struct ionod*) stkalloc(stkp,sizeof(struct ionod)); + iop->iodelim = 0; ++ iop->iosize = 0; + if(token=sh_lex(lexp)) + { + if(token==RPAREN && (iof&IOLSEEK) && lexp->comsub) +--- src/cmd/ksh93/sh/path.c ++++ src/cmd/ksh93/sh/path.c 2013-10-25 13:27:42.151044203 +0000 +@@ -333,7 +333,8 @@ static char *path_lib(Shell_t *shp,Pathc + char save[8]; + for( ;pp; pp=pp->next) + { +- path_checkdup(shp,pp); ++ if(!pp->dev && !pp->ino) ++ path_checkdup(shp,pp); + if(pp->ino==statb.st_ino && pp->dev==statb.st_dev && pp->mtime==statb.st_mtime) + return(pp->lib); + } +@@ -613,6 +614,7 @@ static void funload(Shell_t *shp,int fno + } + while((rp=dtnext(shp->fpathdict,rp)) && strcmp(pname,rp->fname)==0); + sh_close(fno); ++ free((void*)pname); + return; + } + sh_onstate(SH_NOLOG); +@@ -876,7 +878,7 @@ Pathcomp_t *path_absolute(Shell_t *shp,r + { + nv_onattr(nv_open(name,sh_subfuntree(shp,1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE),NV_LTOU|NV_FUNCTION); + funload(shp,f,name); +- close(f); ++ sh_close(f); + f = -1; + return(0); + } +@@ -1408,7 +1410,7 @@ static void exscript(Shell_t *shp,regist + sabuf.ac_etime = compress( (time_t)(after-before)); + fd = open( SHACCT , O_WRONLY | O_APPEND | O_CREAT,RW_ALL); + write(fd, (const char*)&sabuf, sizeof( sabuf )); +- close( fd); ++ sh_close( fd); + } + } + +--- src/cmd/ksh93/sh/streval.c ++++ src/cmd/ksh93/sh/streval.c 2013-10-25 13:26:45.749247290 +0000 +@@ -165,14 +165,11 @@ Sfdouble_t arith_exec(Arith_t *ep) + Math_f fun; + struct lval node; + Shell_t *shp = ep->shp; ++ memset(&node,0,sizeof(node)); + node.shp = shp; + node.emode = ep->emode; + node.expr = ep->expr; + node.elen = ep->elen; +- node.value = 0; +- node.nosub = 0; +- node.ptr = 0; +- node.eflag = 0; + if(level++ >=MAXLEVEL) + { + arith_error(e_recursive,ep->expr,ep->emode); +--- src/cmd/ksh93/sh/subshell.c ++++ src/cmd/ksh93/sh/subshell.c 2013-10-25 13:26:45.749247290 +0000 +@@ -122,23 +122,26 @@ void sh_subtmpfile(Shell_t *shp) + register struct checkpt *pp = (struct checkpt*)shp->jmplist; + register struct subshell *sp = subshell_data->pipe; + /* save file descriptor 1 if open */ +- if((sp->tmpfd = fd = fcntl(1,F_DUPFD,10)) >= 0) ++ if((sp->tmpfd = fd = sh_fcntl(1,F_DUPFD,10)) >= 0) + { ++ int err=errno; + fcntl(fd,F_SETFD,FD_CLOEXEC); + shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX; +- close(1); ++ while(close(1)<0 && errno==EINTR) ++ errno = err; + } + else if(errno!=EBADF) + errormsg(SH_DICT,ERROR_system(1),e_toomany); + /* popping a discipline forces a /tmp file create */ +- sfdisc(sfstdout,SF_POPDISC); ++ if(shp->comsub != 1) ++ sfdisc(sfstdout,SF_POPDISC); + if((fd=sffileno(sfstdout))<0) + { + /* unable to create the /tmp file so use a pipe */ + int fds[3]; + Sfoff_t off; + fds[2] = 0; +- sh_pipe(fds); ++ sh_rpipe(fds); + sp->pipefd = fds[0]; + sh_fcntl(sp->pipefd,F_SETFD,FD_CLOEXEC); + /* write the data to the pipe */ +@@ -180,7 +183,7 @@ void sh_subfork(void) + { + register struct subshell *sp = subshell_data; + Shell_t *shp = sp->shp; +- int curenv = shp->curenv; ++ int curenv = shp->curenv, comsub=shp->comsub; + pid_t pid; + char *trap = shp->st.trapcom[0]; + if(trap) +@@ -204,6 +207,7 @@ void sh_subfork(void) + { + /* this is the child part of the fork */ + /* setting subpid to 1 causes subshell to exit when reached */ ++ shp->cpid = 0; + sh_onstate(SH_FORKED); + sh_onstate(SH_NOLOG); + sh_offoption(SH_MONITOR); +@@ -213,7 +217,7 @@ void sh_subfork(void) + shp->comsub = 0; + SH_SUBSHELLNOD->nvalue.s = 0; + sp->subpid=0; +- shp->st.trapcom[0] = trap; ++ shp->st.trapcom[0] = (comsub==2?NULL:trap); + shp->savesig = 0; + } + } +@@ -337,7 +341,7 @@ static void nv_restore(struct subshell * + } + nv_setsize(mp,nv_size(np)); + if(!(flags&NV_MINIMAL)) +- mp->nvenv = np->nvenv; ++ mp->nvenv = nv_isnull(mp)?0:np->nvenv; + if(!nofree) + mp->nvfun = np->nvfun; + if(nv_isattr(np,NV_IDENT)) +@@ -494,6 +498,8 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + subenv = 0; + } + shp->curenv = ++subenv; ++ if(shp->curenv<=0) ++ shp->curenv = subenv = 1; + savst = shp->st; + sh_pushcontext(shp,&buff,SH_JMPSUB); + subshell = shp->subshell+1; +@@ -508,6 +514,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + sp->options = shp->options; + sp->jobs = job_subsave(); + sp->subdup = shp->subdup; ++ shp->subdup = 0; + #if SHOPT_COSHELL + sp->coshell = shp->coshell; + shp->coshell = 0; +@@ -530,7 +537,9 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + job.curpgid = 0; + sp->subshare = shp->subshare; + sp->comsub = shp->comsub; +- shp->subshare = comsub==2 || (comsub==1 && sh_isoption(SH_SUBSHARE)); ++ shp->subshare = comsub==2 || (comsub && sh_isoption(SH_SUBSHARE)); ++ if(!shp->subshare) ++ sp->pathlist = path_dup((Pathcomp_t*)shp->pathlist); + if(comsub) + shp->comsub = comsub; + if(!comsub || !shp->subshare) +@@ -604,7 +613,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + sp->tmpfd = -1; + sp->pipefd = -1; + /* use sftmp() file for standard output */ +- if(!(iop = sftmp(PIPE_BUF))) ++ if(!(iop = sftmp(comsub==1?PIPE_BUF:IOBSIZE))) + { + sfswap(sp->saveout,sfstdout); + errormsg(SH_DICT,ERROR_system(1),e_tmpcreate); +@@ -639,6 +648,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + sh_popcontext(shp,&buff); + if(shp->subshell==0) /* must be child process */ + { ++ shp->st.trapcom[0] = 0; + subshell_data = sp->prev; + if(jmpval==SH_JMPSCRIPT) + siglongjmp(*shp->jmplist,jmpval); +@@ -664,6 +674,19 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + } + else + { ++ if(comsub!=1 && shp->spid) ++ { ++ int c = shp->exitval; ++ job_wait(shp->spid); ++ if(shp->exitval==ERROR_NOENT) ++ { ++ shp->exitval = c; ++ shp->savexit=shp->exitval; ++ } ++ if(shp->pipepid==shp->spid) ++ shp->spid = 0; ++ shp->pipepid = 0; ++ } + /* move tmp file to iop and restore sfstdout */ + iop = sfswap(sfstdout,NIL(Sfio_t*)); + if(!iop) +@@ -690,19 +713,27 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + } + sfset(iop,SF_READ,1); + } +- sfswap(sp->saveout,sfstdout); ++ if(sp->saveout) ++ sfswap(sp->saveout,sfstdout); ++ else ++ sfstdout = &_Sfstdout; + /* check if standard output was preserved */ + if(sp->tmpfd>=0) + { +- close(1); ++ int err=errno; ++ while(close(1)<0 && errno==EINTR) ++ errno = err; + if (fcntl(sp->tmpfd,F_DUPFD,1) != 1) + duped++; + sh_close(sp->tmpfd); + } + shp->fdstatus[1] = sp->fdstatus; + } +- path_delete((Pathcomp_t*)shp->pathlist); +- shp->pathlist = (void*)sp->pathlist; ++ if(!shp->subshare) ++ { ++ path_delete((Pathcomp_t*)shp->pathlist); ++ shp->pathlist = (void*)sp->pathlist; ++ } + job_subrestore(sp->jobs); + shp->jobenv = savecurenv; + job.curpgid = savejobpgid; +@@ -764,8 +795,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + } + else + free((void*)sp->pwd); +- if(sp->pwdclose) +- close(sp->pwdfd); + if(sp->mask!=shp->mask) + umask(shp->mask=sp->mask); + if(shp->coutpipe!=sp->coutpipe) +@@ -777,8 +806,9 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + shp->cpipe[1] = sp->cpipe; + shp->coutpipe = sp->coutpipe; + } ++ if(sp->pwdclose) ++ close(sp->pwdfd); + shp->subshare = sp->subshare; +- shp->comsub = sp->comsub; + shp->subdup = sp->subdup; + #if SHOPT_COSHELL + shp->coshell = sp->coshell; +@@ -808,7 +838,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + if(nsig>0) + kill(getpid(),nsig); + if(sp->subpid) ++ { + job_wait(sp->subpid); ++ if(comsub>1) ++ sh_iounpipe(shp); ++ } ++ shp->comsub = sp->comsub; + if(comsub && iop && sp->pipefd<0) + sfseek(iop,(off_t)0,SEEK_SET); + if(shp->trapnote) +--- src/cmd/ksh93/sh/xec.c ++++ src/cmd/ksh93/sh/xec.c 2013-10-25 13:29:00.390826813 +0000 +@@ -102,26 +102,30 @@ struct funenv + * temp file. + */ + static int subpipe[3],subdup,tsetio,usepipe; +-static void iounpipe(Shell_t*); + + static int iousepipe(Shell_t *shp) + { +- int i; ++ int fd=sffileno(sfstdout),i,err=errno; + if(usepipe) + { + usepipe++; +- iounpipe(shp); ++ sh_iounpipe(shp); + } + if(sh_rpipe(subpipe) < 0) + return(0); + usepipe++; +- fcntl(subpipe[0],F_SETFD,FD_CLOEXEC); +- subpipe[2] = fcntl(1,F_DUPFD,10); +- fcntl(subpipe[2],F_SETFD,FD_CLOEXEC); ++ if(shp->comsub!=1) ++ { ++ subpipe[2] = sh_fcntl(subpipe[1],F_DUPFD,10); ++ sh_close(subpipe[1]); ++ return(1); ++ } ++ subpipe[2] = sh_fcntl(fd,F_dupfd_cloexec,10); + shp->fdstatus[subpipe[2]] = shp->fdstatus[1]; +- close(1); +- fcntl(subpipe[1],F_DUPFD,1); +- shp->fdstatus[1] = shp->fdstatus[subpipe[1]]; ++ while(close(fd)<0 && errno==EINTR) ++ errno = err; ++ fcntl(subpipe[1],F_DUPFD,fd); ++ shp->fdstatus[1] = shp->fdstatus[subpipe[1]]&~IOCLEX; + sh_close(subpipe[1]); + if(subdup=shp->subdup) for(i=0; i < 10; i++) + { +@@ -135,14 +139,23 @@ static int iousepipe(Shell_t *shp) + return(1); + } + +-static void iounpipe(Shell_t *shp) ++void sh_iounpipe(Shell_t *shp) + { +- int n; ++ int fd=sffileno(sfstdout),n,err=errno; + char buff[SF_BUFSIZE]; +- close(1); +- fcntl(subpipe[2], F_DUPFD, 1); +- shp->fdstatus[1] = shp->fdstatus[subpipe[2]]; ++ if(!usepipe) ++ return; + --usepipe; ++ if(shp->comsub>1) ++ { ++ sh_close(subpipe[2]); ++ while(read(subpipe[0],buff,sizeof(buff))>0); ++ goto done; ++ } ++ while(close(fd)<0 && errno==EINTR) ++ errno = err; ++ fcntl(subpipe[2], F_DUPFD, fd); ++ shp->fdstatus[1] = shp->fdstatus[subpipe[2]]; + if(subdup) for(n=0; n < 10; n++) + { + if(subdup&(1<var_tree,NV_IDENT|NV_NOADD); + while(csp) + { + if(strcmp(name,csp->name)==0) + { +- if(open) ++ if(xopen) + { + coattr(csp->coshell,argv[1]); + return((void*)csp); +@@ -771,7 +785,7 @@ static void *sh_coinit(Shell_t *shp,char + } + csp = csp->next; + } +- if(!open) ++ if(!xopen) + errormsg(SH_DICT,ERROR_exit(1),"%s: unknown namespace",name); + environ[0][2]=0; + csp = newof(0,struct cosh,1,strlen(name)+1); +@@ -898,13 +912,14 @@ static int sh_coexec(Shell_t *shp,const + #if SHOPT_FILESCAN + static Sfio_t *openstream(Shell_t *shp, struct ionod *iop, int *save) + { +- int savein, fd = sh_redirect(shp,iop,3); ++ int err=errno,savein, fd = sh_redirect(shp,iop,3); + Sfio_t *sp; + savein = dup(0); + if(fd==0) + fd = savein; + sp = sfnew(NULL,NULL,SF_UNBOUND,fd,SF_READ); +- close(0); ++ while(close(0)<0 && errno==EINTR) ++ errno = err; + open(e_devnull,O_RDONLY); + shp->offsets[0] = -1; + shp->offsets[1] = 0; +@@ -1434,7 +1449,11 @@ int sh_exec(register const Shnode_t *t, + stat(".",&stata); + /* restore directory changed */ + if(statb.st_ino!=stata.st_ino || statb.st_dev!=stata.st_dev) +- chdir(shp->pwd); ++ { ++ int err=errno; ++ while((chdir(shp->pwd) < 0) && errno==EINTR) ++ errno = err; ++ } + } + sh_offstate(SH_STOPOK); + if(share&SF_SHARE) +@@ -1570,7 +1589,7 @@ int sh_exec(register const Shnode_t *t, + unset_instance(nq,&node,&nr,mode); + sh_funstaks(slp->slchild,-1); + stakdelete(slp->slptr); +- if(jmpval > SH_JMPFUN) ++ if(jmpval > SH_JMPFUN || (io && jmpval>SH_JMPIO)) + siglongjmp(*shp->jmplist,jmpval); + goto setexit; + } +@@ -1597,10 +1616,14 @@ int sh_exec(register const Shnode_t *t, + if(shp->subshell) + { + sh_subtmpfile(shp); +- if(shp->comsub==1 && !(shp->fdstatus[1]&IONOSEEK)) +- unpipe=iousepipe(shp); + if((type&(FAMP|TFORK))==(FAMP|TFORK)) +- sh_subfork(); ++ { ++ if(shp->comsub && !(shp->fdstatus[1]&IONOSEEK)) ++ { ++ unpipe=iousepipe(shp); ++ sh_subfork(); ++ } ++ } + } + no_fork = !ntflag && !(type&(FAMP|FPOU)) && !shp->subshell && + !(shp->st.trapcom[SIGINT] && *shp->st.trapcom[SIGINT]) && +@@ -1676,7 +1699,7 @@ int sh_exec(register const Shnode_t *t, + if(parent<0) + { + if(shp->comsub==1 && usepipe && unpipe) +- iounpipe(shp); ++ sh_iounpipe(shp); + break; + } + #else +@@ -1693,7 +1716,7 @@ int sh_exec(register const Shnode_t *t, + if(parent<0) + { + if(shp->comsub==1 && usepipe && unpipe) +- iounpipe(shp); ++ sh_iounpipe(shp); + break; + } + #else +@@ -1715,6 +1738,8 @@ int sh_exec(register const Shnode_t *t, + nlock--; + job_unlock(); + } ++ if(shp->subshell) ++ shp->spid = parent; + if(type&FPCL) + sh_close(shp->inpipe[0]); + if(type&(FCOOP|FAMP)) +@@ -1730,11 +1755,15 @@ int sh_exec(register const Shnode_t *t, + if(shp->pipepid) + shp->pipepid = parent; + else ++ { + job_wait(parent); ++ if(parent==shp->spid) ++ shp->spid = 0; ++ } + if(shp->topfd > topfd) + sh_iorestore(shp,topfd,0); +- if(usepipe && tsetio && subdup && unpipe) +- iounpipe(shp); ++ if(usepipe && tsetio && subdup) ++ sh_iounpipe(shp); + if(!sh_isoption(SH_MONITOR)) + { + shp->trapnote &= ~SH_SIGIGNORE; +@@ -1906,8 +1935,8 @@ int sh_exec(register const Shnode_t *t, + { + was_interactive = sh_isstate(SH_INTERACTIVE); + sh_offstate(SH_INTERACTIVE); +- sh_iosave(shp,0,shp->topfd,(char*)0); + shp->pipepid = simple; ++ sh_iosave(shp,0,shp->topfd,(char*)0); + sh_iorenumber(shp,shp->inpipe[0],0); + /* + * if read end of pipe is a simple command +@@ -1924,7 +1953,7 @@ int sh_exec(register const Shnode_t *t, + jmpval = sigsetjmp(buffp->buff,0); + if(jmpval==0) + { +- if(shp->comsub==1) ++ if(shp->comsub) + tsetio = 1; + sh_redirect(shp,t->fork.forkio,execflg); + (t->fork.forktre)->tre.tretyp |= t->tre.tretyp&FSHOWME; +@@ -1953,8 +1982,8 @@ int sh_exec(register const Shnode_t *t, + if(type || !sh_isoption(SH_PIPEFAIL)) + shp->exitval = type; + } +- if(shp->comsub==1 && usepipe) +- iounpipe(shp); ++ if(shp->comsub==1 && usepipe && unpipe) ++ sh_iounpipe(shp); + shp->pipepid = 0; + shp->st.ioset = 0; + if(simple && was_errexit) +@@ -2179,7 +2208,7 @@ int sh_exec(register const Shnode_t *t, + } + shp->exitval = n; + #ifdef SIGTSTP +- if(!pipejob && sh_isstate(SH_MONITOR)) ++ if(!pipejob && sh_isstate(SH_MONITOR) && sh_isstate(SH_INTERACTIVE)) + tcsetpgrp(JOBTTY,shp->gd->pid); + #endif /*SIGTSTP */ + job.curpgid = savepgid; +@@ -2320,7 +2349,10 @@ int sh_exec(register const Shnode_t *t, + nv_putsub(np,NIL(char*),0L); + nv_putval(np,cp,0); + if(nameref) ++ { + nv_setref(np,(Dt_t*)0,NV_VARNAME); ++ nv_onattr(np,NV_TABLE); ++ } + if(trap=shp->st.trap[SH_DEBUGTRAP]) + { + av[0] = (t->tre.tretyp&COMSCAN)?"select":"for"; +@@ -2352,6 +2384,8 @@ int sh_exec(register const Shnode_t *t, + if(shp->st.breakcnt<0) + shp->st.execbrk = (++shp->st.breakcnt !=0); + } ++ if(nameref) ++ nv_offattr(np,NV_TABLE); + #if SHOPT_OPTIMIZE + endfor: + sh_popcontext(shp,buffp); +@@ -2466,8 +2500,10 @@ int sh_exec(register const Shnode_t *t, + #if SHOPT_FILESCAN + if(iop) + { ++ int err=errno; + sfclose(iop); +- close(0); ++ while(close(0)<0 && errno==EINTR) ++ errno = err; + dup(savein); + shp->cur_line = 0; + } +@@ -2746,7 +2782,7 @@ int sh_exec(register const Shnode_t *t, + stakdelete(slp->slptr); + if(rp->sdict) + { +- Namval_t *mp, *nq; ++ Namval_t *nq; + shp->last_root = rp->sdict; + for(mp=(Namval_t*)dtfirst(rp->sdict);mp;mp=nq) + { +@@ -2911,6 +2947,15 @@ int sh_exec(register const Shnode_t *t, + break; + } + } ++ if(shp->procsub && *shp->procsub) ++ { ++ pid_t pid, *procsub; ++ int exitval = shp->exitval; ++ for(procsub=shp->procsub;pid=*procsub;procsub++) ++ job_wait(pid); ++ *shp->procsub = 0; ++ shp->exitval = exitval; ++ } + if(shp->trapnote || (shp->exitval && sh_isstate(SH_ERREXIT)) && + t && echeck) + sh_chktrap(shp); +@@ -3167,7 +3212,7 @@ pid_t _sh_fork(Shell_t *shp,register pid + { + if(shp->topfd > restorefd) + sh_iorestore(shp,restorefd,0); +- iounpipe(shp); ++ sh_iounpipe(shp); + } + } + return(parent); +@@ -3479,8 +3524,7 @@ static void sh_funct(Shell_t *shp,Namval + struct funenv fun; + char *fname = nv_getval(SH_FUNNAMENOD); + struct Level *lp =(struct Level*)(SH_LEVELNOD->nvfun); +- int level, pipepid=shp->pipepid, comsub=shp->comsub; +- shp->comsub = 0; ++ int level, pipepid=shp->pipepid; + shp->pipepid = 0; + sh_stats(STAT_FUNCT); + if(!lp->hdr.disc) +@@ -3523,7 +3567,6 @@ static void sh_funct(Shell_t *shp,Namval + lp->maxlevel = level; + SH_LEVELNOD->nvalue.s = lp->maxlevel; + shp->last_root = nv_dict(DOTSHNOD); +- shp->comsub = comsub; + #if 0 + nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE); + #else +@@ -3628,11 +3671,11 @@ static void coproc_init(Shell_t *shp, in + sh_pipe(shp->cpipe); + if((outfd=shp->cpipe[1]) < 10) + { +- int fd=fcntl(shp->cpipe[1],F_DUPFD,10); ++ int fd=sh_fcntl(shp->cpipe[1],F_DUPFD,10); + if(fd>=10) + { + shp->fdstatus[fd] = (shp->fdstatus[outfd]&~IOCLEX); +- close(outfd); ++ sh_close(outfd); + shp->fdstatus[outfd] = IOCLOSE; + shp->cpipe[1] = fd; + } +@@ -3721,7 +3764,7 @@ static int run_subshell(Shell_t *shp,con + if(!shp->gd->shpath) + shp->gd->shpath = pathshell(); + pid = spawnveg(shp->shpath,arglist,envlist,grp); +- close(fd); ++ sh_close(fd); + for(i=3; i < 10; i++) + { + if(shp->fdstatus[i]&IOCLEX && i!=pin && i!=pout) +@@ -4002,7 +4045,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons + shp->gd->shpath = pathshell(); + spawnpid = path_spawn(shp,shp->gd->shpath,&argv[-1],arge,pp,(grp<<1)|1); + if(fd>=0) +- close(fd); ++ sh_close(fd); + argv[0] = argv[-1]; + } + fail: +--- src/cmd/ksh93/tests/leaks.sh ++++ src/cmd/ksh93/tests/leaks.sh 2013-10-25 13:26:45.751247106 +0000 +@@ -67,6 +67,11 @@ done + + data="(v=;sid=;di=;hi=;ti='1328244300';lv='o';id='172.3.161.178';var=(k='conn_num._total';u=;fr=;l='Number of Connections';n='22';t='number';))" + read -C stat <<< "$data" ++for ((i=0; i < 1; i++)) ++do print -r -- "$data" ++done | while read -u$n -C stat ++ do : ++ done {n}<&0- + a=0$(vmstate --format='+%(size)u') + for ((i=0; i < 500; i++)) + do print -r -- "$data" diff --git a/ksh93-filedefined.dif b/ksh93-filedefined.dif new file mode 100644 index 0000000..9f90bfe --- /dev/null +++ b/ksh93-filedefined.dif @@ -0,0 +1,35 @@ +--- ./src/lib/libast/features/stdio.orig 2017-12-20 12:15:45.571650029 +0000 ++++ ./src/lib/libast/features/stdio 2017-12-20 12:16:26.250531883 +0000 +@@ -6,6 +6,8 @@ cat{ + #define _FILE_DEFINED 1 + #define _FILE_defined 1 + #define _FILEDEFED 1 ++ #define __FILE_defined 1 ++ #define ____FILE_defined 1 + + #ifndef __FILE_TAG + #define __FILE_TAG _sfio_s +--- ./src/lib/libast/include/ast.h.orig 2017-12-20 12:16:37.212500201 +0000 ++++ ./src/lib/libast/include/ast.h 2017-12-20 12:17:25.635360669 +0000 +@@ -58,9 +58,21 @@ struct _sfio_s; + #ifndef __FILE_typedef + #define __FILE_typedef 1 + #endif ++#ifndef _FILE_DEFINED ++#define _FILE_DEFINED 1 ++#endif ++#ifndef _FILE_defined ++#define _FILE_defined 1 ++#endif + #ifndef _FILEDEFED + #define _FILEDEFED 1 + #endif ++#ifndef __FILE_defined ++#define __FILE_defined 1 ++#endif ++#ifndef ____FILE_defined ++#define ____FILE_defined 1 ++#endif + #endif + + /* diff --git a/ksh93-foreground-prgrp.dif b/ksh93-foreground-prgrp.dif new file mode 100644 index 0000000..3fb4d7a --- /dev/null +++ b/ksh93-foreground-prgrp.dif @@ -0,0 +1,13 @@ +--- src/cmd/ksh93/sh/jobs.c ++++ src/cmd/ksh93/sh/jobs.c 2012-02-08 10:52:14.000000000 +0000 +@@ -845,7 +845,9 @@ static void job_reset(register struct pr + { + /* save the terminal state for current job */ + #ifdef SIGTSTP +- job_fgrp(pw,tcgetpgrp(job.fd)); ++ pid_t tgrp; ++ if((tgrp=tcgetpgrp(job.fd))!=job.mypid) ++ job_fgrp(pw,tgrp); + if(tcsetpgrp(job.fd,job.mypid) !=0) + return; + #endif /* SIGTSTP */ diff --git a/ksh93-fs3d.dif b/ksh93-fs3d.dif new file mode 100644 index 0000000..cf90eb0 --- /dev/null +++ b/ksh93-fs3d.dif @@ -0,0 +1,62 @@ +--- ./src/lib/libast/misc/fs3d.c.orig 2014-11-11 12:09:50.142397030 +0000 ++++ ./src/lib/libast/misc/fs3d.c 2014-11-11 12:11:19.667992242 +0000 +@@ -39,6 +39,7 @@ + int + fs3d(register int op) + { ++#if SHOPT_FS_3D + register int cur; + register char* v; + char val[sizeof(FS3D_off) + 8]; +@@ -95,6 +96,7 @@ fs3d(register int op) + return cur; + nope: + fsview = -1; ++#endif + return 0; + } + +@@ -107,6 +109,7 @@ fs3d(register int op) + + #undef mount + ++#if SHOPT_FS_3D + extern int mount(const char*, char*, int, void*); + + int +@@ -114,3 +117,4 @@ fs3d_mount(const char* source, char* tar + { + return mount(source, target, flags, data); + } ++#endif +--- ./src/lib/libast/path/pathkey.c.orig 2014-11-11 12:11:29.333948438 +0000 ++++ ./src/lib/libast/path/pathkey.c 2014-11-11 12:11:47.067868209 +0000 +@@ -109,8 +109,10 @@ pathkey_20100601(const char* lang, const + * 3D + */ + ++#if SHOPT_FS_3D + if (!flags && fs3d(FS3D_TEST) && (c = mount(path, tmp, FS3D_GET|FS3D_ALL|FS3D_SIZE(PATH_MAX), NiL)) > 1 && c < PATH_MAX) + path = tmp; ++#endif + + /* + * preroot +--- ./src/lib/libcoshell/coinit.c.orig 2014-11-11 12:08:49.438671153 +0000 ++++ ./src/lib/libcoshell/coinit.c 2014-11-11 12:09:25.956506292 +0000 +@@ -355,6 +355,7 @@ coinitialize(Coshell_t* co, int flags) + p = (int)sfstrtell(sp); + sfprintf(sp, "vpath "); + n = PATH_MAX; ++#if SHOPT_FS_3D + if (fs3d(FS3D_TEST)) + for (;;) + { +@@ -370,6 +371,7 @@ coinitialize(Coshell_t* co, int flags) + } + } + else ++#endif + { + m = 0; + sfprintf(sp, "- /#option/2d"); diff --git a/ksh93-gcc.dif b/ksh93-gcc.dif new file mode 100644 index 0000000..2c948eb --- /dev/null +++ b/ksh93-gcc.dif @@ -0,0 +1,65 @@ +--- src/lib/libast/misc/optget.c ++++ src/lib/libast/misc/optget.c 2013-01-28 14:52:53.000000000 +0000 +@@ -4367,9 +4367,9 @@ optget(register char** argv, const char* + */ + + opt_info.assignment = 0; +- num = 1; +- w = v = 0; +- x = 0; ++ nov = no = num = 1; ++ e = w = v = 0; ++ n = x = 0; + for (;;) + { + if (!opt_info.offset) +@@ -5214,7 +5214,7 @@ optget(register char** argv, const char* + + if (opt_info.num != LONG_MIN) + opt_info.num = (long)(opt_info.number = num); +- if ((n = *++s == '#') || *s == ':' || w && !nov && v && (optnumber(v, &e, NiL), n = !*e)) ++ if ((n = (*++s == '#')) || *s == ':' || w && !nov && v && (optnumber(v, &e, NiL), n = !*e)) + { + if (w) + { +--- src/lib/libpp/ppsearch.c ++++ src/lib/libpp/ppsearch.c 2012-03-14 11:40:11.000000000 +0000 +@@ -107,6 +107,14 @@ ppmultiple(register struct ppfile* fp, r + * search for file using directories in dp + */ + ++#define stupidgcc(flag) \ ++({ \ ++ char *name = NiL; \ ++ if (!(fp->flags & INC_MEMBER(flag)) && (xp = fp->bound[flag])) \ ++ name = xp->name; \ ++ name; \ ++}) ++ + static int + search(register struct ppfile* fp, register struct ppdirs* dp, int type, int flags) + { +@@ -146,10 +154,10 @@ search(register struct ppfile* fp, regis + (fp->flags & INC_BOUND(INC_STANDARD)) ? "STANDARD|" : "", + dp ? (dp->index == INC_PREFIX ? "pre" : dp->index == INC_LOCAL ? "lcl" : dp->index == INC_VENDOR ? "vnd" : "std") : NiL, + dp ? dp->name : NiL, +- !(fp->flags & INC_MEMBER(INC_PREFIX)) && fp->bound[INC_PREFIX] ? fp->bound[INC_PREFIX]->name : NiL, +- !(fp->flags & INC_MEMBER(INC_LOCAL)) && fp->bound[INC_LOCAL] ? fp->bound[INC_LOCAL]->name : NiL, +- !(fp->flags & INC_MEMBER(INC_VENDOR)) && fp->bound[INC_VENDOR] ? fp->bound[INC_VENDOR]->name : NiL, +- !(fp->flags & INC_MEMBER(INC_STANDARD)) && (xp = fp->bound[INC_STANDARD]) ? xp->name : NiL, ++ stupidgcc(INC_PREFIX), ++ stupidgcc(INC_LOCAL), ++ stupidgcc(INC_VENDOR), ++ stupidgcc(INC_STANDARD), + error_info.file + )); + if (flags & SEARCH_HOSTED) +@@ -578,6 +586,8 @@ if (pp.test & 0x0010) error(1, "SEARCH#% + return -1; + } + ++#undef stupidgcc ++ + /* + * search for an include file + * if (flags&SEARCH_INCLUDE) then diff --git a/ksh93-gmt2utc.dif b/ksh93-gmt2utc.dif new file mode 100644 index 0000000..e67b5c4 --- /dev/null +++ b/ksh93-gmt2utc.dif @@ -0,0 +1,70 @@ +--- src/lib/libast/man/tm.3 ++++ src/lib/libast/man/tm.3 2006-04-19 15:55:42.000000000 +0000 +@@ -70,7 +70,7 @@ are used to determine local time zone an + .PP + .L time_t + values are the number of seconds since the epoch, +-.BR "Jan 1 00:00:00 GMT 1970" , ++.BR "Jan 1 00:00:00 UTC 1970" , + with leap seconds omitted. + .PP + The global variable +@@ -433,7 +433,7 @@ that includes the hours and minutes. + .B z + Time zone + .I SHHMM +-west of GMT offset where ++west of UTC offset where + .I S + is + .B + +@@ -614,7 +614,7 @@ Meridian names: AM, PM. + .TP + .B 43-46 + .B UTC +-time zone names: GMT, UTC, UCT, CUT. ++time zone names: UTC, GMT, UCT, CUT. + .TP + .B 47-50 + Daylight savings time suffix names: DST. +--- src/lib/libast/man/tmx.3 ++++ src/lib/libast/man/tmx.3 2006-04-19 15:54:55.000000000 +0000 +@@ -59,7 +59,7 @@ are used to determine local time zone in + .PP + .L time_t + values are the number of seconds since the epoch, +-.BR "Jan 1 00:00:00 GMT 1970" , ++.BR "Jan 1 00:00:00 UTC 1970" , + with leap seconds omitted. + .PP + The global variable +@@ -492,7 +492,7 @@ Meridian names: AM, PM. + .TP + .B 43-46 + .B UTC +-time zone names: GMT, UTC, UCT, CUT. ++time zone names: UTC, GMT, UCT, CUT. + .TP + .B 47-50 + Daylight savings time suffix names: DST. +--- src/lib/libast/tm/tmdata.c ++++ src/lib/libast/tm/tmdata.c 2006-04-19 15:52:53.000000000 +0000 +@@ -54,7 +54,7 @@ static char* format[] = + + "AM", "PM", + +- "GMT", "UTC", "UCT", "CUT", ++ "UTC", "GMT", "UCT", "CUT", + + "DST", "", "", "", + +@@ -230,8 +230,8 @@ static Tm_leap_t leap[] = + + static Tm_zone_t zone[] = + { +- 0, "GMT", 0, ( 0 * 60), 0, /* UTC */ + 0, "UCT", 0, ( 0 * 60), 0, /* UTC */ ++ 0, "GMT", 0, ( 0 * 60), 0, /* UTC */ + 0, "UTC", 0, ( 0 * 60), 0, /* UTC */ + 0, "CUT", 0, ( 0 * 60), 0, /* UTC */ + 0, "Z", 0, ( 0 * 60), 0, /* UTC */ diff --git a/ksh93-heredoc.dif b/ksh93-heredoc.dif new file mode 100644 index 0000000..2774d4f --- /dev/null +++ b/ksh93-heredoc.dif @@ -0,0 +1,11 @@ +--- src/cmd/ksh93/sh/lex.c ++++ src/cmd/ksh93/sh/lex.c 2012-01-16 15:09:38.000000000 +0000 +@@ -1893,6 +1893,8 @@ static int here_copy(Lex_t *lp,register + sfputc(sp,'\\'); + } + } ++ if (LEN < 1) ++ LEN = 1; + bufp = fcseek(-LEN); + } + else diff --git a/ksh93-heredoclex.dif b/ksh93-heredoclex.dif new file mode 100644 index 0000000..aac8be7 --- /dev/null +++ b/ksh93-heredoclex.dif @@ -0,0 +1,19 @@ +--- src/cmd/ksh93/sh/lex.c ++++ src/cmd/ksh93/sh/lex.c 2013-02-26 12:21:11.618820739 +0100 +@@ -1559,6 +1559,7 @@ static int comsub(register Lex_t *lp, in + register int line=lp->sh->inlineno; + char *first,*cp=fcseek(0),word[5]; + int off, messages=0, assignok=lp->assignok, csub; ++ struct ionod *inheredoc = lp->heredoc; + struct lexstate save; + save = lp->lex; + csub = lp->comsub; +@@ -1683,7 +1684,7 @@ done: + lp->lexd.dolparen--; + lp->lex = save; + lp->assignok = (endchar(lp)==RBRACT?assignok:0); +- if(lp->heredoc) ++ if(lp->heredoc && !inheredoc) + errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax5,lp->sh->inlineno,lp->heredoc->ioname); + return(messages); + } diff --git a/ksh93-ia64.dif b/ksh93-ia64.dif new file mode 100644 index 0000000..897b8f3 --- /dev/null +++ b/ksh93-ia64.dif @@ -0,0 +1,40 @@ +--- src/cmd/ksh93/features/math.sh ++++ src/cmd/ksh93/features/math.sh 2012-01-20 14:23:38.000000000 +0000 +@@ -130,6 +130,18 @@ echo "#include " + case $_hdr_ieeefp in + 1) echo "#include " ;; + esac ++cat <= 4 ++# define __signbitl(f) __builtin_signbitl(f) ++# else ++# include ++# if _lib_copysignl ++# define __signbitl(f) (int)(copysignl(1.0,(f))<0.0) ++# endif ++# endif ++#endif ++! + echo + + : generate the intercept functions and table entries +--- src/lib/libast/sfio/sfcvt.c ++++ src/lib/libast/sfio/sfcvt.c 2013-02-01 17:13:48.305452072 +0000 +@@ -54,6 +54,16 @@ static char *Zero = "0"; + #endif + #endif + ++#if defined(__ia64__) && defined(signbit) ++# if defined __GNUC__ && __GNUC__ >= 4 ++# define __signbitl(f) __builtin_signbitl(f) ++# else ++# if _lib_copysignl ++# define __signbitl(f) (int)(copysignl(1.0,(f))<0.0) ++# endif ++# endif ++#endif ++ + #if !_lib_signbit + #if !_ast_fltmax_double + static int neg0ld(Sfdouble_t f) diff --git a/ksh93-int16double.dif b/ksh93-int16double.dif new file mode 100644 index 0000000..5f1628f --- /dev/null +++ b/ksh93-int16double.dif @@ -0,0 +1,22 @@ +--- src/cmd/ksh93/sh/array.c.orig 2015-04-01 11:26:36.544797902 +0000 ++++ src/cmd/ksh93/sh/array.c 2015-04-01 11:27:01.414692760 +0000 +@@ -592,7 +592,7 @@ static char *array_getval(Namval_t *np, + return(cp); + } + #if SHOPT_FIXEDARRAY +- if(ap->fixed && nv_isattr(np,NV_INT16P) == NV_INT16) ++ if(ap->fixed && nv_isattr(np,NV_INT16P|NV_DOUBLE) == NV_INT16) + np->nvalue.s = *np->nvalue.sp; + #endif /* SHOPT_FIXEDARRAY */ + return(nv_getv(np,&ap->hdr)); +--- src/cmd/ksh93/sh/name.c.orig 2015-04-01 11:25:38.049045236 +0000 ++++ src/cmd/ksh93/sh/name.c 2015-04-01 11:25:55.169972879 +0000 +@@ -1647,7 +1647,7 @@ void nv_putval(register Namval_t *np, co + return; + } + up= &np->nvalue; +- if(nv_isattr(np,NV_INT16P) == NV_INT16) ++ if(nv_isattr(np,NV_INT16P|NV_DOUBLE) == NV_INT16) + { + if(!np->nvalue.up || !nv_isarray(np)) + { diff --git a/ksh93-joblock.dif b/ksh93-joblock.dif new file mode 100644 index 0000000..0c3bba6 --- /dev/null +++ b/ksh93-joblock.dif @@ -0,0 +1,31 @@ +--- ./src/cmd/ksh93/include/jobs.h.orig 2014-11-19 14:14:36.055335722 +0000 ++++ ./src/cmd/ksh93/include/jobs.h 2014-11-19 14:16:12.275918218 +0000 +@@ -33,6 +33,7 @@ + # include + #endif /* !SIGINT */ + #include "FEATURE/options" ++#include + + #if SHOPT_COSHELL + # include +@@ -150,16 +151,13 @@ extern struct jobs job; + #define vmbusy() 0 + #endif + +-#define job_lock() (job.in_critical++) ++#define job_lock() asoincint(&job.in_critical) + #define job_unlock() \ + do { \ + int _sig; \ +- if (!--job.in_critical && (_sig = job.savesig)) \ +- { \ +- if (!job.in_critical++ && !vmbusy()) \ +- job_reap(_sig); \ +- job.in_critical--; \ +- } \ ++ if (asogetint(&job.in_critical) == 1 && (_sig = job.savesig) && !vmbusy()) \ ++ job_reap(_sig); \ ++ asodecint(&job.in_critical); \ + } while(0) + + extern const char e_jobusage[]; diff --git a/ksh93-jobs.dif b/ksh93-jobs.dif new file mode 100644 index 0000000..eb8d246 --- /dev/null +++ b/ksh93-jobs.dif @@ -0,0 +1,35 @@ +--- src/cmd/ksh93/sh/jobs.c ++++ src/cmd/ksh93/sh/jobs.c 2012-12-20 13:33:28.000000000 +0000 +@@ -638,12 +638,14 @@ void job_init(Shell_t *shp, int lflag) + /* This should have already been done by rlogin */ + register int fd; + register char *ttynam; ++ int err = errno; + #ifndef SIGTSTP + setpgid(0,shp->gd->pid); + #endif /*SIGTSTP */ + if(job.mypgid<0 || !(ttynam=ttyname(JOBTTY))) + return; +- close(JOBTTY); ++ while(close(JOBTTY)<0 && errno==EINTR) ++ errno = err; + if((fd = open(ttynam,O_RDWR)) <0) + return; + if(fd!=JOBTTY) +@@ -1110,7 +1112,7 @@ static struct process *job_bystring(regi + + int job_kill(register struct process *pw,register int sig) + { +- Shell_t *shp = pw->p_shp; ++ Shell_t *shp; + register pid_t pid; + register int r; + const char *msg; +@@ -1123,6 +1125,7 @@ int job_kill(register struct process *pw + errno = ECHILD; + if(pw==0) + goto error; ++ shp = pw->p_shp; + pid = pw->p_pid; + #if SHOPT_COSHELL + if(pw->p_cojob) diff --git a/ksh93-jpold.dif b/ksh93-jpold.dif new file mode 100644 index 0000000..1f8be72 --- /dev/null +++ b/ksh93-jpold.dif @@ -0,0 +1,10 @@ +--- src/cmd/ksh93/sh/jobs.c.orig 2015-09-15 15:56:08.902265877 +0000 ++++ src/cmd/ksh93/sh/jobs.c 2015-09-15 15:57:00.866122451 +0000 +@@ -1981,6 +1981,7 @@ again: + { + count = bp->count; + jp = bp->list; ++ jpold = 0; + goto again; + } + if(jp) diff --git a/ksh93-limit-name-len.dif b/ksh93-limit-name-len.dif new file mode 100644 index 0000000..ceec301 --- /dev/null +++ b/ksh93-limit-name-len.dif @@ -0,0 +1,31 @@ +--- src/cmd/ksh93/include/ulimit.h ++++ src/cmd/ksh93/include/ulimit.h 2012-02-02 11:30:00.242435132 +0000 +@@ -157,7 +157,7 @@ + + typedef struct Limit_s + { +- const char name[16]; ++ const char* name; + const char* description; + int index; + const char* conf; +--- src/cmd/ksh93/sh/init.c ++++ src/cmd/ksh93/sh/init.c 2013-02-01 15:53:58.733952540 +0000 +@@ -170,7 +170,7 @@ struct match + char *val; + char *rval[2]; + regoff_t *match; +- char node[NV_MINSZ+sizeof(char*)]; ++ char node[NV_MINSZ+sizeof(char*)+sizeof(Dtlink_t)]; + regoff_t first; + int vsize; + int nmatch; +@@ -766,7 +766,7 @@ static int hasgetdisc(register Namfun_t + void sh_setmatch(Shell_t *shp,const char *v, int vsize, int nmatch, regoff_t match[],int index) + { + struct match *mp = &ip->SH_MATCH_init; +- Namval_t *np = nv_namptr(mp->node,0); ++ Namval_t *np = (Namval_t*)(&(mp->node[0])); + register int i,n,x, savesub=shp->subshell; + Namarr_t *ap = nv_arrayptr(SH_MATCHNOD); + shp->subshell = 0; diff --git a/ksh93-limits.dif b/ksh93-limits.dif new file mode 100644 index 0000000..052fe4d --- /dev/null +++ b/ksh93-limits.dif @@ -0,0 +1,122 @@ +--- src/lib/libast/comp/conf.sh ++++ src/lib/libast/comp/conf.sh 2010-08-17 15:45:16.000000000 +0000 +@@ -143,7 +143,7 @@ main() + return 1; + #else + _ast_intmax_t s = 0x7fffffffffffffffLL; +- unsigned _ast_intmax_t u = 0xffffffffffffffffLL; ++ unsigned _ast_intmax_t u = 0xffffffffffffffffULL; + + return 0; + #endif +@@ -801,7 +801,11 @@ defined() # list-file + cat < ++#include + #include ++#if defined(__linux__) ++#include ++#endif + #include $systeminfo$headers + ${tail} + #undef conf +@@ -829,7 +833,11 @@ unsigned int conf[] = { + cat < ++#include + #include ++#if defined(__linux__) ++#include ++#endif + #include $systeminfo$headers + ${tail} + #undef conf +@@ -870,7 +878,11 @@ done + cat < ++#include + #include ++#if defined(__linux__) ++#include ++#endif + #include $systeminfo$headers + ${tail} + #undef conf +@@ -1048,7 +1060,7 @@ do eval name=\"'$'CONF_name_$key\" + case $flags in + *[Ll]*) d= + case ${conf_name} in +- LONG_MAX|SSIZE_MAX) ++ LONG_MAX|UINT_MAX|INT_MAX|SHRT_MAX|SSIZE_MAX|WORD_BIT|LONG_BIT|PTHREAD_*) + x= + ;; + *) eval x='$'CONF_const_${conf_name} +@@ -1108,7 +1120,11 @@ do eval name=\"'$'CONF_name_$key\" + ${head} + #include + #include ++#include + #include ++#if defined(__linux__) ++#include ++#endif + #include $systeminfo$headers + ${tail} + int +@@ -1123,7 +1139,11 @@ main() + ${head} + #include + #include ++#include + #include ++#if defined(__linux__) ++#include ++#endif + #include $systeminfo$headers + ${tail} + ${script} +@@ -1270,7 +1290,11 @@ printf("#endif\n"); + *) cat > $tmp.c < ++#include + #include ++#if defined(__linux__) ++#include ++#endif + #include $systeminfo$headers + ${tail} + ${script} +@@ -1349,7 +1373,7 @@ ${script} + *[lLuU]) + case $LL_suffix in + ??) case $conf_limit in +- *[!lL][lL]|*[!lL][lL][uU]) ++ *[0-9a-fA-F][lL]|*[0-9a-fA-F][uU][lL]) + conf_limit=${conf_limit}L + ;; + esac +@@ -1384,7 +1408,7 @@ ${script} + *[lLuU]) + case $LL_suffix in + ??) case $conf_minmax in +- *[!lL][lL]|*[!lL][lL][uU]) ++ *[0-9a-fA-F][lL]|*[0-9a-fA-F][uU][lL]) + conf_minmax=${conf_minmax}L + ;; + esac +@@ -1561,7 +1585,11 @@ esac + cat < ++#include + #include ++#if defined(__linux__) ++#include ++#endif + #include $systeminfo$headers + ${tail} + #include "${base}.h" diff --git a/ksh93-longenv.dif b/ksh93-longenv.dif new file mode 100644 index 0000000..5d0a76a --- /dev/null +++ b/ksh93-longenv.dif @@ -0,0 +1,65 @@ +--- ./src/cmd/ksh93/include/defs.h.orig 2014-11-13 16:34:43.395195739 +0000 ++++ ./src/cmd/ksh93/include/defs.h 2014-11-13 16:38:37.944297333 +0000 +@@ -162,8 +162,8 @@ struct shared + Namval_t *prev_table; /* previous table used in nv_open */ \ + Sfio_t *outpool; /* ouput stream pool */ \ + long timeout; /* read timeout */ \ +- short curenv; /* current subshell number */ \ +- short jobenv; /* subshell number for jobs */ \ ++ long curenv; /* current subshell number */ \ ++ long jobenv; /* subshell number for jobs */ \ + int infd; /* input file descriptor */ \ + short nextprompt; /* next prompt is PS */ \ + short poolfiles; \ +--- ./src/cmd/ksh93/include/jobs.h.orig 2014-11-13 16:35:10.331086826 +0000 ++++ ./src/cmd/ksh93/include/jobs.h 2014-11-13 16:38:53.856235814 +0000 +@@ -87,7 +87,7 @@ struct process + unsigned short p_exit; /* exit value or signal number */ + unsigned short p_exitmin; /* minimum exit value for xargs */ + unsigned short p_flag; /* flags - see below */ +- int p_env; /* subshell environment number */ ++ long p_env; /* subshell environment number */ + #ifdef JOBS + off_t p_name; /* history file offset for command */ + struct termios p_stty; /* terminal state for job */ +--- ./src/cmd/ksh93/sh/jobs.c.orig 2014-11-13 16:36:02.050894977 +0000 ++++ ./src/cmd/ksh93/sh/jobs.c 2014-11-13 16:37:09.568636499 +0000 +@@ -1815,7 +1815,7 @@ static struct process *job_unpost(regist + register struct process *pw; + /* make sure all processes are done */ + #ifdef DEBUG +- sfprintf(sfstderr,"ksh: job line %4d: drop pid=%d critical=%d pid=%d env=%d\n",__LINE__,getpid(),job.in_critical,pwtop->p_pid,pwtop->p_env); ++ sfprintf(sfstderr,"ksh: job line %4d: drop pid=%d critical=%d pid=%d env=%ld\n",__LINE__,getpid(),job.in_critical,pwtop->p_pid,pwtop->p_env); + sfsync(sfstderr); + #endif /* DEBUG */ + pwtop = pw = job_byjid((int)pwtop->p_job); +--- ./src/cmd/ksh93/sh/subshell.c.orig 2014-11-13 16:34:53.259157199 +0000 ++++ ./src/cmd/ksh93/sh/subshell.c 2014-11-13 16:38:11.440395221 +0000 +@@ -107,7 +107,7 @@ static struct subshell + #endif /* SHOPT_COSHELL */ + } *subshell_data; + +-static int subenv; ++static long subenv; + + + /* +@@ -183,7 +183,8 @@ void sh_subfork(void) + { + register struct subshell *sp = subshell_data; + Shell_t *shp = sp->shp; +- int curenv = shp->curenv, comsub=shp->comsub; ++ long curenv = shp->curenv; ++ int comsub=shp->comsub; + pid_t pid; + char *trap = shp->st.trapcom[0]; + if(trap) +@@ -476,7 +477,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + struct subshell sub_data; + register struct subshell *sp = &sub_data; + int jmpval,nsig=0,duped=0; +- int savecurenv = shp->curenv; ++ long savecurenv = shp->curenv; + int savejobpgid = job.curpgid; + int *saveexitval = job.exitval; + int16_t subshell; diff --git a/ksh93-malloc-hook.dif b/ksh93-malloc-hook.dif new file mode 100644 index 0000000..e6f827d --- /dev/null +++ b/ksh93-malloc-hook.dif @@ -0,0 +1,15 @@ +--- ./src/lib/libast/vmalloc/malloc.c.orig 2014-11-19 11:51:06.992595039 +0000 ++++ ./src/lib/libast/vmalloc/malloc.c 2014-11-19 12:00:22.713076989 +0000 +@@ -1070,12 +1070,8 @@ extern Void_t* F1(_ast_valloc, size_t,n) + + #if !_UWIN + +-#if !_malloc_hook +- + #include + +-#endif +- + typedef struct mallinfo Mallinfo_t; + typedef struct mstats Mstats_t; + diff --git a/ksh93-no-posix_spawn.dif b/ksh93-no-posix_spawn.dif new file mode 100644 index 0000000..5432aea --- /dev/null +++ b/ksh93-no-posix_spawn.dif @@ -0,0 +1,11 @@ +--- src/lib/libast/features/lib.orig 2024-05-13 14:35:41.921554657 +0000 ++++ src/lib/libast/features/lib 2024-05-13 14:36:15.401506572 +0000 +@@ -266,6 +266,8 @@ tst lib_posix_spawn unistd.h stdlib.h sp + int status; + char* cmd[3]; + char tmp[1024]; ++ NOTE("posix_spawn() DISABLED"); ++ _exit(0); + if (argv[1]) + _exit(signal(SIGHUP, SIG_DFL) != SIG_IGN); + signal(SIGHUP, SIG_IGN); diff --git a/ksh93-no-sysctl.dif b/ksh93-no-sysctl.dif new file mode 100644 index 0000000..7053d2d --- /dev/null +++ b/ksh93-no-sysctl.dif @@ -0,0 +1,13 @@ +--- ./src/lib/libcmd/uname.c.orig 2020-11-13 13:08:48.136513672 +0000 ++++ ./src/lib/libcmd/uname.c 2020-11-13 13:09:03.356469649 +0000 +@@ -90,10 +90,6 @@ __STDPP__directive pragma pp:hide getdom + # include + #endif + +-#ifdef __linux__ +-# include +-#endif +- + #if defined(__STDPP__directive) && defined(__STDPP__hide) + __STDPP__directive pragma pp:nohide getdomainname gethostid gethostname sethostname + #else diff --git a/ksh93-nvtree-free.dif b/ksh93-nvtree-free.dif new file mode 100644 index 0000000..47d9d5e --- /dev/null +++ b/ksh93-nvtree-free.dif @@ -0,0 +1,11 @@ +--- src/cmd/ksh93/sh/nvtree.c.orig 2015-03-17 16:00:01.111718083 +0000 ++++ src/cmd/ksh93/sh/nvtree.c 2015-03-17 16:00:31.560586300 +0000 +@@ -1152,6 +1152,8 @@ static void put_tree(register Namval_t * + nv_putv(np, val, flags,fp); + if(val && nv_isattr(np,(NV_INTEGER|NV_BINARY))) + return; ++ if (!val && !np->nvfun) ++ return; + if(ap= nv_arrayptr(np)) + nleft = array_elem(ap); + if(nleft==0) diff --git a/ksh93-optimizeleak.dif b/ksh93-optimizeleak.dif new file mode 100644 index 0000000..8d1ec63 --- /dev/null +++ b/ksh93-optimizeleak.dif @@ -0,0 +1,15 @@ +--- ./src/cmd/ksh93/sh/name.c.orig 2016-06-01 13:09:29.754690694 +0000 ++++ ./src/cmd/ksh93/sh/name.c 2016-06-01 13:09:53.348690652 +0000 +@@ -2726,6 +2726,12 @@ void nv_optimize(Namval_t *np) + } + if((xp= (struct optimize*)fp) && xp->ptr==shp->argaddr) + return; ++ if (xp && xp->next) { ++ register struct optimize *xpn; ++ for (xpn = xp->next; xpn; xpn = xpn->next) ++ if (xpn->ptr == shp->argaddr && xpn->np == np) ++ return; ++ } + if(op = opt_free) + opt_free = op->next; + else diff --git a/ksh93-path-skip.dif b/ksh93-path-skip.dif new file mode 100644 index 0000000..8c11cd4 --- /dev/null +++ b/ksh93-path-skip.dif @@ -0,0 +1,13 @@ +--- ./src/cmd/ksh93/sh/path.c.orig 2014-10-09 15:50:51.198269322 +0000 ++++ ./src/cmd/ksh93/sh/path.c 2014-10-09 15:51:16.351159405 +0000 +@@ -517,8 +517,8 @@ static int path_opentype(Shell_t *shp,co + do + { + pp = path_nextcomp(shp,oldpp=pp,name,0); +- while(oldpp && (oldpp->flags&PATH_SKIP)) +- oldpp = oldpp->next; ++ if (oldpp && (oldpp->flags&PATH_SKIP)) ++ continue; + if(fun && (!oldpp || !(oldpp->flags&PATH_FPATH))) + continue; + if((fd = sh_open(path_relative(shp,stakptr(PATH_OFFSET)),O_RDONLY,0)) >= 0) diff --git a/ksh93-pathtemp.dif b/ksh93-pathtemp.dif new file mode 100644 index 0000000..aaef2e7 --- /dev/null +++ b/ksh93-pathtemp.dif @@ -0,0 +1,114 @@ +--- src/lib/libast/path/pathtemp.c ++++ src/lib/libast/path/pathtemp.c 2012-10-25 10:35:14.510345073 +0000 +@@ -73,15 +73,49 @@ + #include + #include + #include ++#include + + #define ATTEMPT 10 + + #define TMP_ENV "TMPDIR" + #define TMP_PATH_ENV "TMPPATH" + #define TMP1 "/tmp" +-#define TMP2 "/usr/tmp" ++#define TMP2 "/var/tmp" + +-#define VALID(d) (*(d)&&!eaccess(d,W_OK|X_OK)) ++static inline int xaccess(const char *path, int mode) ++{ ++ static size_t pgsz; ++ struct statvfs vfs; ++ int ret; ++ ++ if (!pgsz) ++ pgsz = strtoul(astconf("PAGESIZE",NiL,NiL),NiL,0); ++ ++ if (!path || !*path) ++ { ++ errno = EFAULT; ++ goto err; ++ } ++ ++ do ++ ret = statvfs(path, &vfs); ++ while (ret < 0 && errno == EINTR); ++ ++ if (ret < 0) ++ goto err; ++ ++ if (vfs.f_frsize*vfs.f_bavail < pgsz) ++ { ++ errno = ENOSPC; ++ goto err; ++ } ++ ++ return eaccess(path, mode); ++err: ++ return -1; ++} ++ ++#define VALID(d) (*(d)&&!xaccess(d,W_OK|X_OK)) + + static struct + { +@@ -182,7 +216,7 @@ pathtemp(char* buf, size_t len, const ch + tv.tv_nsec = 0; + else + tvgettime(&tv); +- if (!(d = (char*)dir) || *d && eaccess(d, W_OK|X_OK)) ++ if (!(d = (char*)dir) || (*d && xaccess(d, W_OK|X_OK))) + { + if (!tmp.vec) + { +@@ -227,7 +261,7 @@ pathtemp(char* buf, size_t len, const ch + tmp.dir = tmp.vec; + d = *tmp.dir++; + } +- if (!d && (!*(d = astconf("TMP", NiL, NiL)) || eaccess(d, W_OK|X_OK)) && eaccess(d = TMP1, W_OK|X_OK) && eaccess(d = TMP2, W_OK|X_OK)) ++ if (!d && (!*(d = astconf("TMP", NiL, NiL)) || xaccess(d, W_OK|X_OK)) && xaccess(d = TMP1, W_OK|X_OK) && xaccess(d = TMP2, W_OK|X_OK)) + return 0; + } + if (!len) +--- src/lib/libast/sfio/sftmp.c ++++ src/lib/libast/sfio/sftmp.c 2012-10-25 12:09:18.026344912 +0000 +@@ -20,6 +20,14 @@ + * * + ***********************************************************************/ + #include "sfhdr.h" ++#if _PACKAGE_ast ++# if defined(__linux__) && _lib_statfs ++# include ++# ifndef TMPFS_MAGIC ++# define TMPFS_MAGIC 0x01021994 ++# endif ++# endif ++#endif + + /* Create a temporary stream for read/write. + ** The stream is originally created as a memory-resident stream. +@@ -207,7 +215,24 @@ Sfio_t* f; + int fd; + + #if _PACKAGE_ast ++# if defined(__linux__) && _lib_statfs ++ /* ++ * Use the area of POSIX shared memory objects for the new temporary file descriptor ++ * that is do not access HD or SSD but only the memory based tmpfs of the POSIX SHM ++ */ ++ static int doshm; ++ static char *shm = "/dev/shm"; ++ if (!doshm) ++ { ++ struct statfs fs; ++ if (statfs(shm, &fs) < 0 || fs.f_type != TMPFS_MAGIC || eaccess(shm, W_OK|X_OK)) ++ shm = NiL; ++ doshm++; ++ } ++ if(!(file = pathtemp(NiL,PATH_MAX,shm,"sf",&fd))) ++# else + if(!(file = pathtemp(NiL,PATH_MAX,NiL,"sf",&fd))) ++# endif + return -1; + _rmtmp(f, file); + free(file); diff --git a/ksh93-profile.dif b/ksh93-profile.dif new file mode 100644 index 0000000..ff6e295 --- /dev/null +++ b/ksh93-profile.dif @@ -0,0 +1,64 @@ +--- src/cmd/ksh93/sh/main.c ++++ src/cmd/ksh93/sh/main.c 2010-08-17 15:35:18.000000000 +0000 +@@ -200,14 +200,38 @@ int sh_main(int ac, char *av[], Shinit_f + { + /* system profile */ + sh_source(shp, iop, e_sysprofile); ++ } ++ /* make sure PWD is set up correctly */ ++ path_pwd(shp,1); ++#if SHOPT_SYSRC ++ if(!sh_isoption(SH_NOEXEC)) ++ { ++ if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED) && sh_isoption(SH_RC)) ++ { ++#if SHOPT_BASH ++ if(sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX)) ++ sh_source(shp, iop, e_bash_sysrc); ++ else ++#endif ++ { ++ if(name = sh_mactry(shp,nv_getval(ENVNOD))) ++ name = *name ? strdup(name) : (char*)0; ++ if(!name || !strmatch(name, "?(.)/./*")) ++ sh_source(shp, iop, e_sysrc); ++ if(name) ++ free(name); ++ } ++ } ++ } ++#endif ++ if(sh_isoption(SH_LOGIN_SHELL) && !sh_isoption(SH_NOPROFILE)) ++ { + if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED)) + { + char **files = shp->gd->login_files; + while ((name = *files++) && !sh_source(shp, iop, sh_mactry(shp,name))); + } + } +- /* make sure PWD is set up correctly */ +- path_pwd(shp,1); + if(!sh_isoption(SH_NOEXEC)) + { + if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED) && sh_isoption(SH_RC)) +@@ -215,9 +239,6 @@ int sh_main(int ac, char *av[], Shinit_f + #if SHOPT_BASH + if(sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX)) + { +-#if SHOPT_SYSRC +- sh_source(shp, iop, e_bash_sysrc); +-#endif + sh_source(shp, iop, shp->gd->rcfile ? shp->gd->rcfile : sh_mactry(shp,(char*)e_bash_rc)); + } + else +@@ -225,10 +246,6 @@ int sh_main(int ac, char *av[], Shinit_f + { + if(name = sh_mactry(shp,nv_getval(ENVNOD))) + name = *name ? strdup(name) : (char*)0; +-#if SHOPT_SYSRC +- if(!strmatch(name, "?(.)/./*")) +- sh_source(shp, iop, e_sysrc); +-#endif + if(name) + { + sh_source(shp, iop, name); diff --git a/ksh93-putval.dif b/ksh93-putval.dif new file mode 100644 index 0000000..5cd63e5 --- /dev/null +++ b/ksh93-putval.dif @@ -0,0 +1,15 @@ +--- ./src/cmd/ksh93/sh/name.c.orig 2019-04-04 14:28:17.044667686 +0000 ++++ ./src/cmd/ksh93/sh/name.c 2019-04-04 14:28:32.472629455 +0000 +@@ -1986,8 +1986,11 @@ void nv_putval(register Namval_t *np, co + up->cp = cp; + if(sp) + { ++ size_t splen = strlen(sp); + int c = cp[dot+append]; +- memmove(cp+append,sp,dot); ++ memmove(cp+append,sp,dot>splen?splen:dot); ++ if (dot>splen) ++ memset(cp+append+splen,0,dot-splen); + cp[dot+append] = c; + if(nv_isattr(np, NV_RJUST) && nv_isattr(np, NV_ZFILL)) + rightjust(cp,size,'0'); diff --git a/ksh93-redirectleak.dif b/ksh93-redirectleak.dif new file mode 100644 index 0000000..ddabf37 --- /dev/null +++ b/ksh93-redirectleak.dif @@ -0,0 +1,20 @@ +--- src/cmd/ksh93/sh/io.c.orig 2015-12-09 11:18:00.657295950 +0000 ++++ src/cmd/ksh93/sh/io.c 2015-12-09 11:18:57.719080685 +0000 +@@ -1541,7 +1541,17 @@ int sh_redirect(Shell_t *shp,struct iono + sh_iosave(shp,fn,indx,tname?fname:(trunc?Empty:0)); + } + else if(sh_subsavefd(fn)) ++ { ++ if(fd==fn) ++ { ++ if((r=sh_fcntl(fd,F_DUPFD,10)) > 0) ++ { ++ fd = r; ++ sh_close(fn); ++ } ++ } + sh_iosave(shp,fn,indx|IOSUBSHELL,tname?fname:0); ++ } + } + if(fd<0) + { diff --git a/ksh93-reg.dif b/ksh93-reg.dif new file mode 100644 index 0000000..a5a5d77 --- /dev/null +++ b/ksh93-reg.dif @@ -0,0 +1,18 @@ +--- src/cmd/ksh93/edit/edit.c ++++ src/cmd/ksh93/edit/edit.c 2013-02-01 17:18:31.405454238 +0000 +@@ -1769,8 +1769,13 @@ int ed_histgen(Edit_t *ep,const char *pa + mplast->next = mp; + mplast->next = 0; + } +- ep->hlist = (Histmatch_t**)argv; +- ep->hfirst = ep->hlist?ep->hlist[0]:0; ++ if (argv) ++ { ++ ep->hlist = (Histmatch_t**)argv; ++ ep->hfirst = ep->hlist?ep->hlist[0]:0; ++ } ++ else ++ ep->hfirst = 0; + return(ep->hmax=ac); + } + diff --git a/ksh93-s390.dif b/ksh93-s390.dif new file mode 100644 index 0000000..1e2a136 --- /dev/null +++ b/ksh93-s390.dif @@ -0,0 +1,22 @@ +--- src/cmd/ksh93/bltins/read.c ++++ src/cmd/ksh93/bltins/read.c 2013-02-01 15:29:39.393452098 +0000 +@@ -288,6 +288,19 @@ int sh_readline(register Shell_t *shp,ch + ep->e_nttyparm.c_lflag |= ISIG; + tty_set(fd,TCSADRAIN,&ep->e_nttyparm); + } ++#if defined(__linux__) ++ else if ((shp->fdstatus[fd]&(IOTTY|IONOSEEK))==0) ++ { ++ struct stat st; ++ if ((fstat(fd, &st) == 0) && S_ISFIFO(st.st_mode)) ++ { ++ int fdflg; ++ if (((fdflg = fcntl(fd, F_GETFL)) != -1) && !(fdflg & O_NONBLOCK)) ++ fcntl(fd, F_SETFL, fdflg|O_NONBLOCK); ++ shp->fdstatus[fd] |= IONOSEEK; ++ } ++ } ++#endif + } + binary = nv_isattr(np,NV_BINARY); + if(!binary && !(flags&(N_FLAG|NN_FLAG))) diff --git a/ksh93-sfio.dif b/ksh93-sfio.dif new file mode 100644 index 0000000..6d29a3d --- /dev/null +++ b/ksh93-sfio.dif @@ -0,0 +1,263 @@ +--- src/lib/libast/include/sfio_t.h ++++ src/lib/libast/include/sfio_t.h 2013-10-11 09:22:41.000000000 +0000 +@@ -34,7 +34,7 @@ + #define _SFIO_PRIVATE \ + Sfoff_t extent; /* current file size */ \ + Sfoff_t here; /* current physical location */ \ +- unsigned char unused_1;/* unused #1 */ \ ++ unsigned char ngetr; /* sfgetr count */ \ + unsigned char tiny[1];/* for unbuffered read stream */ \ + unsigned short bits; /* private flags */ \ + unsigned int mode; /* current io mode */ \ +@@ -82,7 +82,7 @@ + (ssize_t)(-1), /* val */ \ + (Sfoff_t)0, /* extent */ \ + (Sfoff_t)0, /* here */ \ +- 0, /* getr */ \ ++ 0, /* ngetr */ \ + {0}, /* tiny */ \ + 0, /* bits */ \ + (unsigned int)(((type)&(SF_RDWR))|SF_INIT), /* mode */ \ +@@ -93,7 +93,8 @@ + (mutex), /* mutex */ \ + (Void_t*)0, /* stdio */ \ + (Sfoff_t)0, /* lpos */ \ +- (size_t)0 /* iosz */ \ ++ (size_t)0, /* iosz */ \ ++ 0 /* getr */ \ + } + + /* function to clear an Sfio_t structure */ +@@ -110,7 +111,7 @@ + (f)->val = (ssize_t)(-1), /* val */ \ + (f)->extent = (Sfoff_t)(-1), /* extent */ \ + (f)->here = (Sfoff_t)0, /* here */ \ +- (f)->getr = 0, /* getr */ \ ++ (f)->ngetr = 0, /* ngetr */ \ + (f)->tiny[0] = 0, /* tiny */ \ + (f)->bits = 0, /* bits */ \ + (f)->mode = 0, /* mode */ \ +@@ -121,7 +122,8 @@ + (f)->mutex = (mtx), /* mutex */ \ + (f)->stdio = (Void_t*)0, /* stdio */ \ + (f)->lpos = (Sfoff_t)0, /* lpos */ \ +- (f)->iosz = (size_t)0 /* iosz */ \ ++ (f)->iosz = (size_t)0, /* iosz */ \ ++ (f)->getr = 0 /* getr */ \ + ) + + /* expose next stream inside discipline function; state saved in int f */ +--- src/lib/libast/sfio/sfflsbuf.c ++++ src/lib/libast/sfio/sfflsbuf.c 2013-10-18 11:50:01.866235555 +0000 +@@ -96,7 +96,7 @@ int c; /* if c>=0, c is also written out + isall = SFISALL(f,isall); + if((w = SFWR(f,data,n,f->disc)) > 0) + { if((n -= w) > 0) /* save unwritten data, then resume */ +- memcpy((char*)f->data,(char*)data+w,n); ++ memmove((char*)f->data,(char*)data+w,n); + written += w; + f->next = f->data+n; + if(c < 0 && (!isall || n == 0)) +--- src/lib/libast/sfio/sfmode.c ++++ src/lib/libast/sfio/sfmode.c 2013-10-11 09:26:43.000000000 +0000 +@@ -258,7 +258,7 @@ reg Sfio_t* f; /* stream to close */ + #endif + { + Sfproc_t* p; +- int pid, status; ++ int status; + + if(!(p = f->proc)) + return -1; +@@ -279,7 +279,7 @@ reg Sfio_t* f; /* stream to close */ + sigcritical(SIG_REG_EXEC|SIG_REG_PROC); + #endif + status = -1; +- while ((pid = waitpid(p->pid,&status,0)) == -1 && errno == EINTR) ++ while (waitpid(p->pid,&status,0) == -1 && errno == EINTR) + ; + #if _PACKAGE_ast + status = status == -1 ? +@@ -405,12 +405,16 @@ reg int local; /* a local call */ + if(f->mode&SF_GETR) + { f->mode &= ~SF_GETR; + #ifdef MAP_TYPE +- if((f->bits&SF_MMAP) && (f->tiny[0] += 1) >= (4*SF_NMAP) ) +- { /* turn off mmap to avoid page faulting */ +- sfsetbuf(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND); +- f->tiny[0] = 0; ++ if(f->bits&SF_MMAP) ++ { ++ if (!++f->ngetr) ++ f->tiny[0]++; ++ if(((f->tiny[0]<<8)|f->ngetr) >= (4*SF_NMAP) ) ++ { /* turn off mmap to avoid page faulting */ ++ sfsetbuf(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND); ++ f->ngetr = f->tiny[0] = 0; ++ } + } +- else + #endif + if(f->getr) + { f->next[-1] = f->getr; +--- src/lib/libast/sfio/sfmove.c ++++ src/lib/libast/sfio/sfmove.c 2013-10-18 12:04:03.194735625 +0000 +@@ -113,7 +113,11 @@ reg int rc; /* record separator */ + + /* try reading a block of data */ + direct = 0; +- if((r = fr->endb - (next = fr->next)) <= 0) ++ if(fr->rsrv && (r = -fr->rsrv->slen) > 0) ++ { fr->rsrv->slen = 0; ++ next = fr->rsrv->data; ++ } ++ else if((r = fr->endb - (next = fr->next)) <= 0) + { /* amount of data remained to be read */ + if((w = n > MAX_SSIZE ? MAX_SSIZE : (ssize_t)n) < 0) + { if(fr->extent < 0) +--- src/lib/libast/sfio/sfpoll.c ++++ src/lib/libast/sfio/sfpoll.c 2013-10-18 11:59:50.778735232 +0000 +@@ -138,7 +138,7 @@ int tm; /* time in millisecs for select + while((np = SFPOLL(fds,m,tm)) < 0 ) + { if(errno == eintr || errno == EAGAIN) + errno = 0; +- else break; ++ else goto report; + } + if(np > 0) /* poll succeeded */ + np = c; +@@ -147,14 +147,14 @@ int tm; /* time in millisecs for select + { f = fa[check[r]]; + + if((f->flags&SF_WRITE) && !WRREADY(f) ) +- { if(fds[m].revents&POLLOUT) ++ { if(fds[m].revents&(POLLOUT|POLLHUP|POLLERR)) + status[check[r]] |= SF_WRITE; + } + + if((f->flags&SF_READ) && !RDREADY(f)) + { if((f->mode&SF_WRITE) && HASAUXFD(f)) + m += 1; +- if(fds[m].revents&POLLIN) ++ if(fds[m].revents&(POLLIN|POLLHUP|POLLERR)) + status[check[r]] |= SF_READ; + } + } +@@ -200,7 +200,7 @@ int tm; /* time in millisecs for select + while((np = select(m+1,&rd,&wr,NIL(fd_set*),tmp)) < 0 ) + { if(errno == eintr) + errno = 0; +- else break; ++ else goto report; + } + if(np > 0) + np = c; +@@ -227,6 +227,7 @@ int tm; /* time in millisecs for select + } + #endif /*_lib_select*/ + ++ report: + for(r = c = 0; c < n; ++c) + { if(status[c] == 0) + continue; +--- src/lib/libast/sfio/sfpool.c ++++ src/lib/libast/sfio/sfpool.c 2013-10-18 11:49:25.614237061 +0000 +@@ -138,7 +138,7 @@ int n; /* current position in pool */ + else /* write failed, recover buffer then quit */ + { if(w > 0) + { v -= w; +- memcpy(head->data,(head->data+w),v); ++ memmove(head->data,(head->data+w),v); + } + head->next = head->data+v; + goto done; +@@ -147,7 +147,7 @@ int n; /* current position in pool */ + + /* move data from head to f */ + if((head->data+k) != f->data ) +- memcpy(f->data,(head->data+k),v); ++ memmove(f->data,(head->data+k),v); + f->next = f->data+v; + } + +--- src/lib/libast/sfio/sfsetbuf.c ++++ src/lib/libast/sfio/sfsetbuf.c 2013-10-18 12:02:37.534736056 +0000 +@@ -254,6 +254,15 @@ size_t size; /* buffer size, -1 for defa + #endif + } + ++ /* set page size, this is also the desired default buffer size */ ++ if(_Sfpage <= 0) ++ { ++#if _lib_getpagesize ++ if((_Sfpage = (size_t)getpagesize()) <= 0) ++#endif ++ _Sfpage = SF_PAGE; ++ } ++ + #if SFSETLINEMODE + if(init) + f->flags |= sfsetlinemode(); +@@ -308,15 +317,6 @@ size_t size; /* buffer size, -1 for defa + (void)_sfpopen(f,-1,-1,1); + } + } +- +- /* set page size, this is also the desired default buffer size */ +- if(_Sfpage <= 0) +- { +-#if _lib_getpagesize +- if((_Sfpage = (size_t)getpagesize()) <= 0) +-#endif +- _Sfpage = SF_PAGE; +- } + } + + #ifdef MAP_TYPE +--- src/lib/libast/string/stropt.c ++++ src/lib/libast/string/stropt.c 2013-01-03 17:20:37.000000000 +0100 +@@ -90,7 +90,7 @@ stropt(const char* as, const void* tab, + { + for (p = (char**)tab; t = *p; p = (char**)((char*)p + siz)) + { +- for (v = s; *t && *t++ == *v; v++); ++ for (v = s; *t && *t == *v; t++, v++); + if (!*t || isspace(*v) || *v == ',' || *v == '=') + break; + if (*v == ':' && *(v + 1) == '=') +--- src/lib/libast/vmalloc/vmopen.c ++++ src/lib/libast/vmalloc/vmopen.c 2013-10-18 13:54:50.918235639 +0000 +@@ -68,19 +68,22 @@ int mode; /* type of region */ + Block_t *bp, *np; + Seg_t *seg; + Vmuchar_t *addr; +- int rv; ++ int rv, mt; + + if(!meth || !disc || !disc->memoryf ) + return NIL(Vmalloc_t*); + + GETPAGESIZE(_Vmpagesize); + ++ mode = (mode&VM_FLAGS) | meth->meth; /* start with user-settable flags */ ++ + vmp = &vmproto; /* avoid memory allocation here! */ + memset(vmp, 0, sizeof(Vmalloc_t)); + memcpy(&vmp->meth, meth, sizeof(Vmethod_t)); ++ mt = vmp->meth.meth; ++ vmp->meth.meth = 0; + vmp->disc = disc; + +- mode &= VM_FLAGS; /* start with user-settable flags */ + size = 0; + + if(disc->exceptf) +@@ -155,6 +158,8 @@ int mode; /* type of region */ + seg->free = bp; + else vd->wild = bp; + ++ vmp->meth.meth = mt; ++ + done: /* now make the region handle */ + if(vd->mode&VM_MEMORYF) + vm = &init->vm.vm; diff --git a/ksh93-shift_ijs.dif b/ksh93-shift_ijs.dif new file mode 100644 index 0000000..7cec256 --- /dev/null +++ b/ksh93-shift_ijs.dif @@ -0,0 +1,429 @@ +--- src/cmd/ksh93/edit/edit.c ++++ src/cmd/ksh93/edit/edit.c 2007-12-20 17:50:28.000000000 +0000 +@@ -28,6 +28,7 @@ + */ + + #include ++#include + #include + #include + #include "FEATURE/options" +@@ -57,8 +58,20 @@ static char KILL_LINE[20] = { ESC, '[', + + + #if SHOPT_MULTIBYTE +-# define is_cntrl(c) ((c<=STRIP) && iscntrl(c)) +-# define is_print(c) ((c&~STRIP) || isprint(c)) ++# if _hdr_wctype ++# include ++# define is_print(c) iswprint((c)) ++# define is_cntrl(c) iswcntrl((c)) ++# else ++# define is_cntrl(c) (((c)<=STRIP) && iscntrl((c))) ++# define is_print(c) (((c)&~STRIP) || isprint((c))) ++# endif ++# if !_lib_iswcntrl && !defined(iswcntrl) ++# define iswcntrl(c) (((c)<=STRIP) && iscntrl((c))) ++# endif ++# if !_lib_iswprint && !defined(iswprint) ++# define iswprint(c) (((c)&~STRIP) || isprint((c))) ++# endif + #else + # define is_cntrl(c) iscntrl(c) + # define is_print(c) isprint(c) +--- src/cmd/ksh93/edit/emacs.c ++++ src/cmd/ksh93/edit/emacs.c 2007-12-20 17:50:28.000000000 +0000 +@@ -62,6 +62,7 @@ One line screen editor for any program + */ + + #include ++#include + #include "FEATURE/cmds" + #if KSHELL + # include "defs.h" +@@ -84,6 +85,9 @@ One line screen editor for any program + + + #if SHOPT_MULTIBYTE ++# if _hdr_wctype ++# include ++# endif + # define gencpy(a,b) ed_gencpy(a,b) + # define genncpy(a,b,n) ed_genncpy(a,b,n) + # define genlen(str) ed_genlen(str) +@@ -1563,11 +1567,19 @@ static void setcursor(register Emacs_t * + #if SHOPT_MULTIBYTE + static int print(register int c) + { ++#if _lib_iswprint || defined(iswprint) ++ return(iswprint(c)); ++#else + return((c&~STRIP)==0 && isprint(c)); ++#endif + } + + static int _isword(register int c) + { ++#if _lib_iswalnum || defined(iswalnum) ++ return(iswalnum(c) || (c == '_')); ++#else + return((c&~STRIP) || isalnum(c) || c=='_'); ++#endif + } + #endif /* SHOPT_MULTIBYTE */ +--- src/cmd/ksh93/edit/vi.c ++++ src/cmd/ksh93/edit/vi.c 2007-12-20 17:50:28.000000000 +0000 +@@ -28,6 +28,8 @@ + * cbosgd!pds + -*/ + ++#include ++#include + + #if KSHELL + # include "defs.h" +@@ -65,10 +67,19 @@ + # define gencpy(a,b) ed_gencpy(a,b) + # define genncpy(a,b,n) ed_genncpy(a,b,n) + # define genlen(str) ed_genlen(str) +-# define digit(c) ((c&~STRIP)==0 && isdigit(c)) +-# define is_print(c) ((c&~STRIP) || isprint(c)) ++# if _hdr_wctype ++# include ++# define digit(c) iswdigit((c)) ++# define is_print(c) iswprint((c)) ++# else ++# define digit(c) (((c)&~STRIP)==0 && isdigit((c))) ++# define is_print(c) (((c)&~STRIP) || isprint((c))) ++# endif ++# if !_lib_iswdigit && !defined(iswdigit) ++# define iswdigit(c) (((c)&~STRIP)==0 && isdigit((c))) ++# endif + # if !_lib_iswprint && !defined(iswprint) +-# define iswprint(c) ((c&~0177) || isprint(c)) ++# define iswprint(c) (((c)&~STRIP) || isprint((c))) + # endif + static int _isalph(int); + static int _ismetach(int); +--- src/cmd/ksh93/sh/io.c ++++ src/cmd/ksh93/sh/io.c 2010-06-28 14:09:09.000000000 +0000 +@@ -1536,6 +1536,7 @@ static int io_heredoc(Shell_t *shp,regis + if(traceon) + sfprintf(sfstderr,"< %s\n",name); + sfputr(outfile,name,'\n'); ++ off = 0; + } + else + { +--- src/cmd/ksh93/sh/macro.c ++++ src/cmd/ksh93/sh/macro.c 2013-03-19 17:16:46.062074381 +0100 +@@ -54,6 +54,7 @@ + #if SHOPT_MULTIBYTE + # undef isascii + # define isacii(c) ((c)<=UCHAR_MAX) ++# include + #else + # define mbchar(p) (*(unsigned char*)p++) + #endif /* SHOPT_MULTIBYTE */ +@@ -2026,6 +2027,11 @@ static void comsubst(Mac_t *mp,register + struct _mac_ savemac; + int savtop = stktell(stkp); + char lastc=0, *savptr = stkfreeze(stkp,0); ++#if SHOPT_MULTIBYTE ++ const Lc_t *lc=lcinfo(LC_CTYPE)->lc; ++ wchar_t lastw=0; ++#endif /* SHOPT_MULTIBYTE */ ++ ssize_t len; + int was_history = sh_isstate(SH_HISTORY); + int was_verbose = sh_isstate(SH_VERBOSE); + int was_interactive = sh_isstate(SH_INTERACTIVE); +@@ -2127,7 +2133,7 @@ static void comsubst(Mac_t *mp,register + num = lseek(fd, (off_t)0, SEEK_CUR); + goto out_offset; + } +- if(!(sp=mp->shp->sftable[fd])) ++ if(!(sp=mp->shp->sftable[fd]) || (sffileno(sp)!=fd &&!(sfset(sp,0,0)&SF_STRING))) + sp = sfnew(NIL(Sfio_t*),(char*)malloc(IOBSIZE+1),IOBSIZE,fd,SF_READ|SF_MALLOC); + type = 3; + } +@@ -2209,17 +2215,36 @@ static void comsubst(Mac_t *mp,register + } + else if(lastc) + { +- mac_copy(mp,&lastc,1); ++ char mb[8]; ++ mb[0] = lastc; ++ len = 1; ++#if SHOPT_MULTIBYTE ++ if(lastw) ++ len = mbconv(mb, lastw); ++ lastw = 0; ++#endif /* SHOPT_MULTIBYTE */ + lastc = 0; ++ mac_copy(mp,mb,len); + } + newlines = nextnewlines; + if(++c < bufsize) + str[c] = 0; + else + { +- ssize_t len = 1; ++ len = 1; + + /* can't write past buffer so save last character */ ++#if SHOPT_MULTIBYTE ++ if ((lc->flags & LC_utf8)==0 && (len = mbsize(str))>1) ++ { ++ len = mb2wc(lastw,str,len); ++ if (len < 0) ++ { ++ lastw = 0; ++ len = 1; ++ } ++ } ++#endif /* SHOPT_MULTIBYTE */ + c -= len; + lastc = str[c]; + str[c] = 0; +@@ -2240,8 +2265,16 @@ static void comsubst(Mac_t *mp,register + } + if(lastc) + { +- mac_copy(mp,&lastc,1); ++ char mb[8]; ++ mb[0] = lastc; ++ len = 1; ++#if SHOPT_MULTIBYTE ++ if(lastw) ++ len = mbconv(mb, lastw); ++ lastw = 0; ++#endif /* SHOPT_MULTIBYTE */ + lastc = 0; ++ mac_copy(mp,mb,len); + } + sfclose(sp); + return; +@@ -2340,13 +2373,13 @@ static void mac_copy(register Mac_t *mp, + if(mp->pattern) + { + char *sp = "&|()"; +- while(c = *sp++) ++ while((c = *sp++)) + { + if(state[c]==0) + state[c] = S_EPAT; + } + sp = "*?[{"; +- while(c = *sp++) ++ while((c = *sp++)) + { + if(state[c]==0) + state[c] = S_PAT; +--- src/cmd/ksh93/sh/string.c ++++ src/cmd/ksh93/sh/string.c 2007-12-20 17:51:07.000000000 +0000 +@@ -37,7 +37,7 @@ + #endif + + #if !_lib_iswprint && !defined(iswprint) +-# define iswprint(c) (((c)&~0377) || isprint(c)) ++# define iswprint(c) (((c)&~STRIP) || isprint(c)) + #endif + + +@@ -245,7 +245,7 @@ void sh_trim(register char *sp) + if(sp) + { + dp = sp; +- while(c= *sp) ++ while((c = *sp)) + { + #if SHOPT_MULTIBYTE + int len; +--- src/cmd/ksh93/tests/sjis.sh ++++ src/cmd/ksh93/tests/sjis.sh 2011-05-20 15:11:29.000000000 +0000 +@@ -0,0 +1,77 @@ ++######################################################################## ++# # ++# Copyright (c) 2007 SuSE Linux Products GmbH, Nuernberg, Germany # ++# # ++# This library is free software; you can redistribute it and/or # ++# modify it under the terms of the GNU Lesser General Public # ++# License as published by the Free Software Foundation; # ++# version 2.1 of the License. # ++# # ++# This library is distributed in the hope that it will be useful, # ++# but WITHOUT ANY WARRANTY; without even the implied warranty of # ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # ++# GNU Lesser General Public License at # ++# http://www.gnu.org/licenses/lgpl-2.1.html for more details # ++# # ++# Author: Werner Fink # ++# # ++######################################################################## ++ ++# ++# Byte ranges for Shift-JIS encoding (hexadecimal): ++# First byte: 81-9F, E0-EF ++# Second byte: 40-7E, 80-FC ++# ++# Now test out some multi byte characters which ++# include 7bit aka ASCII bytes with 0x81 0x{40-7E} ++# ++ ++typeset -i chr=0 ++typeset -i err=0 ++typeset printf=$(type -p printf 2>/dev/null) ++ ++unset LC_ALL ++unset LC_CTYPE ++export LANG=ja_JP.SJIS ++ ++for second in $(seq 64 126); do ++ let chr++ ++ second=$(printf '%x' ${second}) ++ mbchar="$(printf "\x81\x${second}")" ++ if test -z "${mbchar}" ; then ++ let err++ # ERROR in builtin printf ++ echo ' builtin printf with \\x81\\x'${second} failed as result is empty ++ continue ++ fi ++ if test -x "${printf}" ; then ++ if test $(${printf} "\x81\x${second}") != ${mbchar} ; then ++ let err++ # ERROR in builtin printf ++ echo -n ' \\x81\\x'${second} 'failed with ' ++ echo -n $(${printf} "\x81\x${second}") '!= ' ++ echo ${mbchar} ++ continue ++ fi ++ fi ++ uq=$(echo ${mbchar}) ++ dq=$(echo "${mbchar}") ++ test "$uq" != "$dq" && let err+=1 ++ test ${#uq} -ne 1 -o ${#dq} -ne 1 && let err+=1 ++done ++ ++if test $err -ne 0 ; then ++ : err_exit ++ : err_exit ++ print -u2 -n "\t" ++ print -u2 -r ${0##*/}[$LINENO]: "Shift-JIS encoding failed" ++fi ++ ++LANG=POSIX ++typeset -r utf8_euro_char1=$'\u[20ac]' ++typeset -r utf8_euro_char2=$'\342\202\254' ++(( (${#utf8_euro_char1} == 1) && (${#utf8_euro_char2} == 1) )) || export LC_ALL='en_US.UTF-8' ++if [[ "$(printf '\u[20ac]')" != $'\342\202\254' ]] ; then ++ : err_exit ++ print -u2 -n "\t" ++ print -u2 -r ${0##*/}[$LINENO]: "Locale overrride failed." ++fi ++exit $err +--- src/lib/libast/comp/setlocale.c ++++ src/lib/libast/comp/setlocale.c 2007-12-20 17:50:28.000000000 +0000 +@@ -32,6 +32,7 @@ + + #include "lclib.h" + ++#include + #include + #include + #include +--- src/lib/libast/comp/wc.c ++++ src/lib/libast/comp/wc.c 2007-12-20 17:50:28.000000000 +0000 +@@ -26,6 +26,7 @@ + */ + + #include ++#include + #include + + #define STUB 1 +--- src/lib/libast/features/wchar ++++ src/lib/libast/features/wchar 2007-12-20 17:50:28.000000000 +0000 +@@ -8,7 +8,8 @@ cat{ + #define _AST_WCHAR_H 1 + }end + +-lib mbstowcs,wctomb,wcrtomb,wcslen,wcstombs,wcwidth stdlib.h stdio.h wchar.h ++lib mbstowcs,wctomb,wcrtomb,wcslen,wcstombs,wcscpy,wcwidth stdlib.h stdio.h wchar.h wctype.h ++lib iswprint,iswalpha,iswalnum,iswdigit,iswcntrl stdlib.h stdio.h ctype.h wctype.h + lib towlower,towupper stdlib.h stdio.h wchar.h + typ mbstate_t stdlib.h stdio.h wchar.h + nxt wchar +@@ -68,6 +69,12 @@ cat <1) + + #define mb2wc(w,p,n) (*ast.mb_towc)(&w,(char*)p,n) +-#define mbchar(p) (mbwide()?((ast.tmp_int=(*ast.mb_towc)(&ast.tmp_wchar,(char*)(p),mbmax()))>0?((p+=ast.tmp_int),ast.tmp_wchar):(p+=ast.mb_sync+1,ast.tmp_int)):(*(unsigned char*)(p++))) +-#define mbnchar(p,n) (mbwide()?((ast.tmp_int=(*ast.mb_towc)(&ast.tmp_wchar,(char*)(p),n))>0?((p+=ast.tmp_int),ast.tmp_wchar):(p+=ast.mb_sync+1,ast.tmp_int)):(*(unsigned char*)(p++))) + #define mbinit() (mbwide()?(*ast.mb_towc)((wchar_t*)0,(char*)0,mbmax()):0) + #define mbsize(p) (mbwide()?(*ast.mb_len)((char*)(p),mbmax()):((p),1)) + #define mbnsize(p,n) (mbwide()?(*ast.mb_len)((char*)(p),n):((p),1)) +@@ -195,6 +193,17 @@ typedef struct + #define mbxfrm(t,f,n) (mbcoll()?(*ast.mb_xfrm)((char*)(t),(char*)(f),n):0) + #define mbalpha(w) (ast.mb_alpha?(*ast.mb_alpha)(w):isalpha((w)&0xff)) + ++#define mbchar(p) (mbwide() ? \ ++ (((ast.tmp_int=(*ast.mb_towc)(&ast.tmp_wchar,(char*)(p),mbmax()))>0) ? \ ++ ({p+=ast.tmp_int;ast.tmp_wchar;}) : \ ++ ({ast.tmp_int=*(unsigned char*)p;p+=ast.mb_sync+1;ast.tmp_int;})) : \ ++ (*(unsigned char*)(p++))) ++#define mbnchar(p,n) (mbwide() ? \ ++ (((ast.tmp_int=(*ast.mb_towc)(&ast.tmp_wchar,(char*)(p),n))>0) ? \ ++ ({p+=ast.tmp_int;ast.tmp_wchar;}) : \ ++ ({ast.tmp_int=*(unsigned char*)p;p+=ast.mb_sync+1;ast.tmp_int;})) : \ ++ (*(unsigned char*)(p++))) ++ + /* + * common macros + */ +--- src/lib/libast/regex/reglib.h ++++ src/lib/libast/regex/reglib.h 2007-12-20 17:50:28.000000000 +0000 +@@ -57,6 +57,7 @@ typedef struct regsubop_s + char re_rhs[1]; /* substitution rhs */ + + #include ++#include + #include + #include + +--- src/lib/libcmd/Mamfile ++++ src/lib/libcmd/Mamfile 2013-02-05 15:11:03.153953100 +0000 +@@ -509,7 +509,7 @@ make cat.o + prev cat.c + meta cat.o %.c>%.o cat.c cat + prev cat.c +-exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -DERROR_CATALOG=\""libcmd"\" -DUSAGE_LICENSE=\""[-author?Glenn Fowler ][-author?David Korn ][-copyright?Copyright (c) 1992-2012 AT&T Intellectual Property][-license?http://www.eclipse.org/org/documents/epl-v10.html][--catalog?libcmd]"\" -D_BLD_cmd -D_PACKAGE_ast -c cat.c ++exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -DERROR_CATALOG=\""libcmd"\" -DUSAGE_LICENSE=\""[-author?Glenn Fowler ][-author?David Korn ][-copyright?Copyright (c) 1992-2012 AT&T Intellectual Property][-license?http://www.eclipse.org/org/documents/epl-v10.html][--catalog?libcmd]"\" -D_BLD_cmd -D_PACKAGE_ast -DSHOPT_MULTIBYTE -c cat.c + done cat.o generated + make chgrp.o + prev chgrp.c diff --git a/ksh93-signals.dif b/ksh93-signals.dif new file mode 100644 index 0000000..938b8d5 --- /dev/null +++ b/ksh93-signals.dif @@ -0,0 +1,50 @@ +--- src/cmd/ksh93/data/signals.c ++++ src/cmd/ksh93/data/signals.c 2012-02-06 10:16:54.000000000 +0000 +@@ -18,6 +18,9 @@ + * * + ***********************************************************************/ + #include "defs.h" ++#include ++#include ++ + + #if defined(SIGCLD) && !defined(SIGCHLD) + # define SIGCHLD SIGCLD +--- src/cmd/ksh93/sh/xec.c ++++ src/cmd/ksh93/sh/xec.c 2007-12-21 12:28:04.000000000 +0000 +@@ -3834,6 +3834,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons + { + signal(SIGTTIN,SIG_DFL); + signal(SIGTTOU,SIG_DFL); ++ signal(SIGTSTP,SIG_DFL); + } + #endif /* SIGTSTP */ + #ifdef JOBS +@@ -3871,6 +3872,9 @@ static pid_t sh_ntfork(Shell_t *shp,cons + { + signal(SIGTTIN,SIG_IGN); + signal(SIGTTOU,SIG_IGN); ++ if(sh_isstate(SH_INTERACTIVE)) ++ signal(SIGTSTP,SIG_IGN); ++ else signal(SIGTSTP,SIG_DFL); + } + #endif /* SIGTSTP */ + if(spawnpid>0) +@@ -3951,6 +3955,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons + { + signal(SIGTTIN,SIG_DFL); + signal(SIGTTOU,SIG_DFL); ++ signal(SIGTSTP,SIG_DFL); + jobwasset++; + } + #endif /* SIGTSTP */ +@@ -4013,6 +4018,9 @@ static pid_t sh_ntfork(Shell_t *shp,cons + { + signal(SIGTTIN,SIG_IGN); + signal(SIGTTOU,SIG_IGN); ++ if(sh_isstate(SH_INTERACTIVE)) ++ signal(SIGTSTP,SIG_IGN); ++ else signal(SIGTSTP,SIG_DFL); + } + #endif /* SIGTSTP */ + if(sigwasset) diff --git a/ksh93-spawnlock.dif b/ksh93-spawnlock.dif new file mode 100644 index 0000000..e5f19ae --- /dev/null +++ b/ksh93-spawnlock.dif @@ -0,0 +1,40 @@ +--- ./src/cmd/ksh93/sh/jobs.c.orig 2016-07-26 12:52:44.178281624 +0000 ++++ ./src/cmd/ksh93/sh/jobs.c 2016-07-26 12:52:59.563281597 +0000 +@@ -2071,6 +2071,10 @@ void job_fork(pid_t parent) + job_lock(); + jobfork++; + break; ++ case -2: ++ jobfork--; ++ job_unlock(); ++ break; + case 0: + jobfork=0; + job_unlock(); +--- ./src/cmd/ksh93/sh/xec.c.orig 2016-07-26 12:52:37.322281636 +0000 ++++ ./src/cmd/ksh93/sh/xec.c 2016-07-26 12:55:37.097281318 +0000 +@@ -3952,6 +3952,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons + # endif /* !_lib_fork */ + sh_pushcontext(shp,buffp,SH_JMPCMD); + errorpush(&buffp->err,ERROR_SILENT); ++ job_lock(); /* errormsg will unlock */ + jmpval = sigsetjmp(buffp->buff,0); + if(jmpval == 0) + { +@@ -4050,7 +4051,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons + } + fail: + if(jobfork && spawnpid<0) +- job_fork(0); ++ job_fork(-2); + if(spawnpid < 0) switch(errno=shp->path_err) + { + case ENOENT: +@@ -4058,6 +4059,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons + default: + errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec+4); + } ++ job_unlock(); + } + else + exitset(); diff --git a/ksh93-stkalias.dif b/ksh93-stkalias.dif new file mode 100644 index 0000000..d5e7a6c --- /dev/null +++ b/ksh93-stkalias.dif @@ -0,0 +1,33 @@ +--- ./src/lib/libast/misc/stk.c.orig 2014-11-26 16:01:29.606716557 +0000 ++++ ./src/lib/libast/misc/stk.c 2014-11-26 16:03:06.031328609 +0000 +@@ -505,7 +505,7 @@ static char *stkgrow(register Sfio_t *st + register char *cp, *dp=0; + register size_t m = stktell(stream); + size_t endoff; +- char *end=0; ++ char *end=0, *oldbase=0; + int nn=0,add=1; + n += (m + sizeof(struct frame)+1); + if(sp->stkflags&STK_SMALL) +@@ -521,6 +521,7 @@ static char *stkgrow(register Sfio_t *st + dp=sp->stkbase; + sp->stkbase = ((struct frame*)dp)->prev; + end = fp->end; ++ oldbase = dp; + } + endoff = end - dp; + cp = newof(dp, char, n, nn*sizeof(char*)); +@@ -547,10 +548,10 @@ static char *stkgrow(register Sfio_t *st + if(fp->nalias=nn) + { + fp->aliases = (char**)fp->end; +- if(end && nn>1) +- memmove(fp->aliases,end,(nn-1)*sizeof(char*)); ++ if(end && nn>add) ++ memmove(fp->aliases,end,(nn-add)*sizeof(char*)); + if(add) +- fp->aliases[nn-1] = dp + roundof(sizeof(struct frame),STK_ALIGN); ++ fp->aliases[nn-1] = oldbase + roundof(sizeof(struct frame),STK_ALIGN); + } + if(m && !dp) + { diff --git a/ksh93-stkfreeze.dif b/ksh93-stkfreeze.dif new file mode 100644 index 0000000..2ecc68b --- /dev/null +++ b/ksh93-stkfreeze.dif @@ -0,0 +1,30 @@ +--- ./src/cmd/ksh93/sh/xec.c.orig 2014-11-21 14:11:39.619645318 +0000 ++++ ./src/cmd/ksh93/sh/xec.c 2014-11-21 14:13:55.409987787 +0000 +@@ -514,8 +514,8 @@ int sh_debug(Shell_t *shp, const char *t + Stk_t *stkp=shp->stk; + struct sh_scoped savst; + Namval_t *np = SH_COMMANDNOD; +- char *sav = stkptr(stkp,0); + int n=4, offset=stktell(stkp); ++ char *sav = stkfreeze(stkp,0); + const char *cp = "+=( "; + Sfio_t *iop = stkstd; + short level; +@@ -570,7 +570,7 @@ int sh_debug(Shell_t *shp, const char *t + nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE); + shp->st = savst; + if(sav != stkptr(stkp,0)) +- stkset(stkp,sav,0); ++ stkset(stkp,sav,offset); + else + stkseek(stkp,offset); + return(n); +@@ -998,7 +998,7 @@ int sh_exec(register const Shnode_t *t, + int ntflag = 0; + #endif + int topfd = shp->topfd; +- char *sav=stkptr(stkp,0); ++ char *sav=stkfreeze(stkp,0); + char *cp=0, **com=0, *comn; + int argn; + int skipexitset = 0; diff --git a/ksh93-stkset-abort.dif b/ksh93-stkset-abort.dif new file mode 100644 index 0000000..40111ce --- /dev/null +++ b/ksh93-stkset-abort.dif @@ -0,0 +1,11 @@ +--- ./src/lib/libast/misc/stk.c.orig 2014-11-22 10:46:29.708285640 +0000 ++++ ./src/lib/libast/misc/stk.c 2014-11-22 10:48:32.533777385 +0000 +@@ -378,6 +378,8 @@ char *stkset(register Sfio_t * stream, r + frames++; + } + /* set stack back to the beginning */ ++ if (loc) ++ abort(); + cp = (char*)(fp+1); + if(frames) + sfsetbuf(stream,cp,sp->stkend-cp); diff --git a/ksh93-subshellpwd.dif b/ksh93-subshellpwd.dif new file mode 100644 index 0000000..80fbaed --- /dev/null +++ b/ksh93-subshellpwd.dif @@ -0,0 +1,11 @@ +--- ./src/cmd/ksh93/sh/subshell.c.orig 2014-11-13 15:56:44.331110277 +0000 ++++ ./src/cmd/ksh93/sh/subshell.c 2014-11-13 15:58:05.104764274 +0000 +@@ -547,7 +547,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + struct subshell *xp; + sp->shpwd = shp->pwd; + #ifdef _lib_fchdir +- for(xp=sp->prev; xp; xp=xp->prev) ++ for(xp=sp->prev; shp->pwd && xp; xp=xp->prev) + { + if(xp->pwdfd>0 && strcmp(xp->pwd,shp->pwd)==0) + { diff --git a/ksh93-suid_exec.dif b/ksh93-suid_exec.dif new file mode 100644 index 0000000..0d9bf6f --- /dev/null +++ b/ksh93-suid_exec.dif @@ -0,0 +1,147 @@ +--- src/cmd/ksh93/data/msg.c ++++ src/cmd/ksh93/data/msg.c 2007-04-02 14:59:19.000000000 +0000 +@@ -205,7 +205,11 @@ const char e_bash_profile[] = "$HOME/.ba + const char e_crondir[] = "/var/spool/cron"; + const char e_prohibited[] = "login setuid/setgid shells prohibited"; + #if SHOPT_SUID_EXEC ++# ifdef THISPROG ++ const char e_suidexec[] = THISPROG; ++# else + const char e_suidexec[] = "/etc/suid_exec"; ++# endif + #endif /* SHOPT_SUID_EXEC */ + const char hist_fname[] = "/.sh_history"; + const char e_dot[] = "."; +--- src/cmd/ksh93/sh/suid_exec.c ++++ src/cmd/ksh93/sh/suid_exec.c 2012-02-03 08:36:40.000000000 +0000 +@@ -62,10 +62,24 @@ + #define FDVERIFY 12 /* used to validate /tmp process */ + #undef BLKSIZE + #define BLKSIZE sizeof(char*)*1024 +-#define THISPROG "/etc/suid_exec" +-#define DEFSHELL "/bin/sh" ++#ifndef THISPROG ++# define THISPROG "/etc/suid_exec" ++#endif ++#ifndef DEFSHELL ++# define DEFSHELL "/bin/sh" ++#endif + ++#if defined(__linux__) ++static void error_exit(const char*) __attribute__ ((noreturn)); ++#ifndef _lib_setregid ++#define _lib_setregid 1 ++#endif ++#ifndef _lib_setreuid ++#define _lib_setreuid 1 ++#endif ++#else + static void error_exit(const char*); ++#endif + static int in_dir(const char*, const char*); + static int endsh(const char*); + #ifndef _lib_setregid +@@ -76,7 +90,7 @@ static int endsh(const char*); + static int mycopy(int, int); + static void maketemp(char*); + #else +- static void setids(int,int,int); ++ static void setids(int,uid_t,gid_t); + #endif /* _lib_setreuid */ + + static const char version[] = "\n@(#)$Id: suid_exec "SH_RELEASE" $\n"; +@@ -221,7 +235,7 @@ int main(int argc,char *argv[]) + if(effuid != ruserid) + mode |= S_ISUID; + } +- else if(effuid) ++ else if(effuid != euserid) + { + if(effuid != ruserid || setuid(ruserid) < 0) + mode = S_ISUID; +@@ -233,13 +247,18 @@ int main(int argc,char *argv[]) + exec: + #endif /* _lib_setreuid */ + /* only use SHELL if file is in trusted directory and ends in sh */ ++#ifndef __linux__ + shell = getenv("SHELL"); + if(shell == 0 || !endsh(shell) || ( + !in_dir("/bin",shell) && + !in_dir("/usr/bin",shell) && +- !in_dir("/usr/lbin",shell) && + !in_dir("/usr/local/bin",shell))) + shell = DEFSHELL; ++#else ++ shell = DEFSHELL; ++ if(!endsh(shell)) ++ error_exit(badexec); ++#endif + argv[0] = command; + argv[1] = (char*)devfd; + execv(shell,argv); +@@ -249,7 +268,7 @@ exec: + /* + * return true of shell ends in sh of ksh + */ +- ++#ifndef __linux__ + static int endsh(register const char *shell) + { + while(*shell) +@@ -262,7 +281,20 @@ static int endsh(register const char *sh + return(1); + return(0); + } +- ++#else ++static int endsh(const char *shell) ++{ ++ char * shx; ++ while ((shx = getusershell())) { ++ if (strcmp(shx, shell) == 0) { ++ endusershell(); ++ return(1); ++ } ++ } ++ endusershell(); ++ return(0); ++} ++#endif + + /* + * return true of shell is in directory +@@ -341,16 +373,30 @@ int eaccess(register const char *name, r + } + + #ifdef _lib_setreuid +-static void setids(int mode,int owner,int group) ++#include ++#include ++#include ++static void setids(int mode,uid_t owner,gid_t group) + { +- if(mode & S_ISGID) +- setregid(rgroupid,group); ++ if(mode & S_ISGID) { ++ struct passwd *pwd; ++ ++ if (setregid(rgroupid,group)) ++ error_exit(badexec); ++ ++ if (((pwd = getpwuid(owner)) == (struct passwd*)0) || !(pwd->pw_name)) ++ error_exit(badexec); ++ ++ if (initgroups (pwd->pw_name, group)) ++ error_exit(badexec); ++ } + + /* set effective uid even if S_ISUID is not set. This is because + * we are *really* executing EUID root at this point. Even if S_ISUID + * is not set, the value for owner that is passsed should be correct. + */ +- setreuid(ruserid,owner); ++ if (setreuid(ruserid,owner)) ++ error_exit(badexec); + } + + #else diff --git a/ksh93-test.dif b/ksh93-test.dif new file mode 100644 index 0000000..cbd3723 --- /dev/null +++ b/ksh93-test.dif @@ -0,0 +1,36 @@ +--- src/cmd/ksh93/bltins/test.c ++++ src/cmd/ksh93/bltins/test.c 2011-05-20 13:45:25.000000000 +0000 +@@ -47,12 +47,12 @@ + #ifdef S_ISSOCK + # if _pipe_socketpair + # if _socketpair_shutdown_mode +-# define isapipe(f,p) (test_stat(f,p)>=0&&S_ISFIFO((p)->st_mode)||S_ISSOCK((p)->st_mode)&&(p)->st_ino&&((p)->st_mode&(S_IRUSR|S_IWUSR))!=(S_IRUSR|S_IWUSR)) ++# define isapipe(f,p) (test_stat(f,p)>=0&&(S_ISFIFO((p)->st_mode)||(S_ISSOCK((p)->st_mode)&&(p)->st_ino&&((p)->st_mode&(S_IRUSR|S_IWUSR))!=(S_IRUSR|S_IWUSR)))) + # else +-# define isapipe(f,p) (test_stat(f,p)>=0&&S_ISFIFO((p)->st_mode)||S_ISSOCK((p)->st_mode)&&(p)->st_ino) ++# define isapipe(f,p) (test_stat(f,p)>=0&&(S_ISFIFO((p)->st_mode)||S_ISSOCK((p)->st_mode)&&(p)->st_ino)) + # endif + # else +-# define isapipe(f,p) (test_stat(f,p)>=0&&S_ISFIFO((p)->st_mode)||S_ISSOCK((p)->st_mode)&&(p)->st_ino) ++# define isapipe(f,p) (test_stat(f,p)>=0&&(S_ISFIFO((p)->st_mode)||S_ISSOCK((p)->st_mode)&&(p)->st_ino)) + # endif + # define isasock(f,p) (test_stat(f,p)>=0&&S_ISSOCK((p)->st_mode)) + #else +@@ -87,7 +87,7 @@ static int test_strmatch(Shell_t *shp,co + regoff_t match[2*(MATCH_MAX+1)],n; + register int c, m=0; + register const char *cp=pat; +- while(c = *cp++) ++ while((c = *cp++)) + { + if(c=='(') + m++; +@@ -463,7 +463,7 @@ int test_unop(Shell_t *shp,register int + + int test_binop(Shell_t *shp,register int op,const char *left,const char *right) + { +- register double lnum,rnum; ++ register double lnum = 0, rnum = 0; + if(op&TEST_ARITH) + { + while(*left=='0') diff --git a/ksh93-typedef.dif b/ksh93-typedef.dif new file mode 100644 index 0000000..f4c76d4 --- /dev/null +++ b/ksh93-typedef.dif @@ -0,0 +1,37 @@ +--- src/cmd/ksh93/bltins/typeset.c ++++ src/cmd/ksh93/bltins/typeset.c 2013-03-19 17:21:08.667413362 +0100 +@@ -461,6 +461,7 @@ static void print_value(Sfio_t *iop, Nam + { + char *name; + int aflag=tp->aflag; ++ Namval_t *table; + if(nv_isnull(np)) + { + if(!np->nvflag) +@@ -504,7 +505,9 @@ static void print_value(Sfio_t *iop, Nam + sfwrite(iop,"}\n",2); + return; + } ++ table = tp->sh->last_table; + sfputr(iop,nv_name(np),aflag=='+'?'\n':'='); ++ tp->sh->last_table = table; + if(aflag=='+') + return; + if(nv_isarray(np) && nv_arrayptr(np)) +@@ -675,6 +678,7 @@ static int setall(char **argv,regist + { + if(comvar || (shp->last_root==shp->var_tree && (tp->tp || (!shp->st.real_fun && (nvflags&NV_STATIC)) || (!(flag&(NV_EXPORT|NV_RDONLY)) && nv_isattr(np,(NV_EXPORT|NV_IMPORT))==(NV_EXPORT|NV_IMPORT))))) + { ++ if((flag&(NV_HOST|NV_INTEGER))!=NV_HOST) + _nv_unset(np,0); + } + } +@@ -790,7 +794,7 @@ static int setall(char **argv,regist + else + { + char *oldname=0; +- int len=strlen(name); ++ size_t len=strlen(name); + if(tp->argnum==1 && newflag==NV_INTEGER && nv_isattr(np,NV_INTEGER)) + tp->argnum = 10; + if(np->nvfun && !nv_isarray(np) && name[len-1]=='.') diff --git a/ksh93-uname.dif b/ksh93-uname.dif new file mode 100644 index 0000000..6e0c8af --- /dev/null +++ b/ksh93-uname.dif @@ -0,0 +1,128 @@ +--- src/lib/libcmd/date.c ++++ src/lib/libcmd/date.c 2007-03-30 10:51:14.000000000 +0000 +@@ -226,10 +226,19 @@ settime(Shbltin_t* context, const char* + if (!adjust && !network) + return tmxsettime(now); + argv = args; ++#ifdef __linux__ ++ s = "/bin/date"; ++#else + s = "/usr/bin/date"; ++#endif + if (!streq(cmd, s) && (!eaccess(s, X_OK) || !eaccess(s+=4, X_OK))) + { + *argv++ = s; ++#ifdef __linux__ ++ tmxfmt(buf, sizeof(buf), "%m%d%H" "%M%Y.%S", now); ++ if (tm_info.flags & TM_UTC) ++ *argv++ = "--utc"; ++#else + if (streq(astconf("UNIVERSE", NiL, NiL), "att")) + { + tmxfmt(buf, sizeof(buf), "%m%d%H" "%M%Y.%S", now); +@@ -244,6 +253,7 @@ settime(Shbltin_t* context, const char* + if (tm_info.flags & TM_UTC) + *argv++ = "-u"; + } ++#endif + *argv++ = buf; + *argv = 0; + if (!sh_run(context, argv - args, args)) +--- src/lib/libcmd/uname.c ++++ src/lib/libcmd/uname.c 2007-03-28 16:38:01.000000000 +0000 +@@ -79,6 +79,7 @@ __STDPP__directive pragma pp:hide getdom + + #include + #include ++#include + #include + + #include "FEATURE/utsname" +@@ -86,9 +87,11 @@ __STDPP__directive pragma pp:hide getdom + #define MAXHOSTNAME 64 + + #if _lib_uname && _sys_utsname ++# include ++#endif + +-#include +- ++#ifdef __linux__ ++# include + #endif + + #if defined(__STDPP__directive) && defined(__STDPP__hide) +@@ -269,6 +272,9 @@ b_uname(int argc, char** argv, Shbltin_t + { + case 'a': + flags |= OPT_all|((1L< 0) { ++ if (strncmp(line, "vendor_id", 9) == 0) { ++ if (strstr(line, "AuthenticAMD")) ++ s = "athlon"; ++ break; ++ } ++ } ++ sfclose(io); ++ } ++ } ++ } ++#endif ++ if (!s && !*(s = astconf("ARCHITECTURE", NiL, NiL))) + s = ut.machine; + output(OPT_processor, s, "processor"); + } + if (flags & OPT_implementation) + { +- if (!*(s = astconf("PLATFORM", NiL, NiL)) && !*(s = astconf("HW_NAME", NiL, NiL))) ++ s = NULL; ++#ifdef __linux__ ++ if (!s) { ++ strcpy((s = buf), ut.machine); ++ if (s[0] == 'i' && s[2] == '8' && s[3] == '6' && s[4] == '\0') ++ s[1] = '3'; ++ } ++#endif ++ if (!s && !*(s = astconf("PLATFORM", NiL, NiL)) && !*(s = astconf("HW_NAME", NiL, NiL))) + { + if (t = strchr(hosttype, '.')) + t++; diff --git a/ksh93-uninitialized.dif b/ksh93-uninitialized.dif new file mode 100644 index 0000000..39cd9d0 --- /dev/null +++ b/ksh93-uninitialized.dif @@ -0,0 +1,361 @@ +--- src/cmd/builtin/pty.c ++++ src/cmd/builtin/pty.c 2013-10-25 13:30:22.019295258 +0000 +@@ -503,7 +503,7 @@ masterline(Sfio_t* mp, Sfio_t* lp, char* + char* t; + ssize_t n; + ssize_t a; +- size_t promptlen; ++ size_t promptlen = 0; + ptrdiff_t d; + char promptbuf[64]; + +@@ -773,6 +773,8 @@ dialogue(Sfio_t* mp, Sfio_t* lp, int del + !(master->buf = vmnewof(vm, 0, char, 2 * SF_BUFSIZE, 0))) + { + error(ERROR_SYSTEM|2, "out of space"); ++ id = 0; ++ line = 0; + goto done; + } + master->vm = vm; +--- src/cmd/ksh93/edit/edit.c ++++ src/cmd/ksh93/edit/edit.c 2013-10-25 13:30:22.020295166 +0000 +@@ -1414,12 +1414,12 @@ int ed_internal(const char *src, genchar + int ed_external(const genchar *src, char *dest) + { + register genchar wc; +- register int c,size; + register char *dp = dest; + char *dpmax = dp+sizeof(genchar)*MAXLINE-2; + if((char*)src == dp) + { +- char buffer[MAXLINE*sizeof(genchar)]; ++ int c; ++ char buffer[MAXLINE*sizeof(genchar)] = ""; + c = ed_external(src,buffer); + + #ifdef _lib_wcscpy +@@ -1431,6 +1431,7 @@ int ed_external(const genchar *src, char + } + while((wc = *src++) && dpsh_name;tp++) + n++; + np = (Namval_t*)calloc(n,sizeof(Namval_t)); +--- src/cmd/ksh93/sh/macro.c ++++ src/cmd/ksh93/sh/macro.c 2013-10-25 13:30:22.021295073 +0000 +@@ -1794,7 +1794,7 @@ retry2: + register int d = (mode=='@'?' ':mp->ifs); + regoff_t match[2*(MATCH_MAX+1)]; + int nmatch, nmatch_prev, vsize_last; +- char *vlast; ++ char *vlast=NULL; + while(1) + { + if(!v) +--- src/cmd/ksh93/sh/name.c ++++ src/cmd/ksh93/sh/name.c 2013-10-25 13:30:22.022294981 +0000 +@@ -1344,7 +1344,7 @@ Namval_t *nv_open(const char *name, Dt_t + const char *msg = e_varname; + char *fname = 0; + int offset = staktell(); +- Dt_t *funroot; ++ Dt_t *funroot = NIL(Dt_t*); + #if NVCACHE + struct Cache_entry *xp; + #endif +@@ -1820,7 +1820,7 @@ void nv_putval(register Namval_t *np, co + else + { + const char *tofree=0; +- int offset,append; ++ int offset=0,append; + #if _lib_pathnative + char buff[PATH_MAX]; + #endif /* _lib_pathnative */ +--- src/cmd/ksh93/sh/nvdisc.c ++++ src/cmd/ksh93/sh/nvdisc.c 2013-10-25 13:30:22.022294981 +0000 +@@ -449,7 +449,7 @@ static Sfdouble_t lookupn(Namval_t *np, + char *nv_setdisc(register Namval_t* np,register const char *event,Namval_t *action,register Namfun_t *fp) + { + register struct vardisc *vp = (struct vardisc*)np->nvfun; +- register int type; ++ register int type = -1; + char *empty = ""; + while(vp) + { +@@ -505,6 +505,8 @@ char *nv_setdisc(register Namval_t* np,r + } + return(NIL(char*)); + } ++ if (type < 0) ++ return(NIL(char*)); + /* Handle GET/SET/APPEND/UNSET disc */ + if(vp && vp->fun.disc->putval!=assign) + vp = 0; +--- src/cmd/ksh93/sh/nvtree.c ++++ src/cmd/ksh93/sh/nvtree.c 2013-10-25 13:30:22.023294889 +0000 +@@ -583,7 +583,7 @@ void nv_outnode(Namval_t *np, Sfio_t* ou + char *fmtq,*ep,*xp; + Namval_t *mp; + Namarr_t *ap = nv_arrayptr(np); +- int scan,tabs=0,c,more,associative = 0; ++ int scan=0,tabs=0,c,more,associative = 0; + int saveI = Indent; + Indent = indent; + if(ap) +@@ -696,7 +696,7 @@ void nv_outnode(Namval_t *np, Sfio_t* ou + + static void outval(char *name, const char *vname, struct Walk *wp) + { +- register Namval_t *np, *nq, *last_table=wp->shp->last_table; ++ register Namval_t *np, *nq=0, *last_table=wp->shp->last_table; + register Namfun_t *fp; + int isarray=0, special=0,mode=0; + if(*name!='.' || vname[strlen(vname)-1]==']') +--- src/cmd/ksh93/sh/nvtype.c ++++ src/cmd/ksh93/sh/nvtype.c 2013-10-25 13:30:22.023294889 +0000 +@@ -854,9 +854,10 @@ void nv_newtype(Namval_t *mp) + Namval_t *nv_mktype(Namval_t **nodes, int numnodes) + { + Namval_t *mp=nodes[0], *bp=0, *np, *nq, **mnodes=nodes; +- int i,j,k,m,n,nd=0,nref=0,iref=0,inherit=0; ++ int i,j,k,nd=0,nref=0,iref=0,inherit=0; + int size=sizeof(NV_DATA), dsize=0, nnodes; +- size_t offset=0; ++ size_t offset=0,m; ++ ssize_t n; + char *name=0, *cp, *sp, **help; + Namtype_t *pp,*qp=0,*dp,*tp; + Dt_t *root = nv_dict(mp); +@@ -869,6 +870,7 @@ Namval_t *nv_mktype(Namval_t **nodes, in + _nv_unset(nodes[0],NV_RDONLY); + errormsg(SH_DICT,ERROR_exit(1),e_badtypedef,cp); + } ++ n=strlen(nodes[1]->nvname); + for(nnodes=1,i=1; i childfun.fun, NV_LAST); + if(tp = (Namtype_t*)nv_hasdisc(nq, &type_disc)) + tp->strsize = -tp->strsize; +-else sfprintf(sfstderr,"tp==NULL\n"); + for(r=0; r < dp->numnodes; r++) + { + Namval_t *nr = nv_namptr(dp->nodes,r); +--- src/cmd/ksh93/sh/parse.c ++++ src/cmd/ksh93/sh/parse.c 2013-10-25 13:30:22.024294796 +0000 +@@ -301,7 +301,7 @@ static Shnode_t *getanode(Lex_t *lp, str + */ + static Shnode_t *makelist(Lex_t *lexp, int type, Shnode_t *l, Shnode_t *r) + { +- register Shnode_t *t; ++ register Shnode_t *t = NIL(Shnode_t*); + if(!l || !r) + sh_syntax(lexp); + else +@@ -742,7 +742,7 @@ static Shnode_t *funct(Lex_t *lexp) + register Shnode_t *t; + register int flag; + struct slnod *volatile slp=0; +- Stak_t *savstak; ++ Stak_t *savstak = NIL(Stak_t*); + Sfoff_t first, last; + struct functnod *volatile fp; + Sfio_t *iop; +@@ -815,7 +815,7 @@ static Shnode_t *funct(Lex_t *lexp) + { + struct comnod *ac; + char *cp, **argv, **argv0; +- int c; ++ int c=-1; + t->funct.functargs = ac = (struct comnod*)simple(lexp,SH_NOIO|SH_FUNDEF,NIL(struct ionod*)); + if(ac->comset || (ac->comtyp&COMSCAN)) + errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax4,lexp->sh->inlineno); +--- src/cmd/ksh93/sh/xec.c ++++ src/cmd/ksh93/sh/xec.c 2013-10-25 13:30:22.025294704 +0000 +@@ -1507,7 +1507,7 @@ int sh_exec(register const Shnode_t *t, + Namval_t node; + #endif /* SHOPT_NAMESPACE */ + struct Namref nr; +- long mode; ++ long mode = 0; + register struct slnod *slp; + if(!np->nvalue.ip) + { +@@ -1916,8 +1916,8 @@ int sh_exec(register const Shnode_t *t, + * don't create a new process, just + * save and restore io-streams + */ +- pid_t pid; +- int jmpval, waitall; ++ pid_t pid = 0; ++ int jmpval, waitall = 0; + int simple = (t->fork.forktre->tre.tretyp&COMMSK)==TCOM; + struct checkpt *buffp = (struct checkpt*)stkalloc(shp->stk,sizeof(struct checkpt)); + #if SHOPT_COSHELL +@@ -2409,7 +2409,7 @@ int sh_exec(register const Shnode_t *t, + Shnode_t *tt = t->wh.whtre; + #if SHOPT_FILESCAN + Sfio_t *iop=0; +- int savein; ++ int savein=-1; + #endif /*SHOPT_FILESCAN*/ + #if SHOPT_OPTIMIZE + int jmpval = ((struct checkpt*)shp->jmplist)->mode; +@@ -2877,7 +2877,7 @@ int sh_exec(register const Shnode_t *t, + else + { + register int traceon=0; +- register char *right; ++ register char *right = 0; + register char *trap; + char *argv[6]; + n = type>>TSHIFT; +@@ -2911,7 +2911,7 @@ int sh_exec(register const Shnode_t *t, + } + else if(type&TBINARY) + { +- char *op; ++ char *op = 0; + int pattern = 0; + if(trap || traceon) + op = (char*)(shtab_testops+(n&037)-1)->sh_name; +@@ -3376,7 +3376,7 @@ int sh_funscope(int argn, char *argv[],i + int jmpval; + volatile int r = 0; + int n; +- char *savstak; ++ char *savstak = 0; + struct funenv *fp = 0; + struct checkpt *buffp = (struct checkpt*)stkalloc(shp->stk,sizeof(struct checkpt)); + Namval_t *nspace = shp->namespace; +@@ -3492,10 +3492,10 @@ int sh_funscope(int argn, char *argv[],i + shp->st = *prevscope; + shp->topscope = (Shscope_t*)prevscope; + nv_getval(sh_scoped(shp,IFSNOD)); +- if(nsig) ++ if(nsig && savstak) + memcpy((char*)&shp->st.trapcom[0],savstak,nsig); + shp->trapnote=0; +- if(nsig) ++ if(nsig && savstak) + stakset(savstak,0); + shp->options = options; + shp->last_root = last_root; +@@ -3584,11 +3584,11 @@ static void sh_funct(Shell_t *shp,Namval + int sh_fun(Namval_t *np, Namval_t *nq, char *argv[]) + { + Shell_t *shp = sh_getinterp(); +- register int offset; ++ register int offset = 0; + register char *base; + Namval_t node; + struct Namref nr; +- long mode; ++ long mode = 0; + char *prefix = shp->prefix; + int n=0; + char *av[3]; +--- src/lib/libast/sfio/sfstrtof.h ++++ src/lib/libast/sfio/sfstrtof.h 2013-10-25 13:30:22.025294704 +0000 +@@ -211,8 +211,8 @@ S2F_function(str, end) char* str; char** + int decimal = 0; + int thousand = 0; + int part = 0; +- int back_part; +- S2F_batch back_n; ++ int back_part = 0; ++ S2F_batch back_n = 0; + S2F_number v; + S2F_number p; + S2F_part_t parts[16]; +--- src/lib/libast/sfio/sftable.c ++++ src/lib/libast/sfio/sftable.c 2013-10-25 13:30:22.026294612 +0000 +@@ -53,7 +53,7 @@ int type; /* >0: scanf, =0: printf, -1: + #endif + { + int base, fmt, flags, dot, width, precis; +- ssize_t n_str, size; ++ ssize_t n_str, size = 0; + char *t_str, *sp; + int v, n, skip, dollar, decimal, thousand; + Sffmt_t savft; +--- src/lib/libast/sfio/sfvprintf.c ++++ src/lib/libast/sfio/sfvprintf.c 2013-10-25 13:30:22.026294612 +0000 +@@ -101,7 +101,7 @@ char* form; /* format to use */ + va_list args; /* arg list if !argf */ + #endif + { +- int n, v, w, k, n_s, base, fmt, flags; ++ int n, v=0, w, k, n_s, base, fmt, flags; + Sflong_t lv; + char *sp, *ssp, *endsp, *ep, *endep; + int dot, width, precis, sign, decpt; +@@ -129,7 +129,7 @@ va_list args; /* arg list if !argf */ + int decimal = 0, thousand = 0; + + #if _has_multibyte +- wchar_t* wsp; ++ wchar_t* wsp = 0; + SFMBDCL(fmbs) /* state of format string */ + SFMBDCL(mbs) /* state of some string */ + #ifdef mbwidth +--- src/lib/libast/string/stropt.c ++++ src/lib/libast/string/stropt.c 2013-10-25 13:30:22.033293966 +0000 +@@ -60,13 +60,13 @@ stropt(const char* as, const void* tab, + register char* v; + register char* t; + char** p; +- char* u; ++ char* u = 0; + char* x; + char* e; + int n; + int ql; + int qr; +- int qc; ++ int qc = 0; + + if (!as) n = 0; + else if (!(x = s = strdup(as))) n = -1; +--- src/lib/libast/string/strtoi.h ++++ src/lib/libast/string/strtoi.h 2013-10-25 13:30:22.027294520 +0000 +@@ -230,13 +230,13 @@ S2I_function(a, e, base) const char* a; + #endif + register S2I_unumber n; + register S2I_unumber x; +- register int c; ++ register int c = 0; + register int shift; + register unsigned char* p; + register unsigned char* cv; + unsigned char* b; + unsigned char* k; +- S2I_unumber v; ++ S2I_unumber v = 0; + #if S2I_multiplier + register int base; + #endif diff --git a/ksh93-unset-f.dif b/ksh93-unset-f.dif new file mode 100644 index 0000000..5630e10 --- /dev/null +++ b/ksh93-unset-f.dif @@ -0,0 +1,12 @@ +--- src/cmd/ksh93/sh/xec.c ++++ src/cmd/ksh93/sh/xec.c 2011-07-04 15:42:21.000000000 +0000 +@@ -3387,7 +3387,8 @@ int sh_funscope(int argn, char *argv[],i + shp->st.var_local = shp->var_tree; + if(!fun) + { +- shp->st.filename = fp->node->nvalue.rp->fname; ++ if (fp->node->nvalue.rp) ++ shp->st.filename = fp->node->nvalue.rp->fname; + shp->st.funname = nv_name(fp->node); + shp->last_root = nv_dict(DOTSHNOD); + nv_putval(SH_PATHNAMENOD,shp->st.filename,NV_NOFREE); diff --git a/ksh93-untrustedenv.dif b/ksh93-untrustedenv.dif new file mode 100644 index 0000000..358849b --- /dev/null +++ b/ksh93-untrustedenv.dif @@ -0,0 +1,51 @@ +--- src/cmd/ksh93/sh/arith.c.orig ++++ src/cmd/ksh93/sh/arith.c +@@ -513,21 +513,34 @@ Sfdouble_t sh_strnum(register const char *str, char** ptr, int mode) + char base=(shp->inarith?0:10), *last; + if(*str==0) + { +- if(ptr) +- *ptr = (char*)str; +- return(0); +- } +- errno = 0; +- d = strtonll(str,&last,&base,-1); +- if(*last || errno) +- { +- if(!last || *last!='.' || last[1]!='.') +- d = strval(shp,str,&last,arith,mode); +- if(!ptr && *last && mode>0) +- errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*last,str); ++ d = 0.0; ++ last = (char*)str; ++ } else { ++ errno = 0; ++ d = strtonll(str,&last,&base,-1); ++ if (*last && !shp->inarith && sh_isstate(SH_INIT)) { ++ // This call is to handle "base#value" literals if we're importing untrusted env vars. ++ errno = 0; ++ d = strtonll(str, &last, NULL, -1); ++ } ++ ++ if(*last || errno) ++ { ++ if (sh_isstate(SH_INIT)) { ++ // Initializing means importing untrusted env vars. Since the string does not appear ++ // to be a recognized numeric literal give up. We can't safely call strval() since ++ // that allows arbitrary expressions which would create a security vulnerability. ++ d = 0.0; ++ } else { ++ if(!last || *last!='.' || last[1]!='.') ++ d = strval(shp,str,&last,arith,mode); ++ if(!ptr && *last && mode>0) ++ errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*last,str); ++ } ++ } else if (!d && *str=='-') { ++ d = -0.0; ++ } + } +- else if (!d && *str=='-') +- d = -0.0; + if(ptr) + *ptr = last; + return(d); diff --git a/ksh93-vi.dif b/ksh93-vi.dif new file mode 100644 index 0000000..04d676b --- /dev/null +++ b/ksh93-vi.dif @@ -0,0 +1,60 @@ +--- src/cmd/ksh93/edit/vi.c ++++ src/cmd/ksh93/edit/vi.c 2007-03-28 16:41:47.000000000 +0000 +@@ -401,6 +401,8 @@ int ed_viread(void *context, int fd, reg + + if(!yankbuf) + yankbuf = (genchar*)malloc(MAXLINE*CHARSIZE); ++ if (!vp->lastline) ++ vp->lastline = (genchar*)malloc(MAXLINE*CHARSIZE); + if( vp->last_cmd == '\0' ) + { + /*** first time for this shell ***/ +@@ -410,6 +412,8 @@ int ed_viread(void *context, int fd, reg + vp->lastmotion = '\0'; + vp->lastrepeat = 1; + vp->repeat = 1; ++ if (!yankbuf) ++ return(-1); + *yankbuf = 0; + } + +@@ -1137,7 +1141,7 @@ static void cdelete(Vi_t *vp,register in + + /*** save characters to be deleted ***/ + +- if( mode != 'c' ) ++ if( mode != 'c' && yankbuf ) + { + i = cp[nchars]; + cp[nchars] = 0; +@@ -2169,6 +2173,9 @@ static void save_last(register Vi_t* vp) + { + register int i; + ++ if (vp->lastline == NULL) ++ return; ++ + if( (i = cur_virt - first_virt + 1) > 0 ) + { + /*** save last thing user typed ***/ +@@ -2417,6 +2424,11 @@ static int textmod(register Vi_t *vp,reg + p = yankbuf; + } + ++ if (!p) ++ { ++ return(BAD); ++ } ++ + addin: + switch( c ) + { +@@ -2687,6 +2699,8 @@ yankeol: + vp->lastmotion = c; + if( c == 'y' ) + { ++ if (!yankbuf) ++ return(BAD); + gencpy(yankbuf, virtual); + } + else if(!delmotion(vp, c, 'y')) diff --git a/ksh93-vm.dif b/ksh93-vm.dif new file mode 100644 index 0000000..6fb3d75 --- /dev/null +++ b/ksh93-vm.dif @@ -0,0 +1,45 @@ +--- src/lib/libast/vmalloc/vmhdr.h ++++ src/lib/libast/vmalloc/vmhdr.h 2012-01-19 09:45:14.000000000 +0000 +@@ -152,6 +152,9 @@ extern void _vmmessage _ARG_((const cha + #endif /*DEBUG*/ + + #define VMPAGESIZE 8192 ++#if defined(__linux__) && !defined(_lib_getpagesize) ++#define _lib_getpagesize 1 ++#endif + #if _lib_getpagesize + #define GETPAGESIZE(x) ((x) ? (x) : ((x)=getpagesize()) ) + #else +--- src/lib/libast/vmalloc/vmmopen.c ++++ src/lib/libast/vmalloc/vmmopen.c 2012-01-20 11:13:12.000000000 +0000 +@@ -63,8 +63,10 @@ void _STUB_vmmapopen(){} + /* magic word signaling file/segment is ready */ + #define MM_MAGIC ((unsigned int)(('P'<<24) | ('&'<<16) | ('N'<<8) | ('8')) ) + ++#ifndef __linux__ + /* default mimimum region size */ + #define MM_MINSIZE (64*_Vmpagesize) ++#endif + + /* macros to get the data section and size */ + #define MMHEAD(file) ROUND(sizeof(Mmvm_t)+strlen(file), ALIGN) +@@ -166,10 +168,18 @@ static int mminit(Mmdisc_t* mmdc) + + if(mmdc->mmvm) /* already done this */ + return 0; +- ++#ifdef MM_MINSIZE + /* fixed size region so make it reasonably large */ + if((size = mmdc->size) < MM_MINSIZE ) + size = MM_MINSIZE; ++#else ++ if (sizeof(void*) > 32) ++ extent = ROUND(0x80000,_Vmpagesize); ++ else ++ extent = ROUND(0x40000,_Vmpagesize); ++ if((size = mmdc->size) < extent) ++ size = extent; ++#endif + size += MMHEAD(mmdc->file) + ALIGN; + size = ROUND(size, _Vmpagesize); + diff --git a/ksh93.dif b/ksh93.dif new file mode 100644 index 0000000..ca4a331 --- /dev/null +++ b/ksh93.dif @@ -0,0 +1,515 @@ +--- src/cmd/ksh93/bltins/print.c ++++ src/cmd/ksh93/bltins/print.c 2008-05-05 11:20:21.000000000 +0000 +@@ -105,7 +105,11 @@ static char* nullarg[] = { 0, 0 }; + { + static char bsd_univ; + struct print prdata; +- prdata.options = sh_optecho+5; ++# if defined(__linux__) ++ prdata.options = sh_optecho; ++# else ++ prdata.options = sh_optecho + 5; ++# endif + prdata.raw = prdata.echon = 0; + prdata.sh = context->shp; + NOT_USED(argc); +@@ -118,7 +122,52 @@ static char* nullarg[] = { 0, 0 }; + prdata.sh->universe = 1; + } + if(!bsd_univ) ++ { ++# if defined(__linux__) ++ char *opt = argv[1]; ++ while ((opt = argv[1]) && (*opt == '-')) ++ { ++ int c; ++ ++ opt++; ++ ++ for (c = 0; opt[c]; c++) ++# if !SHOPT_ECHOE ++ if (strchr("neE", opt[c]) == 0) ++# else ++ if (strchr("n", opt[c]) == 0) ++# endif /* SHOPT_ECHOE */ ++ break; ++ ++ if (*opt == 0 || opt[c]) ++ break; ++ ++ while ((c = *opt++)) ++ { ++ switch (c) { ++ case 'n': ++ prdata.echon = 1; ++ break; ++# if !SHOPT_ECHOE ++ case 'e': ++ prdata.raw = 0; ++ break; ++ case 'E': ++ prdata.raw = 1; ++ break; ++# endif /* SHOPT_ECHOE */ ++ default: ++ goto out; ++ break; ++ } ++ } ++ ++ argv++; ++ } ++ out: ++# endif + return(b_print(0,argv,(Shbltin_t*)&prdata)); ++ } + prdata.options = sh_optecho; + prdata.raw = 1; + while(argv[1] && *argv[1]=='-') +--- src/cmd/ksh93/data/msg.c ++++ src/cmd/ksh93/data/msg.c 2007-12-20 18:01:26.000000000 +0000 +@@ -202,7 +202,7 @@ const char e_bash_login[] = "$HOME/.bash + const char e_bash_logout[] = "$HOME/.bash_logout"; + const char e_bash_profile[] = "$HOME/.bash_profile"; + #endif +-const char e_crondir[] = "/usr/spool/cron/atjobs"; ++const char e_crondir[] = "/var/spool/cron"; + const char e_prohibited[] = "login setuid/setgid shells prohibited"; + #if SHOPT_SUID_EXEC + const char e_suidexec[] = "/etc/suid_exec"; +--- src/cmd/ksh93/data/variables.c ++++ src/cmd/ksh93/data/variables.c 2008-09-18 17:22:24.000000000 +0000 +@@ -69,7 +69,7 @@ const struct shtable2 shtab_variables[] + "OPTARG", 0, (char*)0, + "OPTIND", NV_NOFREE|NV_INTEGER, (char*)0, + "PS4", 0, (char*)0, +- "FPATH", 0, (char*)0, ++ "FPATH", NV_NOFREE, "/usr/share/ksh/fun", + "LANG", 0, (char*)0, + "LC_ALL", 0, (char*)0, + "LC_COLLATE", 0, (char*)0, +--- src/cmd/ksh93/features/options ++++ src/cmd/ksh93/features/options 2007-12-20 18:01:26.000000000 +0000 +@@ -36,7 +36,7 @@ tst cross{ + option TEST_L $? + test -f /etc/ksh.kshrc -o -f /etc/bash.bashrc && + option SYSRC 0 +- test -f /bin/universe && univ=`/bin/universe` > /dev/null 2>&1 -a ucb = "$univ" ++ test -x /bin/universe && univ=`/bin/universe` > /dev/null 2>&1 && test ucb = "$univ" + option UCB $? + }end + +--- src/cmd/ksh93/sh.1 ++++ src/cmd/ksh93/sh.1 2008-09-22 12:11:56.000000000 +0000 +@@ -200,7 +200,7 @@ separated by + .BR \(bv . + The standard output of each command but the last + is connected by a +-.IR pipe (2) ++.IR socketpair (2) + to the standard input of the next command. + Each command, + except possibly the last, +--- src/cmd/ksh93/sh/main.c ++++ src/cmd/ksh93/sh/main.c 2007-12-20 18:01:26.000000000 +0000 +@@ -113,9 +113,9 @@ int sh_source(Shell_t *shp, Sfio_t *iop, + } + + #ifdef S_ISSOCK +-#define REMOTE(m) (S_ISSOCK(m)||!(m)) ++#define REMOTE(m) ((S_ISSOCK((m).st_mode)||!((m).st_mode))&&!((m).st_ino)) + #else +-#define REMOTE(m) !(m) ++#define REMOTE(m) (!((m).st_mode)&&!((m).st_ino)) + #endif + + int sh_main(int ac, char *av[], Shinit_f userinit) +@@ -179,7 +179,7 @@ int sh_main(int ac, char *av[], Shinit_f + } + if(!sh_isoption(SH_RC) && (sh_isoption(SH_BASH) && !sh_isoption(SH_POSIX) + #if SHOPT_REMOTE +- || !fstat(0, &statb) && REMOTE(statb.st_mode) ++ || !fstat(0, &statb) && REMOTE(statb) + #endif + )) + sh_onoption(SH_RC); +--- src/cmd/ksh93/sh/xec.c ++++ src/cmd/ksh93/sh/xec.c 2012-01-26 12:07:46.000000000 +0000 +@@ -1015,7 +1015,7 @@ int sh_exec(register const Shnode_t *t, + { + case TCOM: + { +- register struct argnod *argp; ++ volatile struct argnod *argp; + char *trap; + Namval_t *np, *nq, *last_table; + struct ionod *io; +@@ -1131,7 +1131,7 @@ int sh_exec(register const Shnode_t *t, + comn = com[argn-1]; + } + io = t->tre.treio; +- if(shp->envlist = argp = t->com.comset) ++ if((shp->envlist = argp = t->com.comset)) + { + if(argn==0 || (np && nv_isattr(np,(BLT_DCL|BLT_SPC)))) + { +--- src/cmd/ksh93/tests/attributes.sh ++++ src/cmd/ksh93/tests/attributes.sh 2009-07-09 13:14:05.000000000 +0000 +@@ -199,7 +199,7 @@ hello worldhello worldhello world + [[ $v1 == "$b1" ]] || err_exit "v1=$v1 should be $b1" + [[ $v2 == "$x" ]] || err_exit "v1=$v2 should be $x" + if env '!=1' >/dev/null 2>&1 +-then [[ $(env '!=1' $SHELL -c 'echo ok' 2>/dev/null) == ok ]] || err_exit 'malformed environment terminates shell' ++then [[ $(env "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" '!=1' $SHELL -c 'echo ok' 2>/dev/null) == ok ]] || err_exit 'malformed environment terminates shell' + fi + unset var + typeset -b var +--- src/cmd/ksh93/tests/bracket.sh ++++ src/cmd/ksh93/tests/bracket.sh 2012-02-09 14:11:32.000000000 +0000 +@@ -221,6 +221,10 @@ done + [[ abcdcdabcde == {5}(ab|cd)e ]] || err_exit 'abcdcdabcd == {5}(ab|cd)e' + ) || err_exit 'errors with {..}(...) patterns' + [[ D290.2003.02.16.temp == D290.+(2003.02.16).temp* ]] || err_exit 'pattern match bug with +(...)' ++atime=$(stat -c '%X' $file) ++sleep 2 ++cat $file > /dev/null ++if [[ $atime -lt $(stat -c '%X' $file) ]] then + rm -rf $file + { + [[ -N $file ]] && err_exit 'test -N $tmp/*: st_mtime>st_atime after creat' +@@ -231,6 +235,7 @@ sleep 2 + read + [[ -N $file ]] && err_exit 'test -N $tmp/*: st_mtime>st_atime after read' + } > $file < $file ++fi + if rm -rf "$file" && ln -s / "$file" + then [[ -L "$file" ]] || err_exit '-L not working' + [[ -L "$file"/ ]] && err_exit '-L with file/ not working' +--- src/cmd/ksh93/tests/builtins.sh ++++ src/cmd/ksh93/tests/builtins.sh 2009-07-09 13:14:50.000000000 +0000 +@@ -344,7 +344,7 @@ wait $pid1 + (( $? == 1 )) || err_exit "wait not saving exit value" + wait $pid2 + (( $? == 127 )) || err_exit "subshell job known to parent" +-env= ++env="LD_LIBRARY_PATH=\$LD_LIBRARY_PATH" + v=$(getconf LIBPATH) + for v in ${v//,/ } + do v=${v#*:} +--- src/cmd/ksh93/tests/coprocess.sh ++++ src/cmd/ksh93/tests/coprocess.sh 2013-02-01 15:22:31.000000000 +0000 +@@ -113,15 +113,15 @@ do + cop=$! + exp=Done + print -p $'print hello | '$cat$'\nprint '$exp +- read -t 5 -p +- read -t 5 -p ++ read -t 50 -p ++ read -t 50 -p + got=$REPLY + if [[ $got != $exp ]] + then err_exit "${SHELL-ksh} $cat coprocess io failed -- got '$got', expected '$exp'" + fi + exec 5<&p 6>&p + exec 5<&- 6>&- +- { sleep 4; kill $cop; } 2>/dev/null & ++ { sleep 10; kill $cop; } 2>/dev/null & + spy=$! + if wait $cop 2>/dev/null + then kill $spy 2>/dev/null +@@ -134,10 +134,10 @@ do + echo line2 | grep 'line1' + } |& + SECONDS=0 count=0 +- while read -p -t 10 line ++ while read -p -t 100 line + do ((count++)) + done +- if (( SECONDS > 8 )) ++ if (( SECONDS > 80 )) + then err_exit "$cat coprocess read -p hanging (SECONDS=$SECONDS count=$count)" + fi + wait $! +@@ -160,7 +160,7 @@ do + wait $! + done + print +- ) 2>/dev/null | read -t 10 r ++ ) 2>/dev/null | read -t 100 r + [[ $r == $e ]] || err_exit "$cat coprocess timing bug -- expected $e, got '$r'" + + r= +@@ -173,8 +173,9 @@ do + wait $! + done + print $r +- ) 2>/dev/null | read -t 10 r ++ ) 2>/dev/null | read -t 100 r + [[ $r == $e ]] || err_exit "$cat coprocess command substitution bug -- expected $e, got '$r'" ++ kill $(jobs -p) 2>/dev/null + + ( + $cat |& +@@ -212,7 +213,7 @@ do + done + + trap 'sleep_pid=; kill $pid; err_exit "$cat coprocess 1 hung"' TERM +- { sleep 5; kill $$; } & ++ { sleep 10; kill $$; } & + sleep_pid=$! + $cat |& + pid=$! +@@ -226,7 +227,7 @@ do + [[ $sleep_pid ]] && kill $sleep_pid + + trap 'sleep_pid=; kill $pid; err_exit "$cat coprocess 2 hung"' TERM +- { sleep 5; kill $$; } & ++ { sleep 10; kill $$; } & + sleep_pid=$! + $cat |& + pid=$! +@@ -238,7 +239,7 @@ do + [[ $sleep_pid ]] && kill $sleep_pid + + trap 'sleep_pid=; kill $pid; err_exit "$cat coprocess 3 hung"' TERM +- { sleep 5; kill $$; } & ++ { sleep 10; kill $$; } & + sleep_pid=$! + $cat |& + pid=$! +--- src/cmd/ksh93/tests/locale.sh ++++ src/cmd/ksh93/tests/locale.sh 2011-05-24 14:46:02.000000000 +0000 +@@ -62,7 +62,7 @@ done + # this locale is supported by ast on all platforms + # EU for { decimal_point="," thousands_sep="." } + +-locale=C_EU.UTF-8 ++locale=de_DE.UTF-8 + + export LC_ALL=C + +@@ -111,11 +111,11 @@ set -- $($SHELL -c " + unset LC_CTYPE + export LANG=$locale + export LC_ALL=C +- command wc -C < $tmp/two_euro_chars.txt ++ command wc -m < $tmp/two_euro_chars.txt + unset LC_ALL +- command wc -C < $tmp/two_euro_chars.txt ++ command wc -m < $tmp/two_euro_chars.txt + export LC_ALL=C +- command wc -C < $tmp/two_euro_chars.txt ++ command wc -m < $tmp/two_euro_chars.txt + ") + got=$* + [[ $got == $exp ]] || err_exit "command wc LC_ALL default failed -- expected '$exp', got '$got'" +@@ -124,11 +124,11 @@ set -- $($SHELL -c " + then unset LC_CTYPE + export LANG=$locale + export LC_ALL=C +- wc -C < $tmp/two_euro_chars.txt ++ wc -m < $tmp/two_euro_chars.txt + unset LC_ALL +- wc -C < $tmp/two_euro_chars.txt ++ wc -m < $tmp/two_euro_chars.txt + export LC_ALL=C +- wc -C < $tmp/two_euro_chars.txt ++ wc -m < $tmp/two_euro_chars.txt + fi + ") + got=$* +@@ -336,7 +336,7 @@ then LC_ALL=en_US.UTF-8 + [[ $(print -r -- "$x") == $'hello\u[20ac]\xee world' ]] || err_exit '%q with unicode and non-unicode not working' + if [[ $(whence od) ]] + then got='68 65 6c 6c 6f e2 82 ac ee 20 77 6f 72 6c 64 0a' +- [[ $(print -r -- "$x" | od -An -tx1) == "$got" ]] || err_exit "incorrect string from printf %q" ++ [[ $(print -r -- "$x" | od -An -tx1) =~ "$got" ]] || err_exit "incorrect string from printf %q" + fi + + fi +--- src/cmd/ksh93/tests/options.sh ++++ src/cmd/ksh93/tests/options.sh 2012-01-16 16:50:59.000000000 +0000 +@@ -510,7 +510,7 @@ z=$($SHELL 2>&1 -uc 'print ${X2345678901 + [[ $z == *X23456789012345:* ]] || err_exit "error message garbled with set -u got $z" + + # pipe hang bug fixed 2011-03-15 +-float start=SECONDS toolong=3 ++float start=SECONDS toolong=8 + ( $SHELL <<-EOF + set -o pipefail + (sleep $toolong;kill \$\$> /dev/null) & +--- src/cmd/ksh93/tests/path.sh ++++ src/cmd/ksh93/tests/path.sh 2008-09-11 16:02:46.000000000 +0000 +@@ -269,7 +269,7 @@ builtin getconf + getconf UNIVERSE - att # override sticky default 'UNIVERSE = foo' + + [[ $(PATH=/usr/ucb/bin:/usr/bin echo -n ucb) == 'ucb' ]] || err_exit "ucb universe echo ignores -n option" +-[[ $(PATH=/usr/xpg/bin:/usr/bin echo -n att) == '-n att' ]] || err_exit "att universe echo does not ignore -n option" ++[[ $(PATH=/usr/xpg/bin:/usr/bin echo -n att) == 'att' ]] || err_exit "att universe echo ignores -n option" + + PATH=$path + +--- src/cmd/ksh93/tests/pty.sh ++++ src/cmd/ksh93/tests/pty.sh 2012-03-15 11:51:40.000000000 +0000 +@@ -428,15 +428,16 @@ r echo repeat-3 + + # err_exit # + whence -q less && +-TERM=vt100 tst $LINENO <<"!" ++TERM=xterm tst $LINENO <<"!" + L process/terminal group exercise + +-w m=yes; while true; do echo $m-$m; done | less ++w m=yes; while true; do echo $m-$m; done | less -b1 -c + u :$|:\E|lines + c \cZ + r Stopped + w fg + u yes-yes ++w q + ! + + exit $((Errors<125?Errors:125)) +--- src/cmd/ksh93/tests/signal.sh ++++ src/cmd/ksh93/tests/signal.sh 2011-05-20 13:25:48.000000000 +0000 +@@ -285,10 +285,10 @@ then for exp in TERM VTALRM PIPE + $SHELL <<- EOF + foo() { return 0; } + trap foo EXIT +- { sleep 2; kill -$exp \$\$; sleep 3; kill -0 \$\$ && kill -KILL \$\$; } & ++ { sleep 2; kill -$exp \$\$; sleep 8; kill -0 \$\$ && kill -KILL \$\$; } & + $yes | + while read yes +- do (/bin/date; sleep .1) ++ do (/bin/date; sleep .01) + done > /dev/null + EOF + } 2>> /dev/null +--- src/lib/libast/disc/memfatal.c ++++ src/lib/libast/disc/memfatal.c 2009-07-09 13:30:39.000000000 +0000 +@@ -74,7 +74,7 @@ memfatal(void) + { + Vmdisc_t* disc; + +- malloc(0); ++ void * ptr = malloc(0); + if (disc = vmdisc(Vmregion, NiL)) + disc->exceptf = nomalloc; + } +--- src/lib/libast/features/align.c ++++ src/lib/libast/features/align.c 2007-12-20 18:01:26.000000000 +0000 +@@ -32,6 +32,7 @@ + #include "FEATURE/common" + + #include ++#include + + union _u_ + { +--- src/lib/libast/features/botch.c ++++ src/lib/libast/features/botch.c 2007-12-20 18:01:26.000000000 +0000 +@@ -27,6 +27,7 @@ + * generate ast traps for botched standard prototypes + */ + ++#include + #include + + #include "FEATURE/lib" +--- src/lib/libast/features/lib ++++ src/lib/libast/features/lib 2007-12-20 18:01:26.000000000 +0000 +@@ -538,14 +538,19 @@ tst lib_utime_now note{ utime works with + }end + + tst cross{ +- u=att +- case `/bin/cat -s /dev/null/foo 2>&1` in +- '') ;; +- *) case `/bin/echo '\\t'` in +- '\t') u=ucb ;; ++ if test -n "$UNIVERSE" ++ then ++ u=$UNIVERSE ++ else ++ u=att ++ case `/bin/cat -s /dev/null/foo 2>&1` in ++ '') ;; ++ *) case `/bin/echo '\\t'` in ++ '\t') u=ucb ;; ++ esac ++ ;; + esac +- ;; +- esac ++ fi + echo "#define _UNIV_DEFAULT \"$u\" /* default universe name */" + }end + +--- src/lib/libast/misc/procopen.c ++++ src/lib/libast/misc/procopen.c 2007-12-20 18:01:26.000000000 +0000 +@@ -599,7 +599,7 @@ procopen(const char* cmd, char** argv, c + if (!fork()) + { + sfsprintf(path, sizeof(path), "%d", getppid()); +- execlp("trace", "trace", "-p", path, NiL); ++ execlp("trace", "trace", "-p", path, NULL); + _exit(EXIT_NOTFOUND); + } + sleep(2); +--- src/lib/libast/port/astwinsize.c ++++ src/lib/libast/port/astwinsize.c 2012-02-03 08:58:43.000000000 +0000 +@@ -29,6 +29,10 @@ + #include + #include + ++#if _sys_ioctl ++#include ++#endif ++ + #if defined(__STDPP__directive) && defined(__STDPP__hide) + __STDPP__directive pragma pp:hide ioctl sleep + #else +@@ -36,10 +40,6 @@ __STDPP__directive pragma pp:hide ioctl + #define sleep ______sleep + #endif + +-#if _sys_ioctl +-#include +-#endif +- + #if defined(TIOCGWINSZ) + #if _sys_stream && _sys_ptem + #include +--- src/lib/libast/sfio/sfstrtof.h ++++ src/lib/libast/sfio/sfstrtof.h 2007-12-20 18:01:26.000000000 +0000 +@@ -54,7 +54,7 @@ + + #if !defined(S2F_function) + #define S2F_function _sfdscan +-#define S2F_static 1 ++#define S2F_static -1 + #define S2F_type 2 + #define S2F_scan 1 + #ifndef elementsof +--- src/lib/libcmd/Mamfile ++++ src/lib/libcmd/Mamfile 2013-02-05 10:41:01.310073683 +0000 +@@ -897,7 +897,7 @@ exec - -e '/^b_[a-z_][a-z_0-9]*(/!d' \ + exec - -e 's/^b_//' \ + exec - -e 's/(.*//' \ + exec - -e 's/.*/CMDLIST(&)/' \ +-exec - | ++exec - cmdinit.c basename.c cat.c chgrp.c chmod.c chown.c cksum.c cmp.c comm.c cp.c cut.c dirname.c date.c expr.c fds.c fmt.c fold.c getconf.c head.c id.c join.c ln.c logname.c md5sum.c mkdir.c mkfifo.c mktemp.c mv.c paste.c pathchk.c pids.c rev.c rm.c rmdir.c stty.c sum.c sync.c tail.c tee.c tty.c uname.c uniq.c vmstate.c wc.c revlib.c wclib.c fts_fix.c lib.c | + exec - sort -u + exec - } > 1.${COTEMP}.h + exec - if cmp 2>/dev/null -s 1.${COTEMP}.h cmdlist.h +--- src/lib/libcmd/chmod.c ++++ src/lib/libcmd/chmod.c 2011-05-20 13:28:58.000000000 +0000 +@@ -272,7 +272,7 @@ b_chmod(int argc, char** argv, Shbltin_t + case FTS_SLNONE: + if (chlink) + { +-#if _lib_lchmod ++#if !defined(__linux__) && _lib_lchmod + chmodf = lchmod; + goto commit; + #else diff --git a/leak1.sh b/leak1.sh new file mode 100644 index 0000000..0f36834 --- /dev/null +++ b/leak1.sh @@ -0,0 +1,47 @@ +#!/usr/bin/ksh + +PATH=/bin:/usr/bin:/usr/sbin:/sbin + +getSampleInterval() { return 0; } +typeset -lui count=${1:-4000} +typeset -ilu leak=0 + +typeset -a curstate=(0 0 0) +typeset -a oldstate=(0 0 0) + +vm() +{ + typeset size + typeset key unit result="" + while read key size unit; do + case "$key" in + VmSize*) result=${result:+"$result "}$size ;; + VmRSS*) result=${result:+"$result "}$size ;; + VmData*) result=${result:+"$result "}$size ;; + esac + done < /proc/$$/status + echo $result +} + +lessequal() +{ + typeset -i ret=0 + ((${curstate[0]} > ${oldstate[0]})) && let ret=1 + ((${curstate[1]} > ${oldstate[1]})) && let ret=1 + ((${curstate[2]} > ${oldstate[2]})) && let ret=1 + return $ret +} + +oldstate=($(vm)) +while ((count-- > 0)) +do + interval=$(getSampleInterval) + + curstate=($(vm)) + lessequal || let leak++ + oldstate=(${curstate[@]}) + +done + +echo "[${0##*/}: leak count at $leak]" +((leak < 20)) || exit 1 diff --git a/leak2.sh b/leak2.sh new file mode 100644 index 0000000..caa82d0 --- /dev/null +++ b/leak2.sh @@ -0,0 +1,65 @@ +#!/usr/bin/ksh + +foo=0 +LoopCountForMEMSAP=0 +bla=234 +typeset -lui count=${1:-4000} +typeset -lui leak=0 + +typeset -a curstate=(0 0 0) +typeset -a oldstate=(0 0 0) + +vm() +{ + typeset size + typeset key unit result="" + while read key size unit; do + case "$key" in + VmSize*) result=${result:+"$result "}$size ;; + VmRSS*) result=${result:+"$result "}$size ;; + VmData*) result=${result:+"$result "}$size ;; + esac + done < /proc/$$/status + echo $result +} + +fusub() +{ + datum=`date +%S` + interval=$((10 - datum%10)) +} + +fvsub() +{ + datum=$(date +%S) + interval=$((10 - datum%10)) +} + +lessequal() +{ + typeset -i ret=0 + ((${curstate[0]} > ${oldstate[0]})) && let ret=1 + ((${curstate[1]} > ${oldstate[1]})) && let ret=1 + ((${curstate[2]} > ${oldstate[2]})) && let ret=1 + return $ret +} + +oldstate=($(vm)) +while ((count-- > 0)) +do + foo=$((foo+1)) + + if ((count%2 == 0)) ; then + datum=`fusub` + else + datum=$(fvsub) + fi + + curstate=($(vm)) + lessequal || let leak++ + oldstate=(${curstate[@]}) + +done + +echo "[${0##*/}: leak count at $leak]" +((leak < 60)) || exit 1 diff --git a/leak3.sh b/leak3.sh new file mode 100644 index 0000000..0a52307 --- /dev/null +++ b/leak3.sh @@ -0,0 +1,22 @@ +#!/bin/ksh + +a_sh=$(mktemp ${TMPDIR:-/tmp}/${0##*/}.XXXXXX) || exit 1 +trap "rm -f $a_sh" EXIT + +(cat > $a_sh) <<-EOF + #!$SHELL + check_proc_handle () + { + handleSoftLimit=$(ulimit -n) + echo \$handleSoftLimit > /dev/null + } + check_proc_handle +EOF +chmod +x $a_sh + +typeset -lui count=${1:-4000} + +while ((count-- > 0)) +do + $a_sh +done diff --git a/sigexec.c b/sigexec.c new file mode 100644 index 0000000..51f5d0c --- /dev/null +++ b/sigexec.c @@ -0,0 +1,227 @@ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static sig_atomic_t died; +static void sigchld(int sig __attribute__((__unused__))) +{ + const int old_errno = errno; + int status; + pid_t pid; + while ((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) != 0) { + if (errno == ECHILD) + break; + if (pid < 0) + continue; + died = 1; + } + errno = old_errno; +} + +static pid_t pid = -1; +static void sigother(int sig) +{ + printf("%s\n", strsignal(sig)); + if (sig == SIGINT) + sig = SIGTERM; + if (pid > 0) kill(pid, sig); +} + +int main(int argc, char* argv[]) +{ + int ptm, pts; + ssize_t len; + static struct termios o; + static struct winsize w; + char devname[NAME_MAX+1]; + char buffer[65536]; + sigset_t set; + struct sigaction sa; + + if (ioctl(0, TIOCGWINSZ, &w) < 0) { + w.ws_row = 24; + w.ws_col = 160; + errno = 0; + } + if (tcgetattr(0, &o) < 0) { +#ifdef B115200 + cfsetispeed(&o, B115200); + cfsetospeed(&o, B115200); +#elif defined(B57600) + cfsetispeed(&o, B57600); + cfsetospeed(&o, B57600); +#elif defined(B38400) + cfsetispeed(&o, B38400); + cfsetospeed(&o, B38400); +#endif + } + + o.c_iflag = TTYDEF_IFLAG; + o.c_oflag = TTYDEF_OFLAG; + o.c_lflag = TTYDEF_LFLAG; +# ifdef CBAUD + o.c_lflag &= ~CBAUD; +# endif +#ifdef B115200 + o.c_cflag = B115200; +#elif defined(B57600) + o.c_cflag = B57600; +#elif defined(B38400) + o.c_cflag = B38400; +#endif + o.c_cflag |= TTYDEF_CFLAG; + + /* Sane setting, allow eight bit characters, no carriage return delay + * the same result as `stty sane cr0 pass8' + */ + o.c_iflag |= (BRKINT | ICRNL | IMAXBEL); + o.c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | INPCK | ISTRIP); + o.c_oflag |= (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0); + o.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |\ + NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); + o.c_lflag |= (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOKE); + o.c_lflag &= ~(ECHONL|ECHOCTL|ECHOPRT | NOFLSH | XCASE | TOSTOP); + o.c_cflag |= (CREAD | CS8 | HUPCL); + o.c_cflag &= ~(PARODD | PARENB); + /* + * VTIME and VMIN can overlap with VEOF and VEOL since they are + * only used for non-canonical mode. We just set the at the + * beginning, so nothing bad should happen. + */ + o.c_cc[VTIME] = 0; + o.c_cc[VMIN] = CMIN; + o.c_cc[VINTR] = CINTR; + o.c_cc[VQUIT] = CQUIT; + o.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */ + o.c_cc[VKILL] = CKILL; + o.c_cc[VEOF] = CEOF; +# ifdef VSWTC + o.c_cc[VSWTC] = _POSIX_VDISABLE; +# else + o.c_cc[VSWTCH] = _POSIX_VDISABLE; +# endif + o.c_cc[VSTART] = CSTART; + o.c_cc[VSTOP] = CSTOP; + o.c_cc[VSUSP] = CSUSP; + o.c_cc[VEOL] = _POSIX_VDISABLE; + o.c_cc[VREPRINT] = CREPRINT; + o.c_cc[VDISCARD] = CDISCARD; + o.c_cc[VWERASE] = CWERASE; + o.c_cc[VLNEXT] = CLNEXT; + o.c_cc[VEOL2] = _POSIX_VDISABLE; + + if (openpty(&ptm, &pts, devname, &o, &w) < 0) { + perror("pty: can not open pty/tty pair"); + exit(1); + } + + (void)sigemptyset(&set); + (void)sigaddset(&set, SIGCHLD); + sigprocmask(SIG_UNBLOCK, &set, (sigset_t*)0); + + sa.sa_flags = SA_RESTART; + sa.sa_handler = sigchld; + sigemptyset (&sa.sa_mask); + sigaction(SIGCHLD, &sa, (struct sigaction*)0); + + (void)sigemptyset(&set); + (void)sigaddset(&set, SIGTERM); + sigprocmask(SIG_UNBLOCK, &set, (sigset_t*)0); + + sa.sa_flags = SA_RESTART; + sa.sa_handler = sigother; + sigemptyset (&sa.sa_mask); + sigaction(SIGTERM, &sa, (struct sigaction*)0); + + (void)sigemptyset(&set); + (void)sigaddset(&set, SIGHUP); + sigprocmask(SIG_UNBLOCK, &set, (sigset_t*)0); + + sa.sa_flags = SA_RESTART; + sa.sa_handler = sigother; + sigemptyset (&sa.sa_mask); + sigaction(SIGHUP, &sa, (struct sigaction*)0); + + switch ((pid = fork())) { + case 0: + ioctl(1, TIOCNOTTY); + if (setsid() < 0) { + perror("pty: can not get controlling tty"); + exit(1); + } + dup2(pts, 0); + dup2(pts, 1); + dup2(pts, 2); + close(pts); + close(ptm); + if (ioctl (0, TIOCSCTTY, 1) < 0) { + perror("pty: can not get controlling tty"); + exit(1); + } + break; + case -1: + close(pts); + close(ptm); + perror("pty: can not fork"); + exit(1); + default: + dup2(ptm, 0); + close(pts); + close(ptm); + while ((len = read(0, buffer, sizeof(buffer)))) { + ssize_t p = 0; + const char* ptr = buffer; + while (len > 0) { + p = write(1, ptr, len); + if (p < 0) { + if (errno == EPIPE) + exit (0); + if (errno == EINTR || errno == EAGAIN) + continue; + return 1; + } + ptr += p; + len -= p; + } + if (died) + break; + } + return 0; + } + + (void)sigfillset(&set); + sigprocmask(SIG_UNBLOCK, &set, (sigset_t*)0); + + (void)sigemptyset(&set); + (void)sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, (sigset_t*)0); + + sa.sa_flags = SA_RESTART; + sa.sa_handler = SIG_DFL; + sigemptyset (&sa.sa_mask); + + sigaction(SIGHUP, &sa, (struct sigaction*)0); + sigaction(SIGINT, &sa, (struct sigaction*)0); + sigaction(SIGPIPE, &sa, (struct sigaction*)0); + sigaction(SIGTERM, &sa, (struct sigaction*)0); + sigaction(SIGURG, &sa, (struct sigaction*)0); + sigaction(SIGXFSZ, &sa, (struct sigaction*)0); + sigaction(SIGQUIT, &sa, (struct sigaction*)0); + + sa.sa_handler = SIG_IGN; + sigaction(SIGQUIT, &sa, (struct sigaction*)0); + + return execv(argv[1], &argv[1]); +} diff --git a/ulimit.sh b/ulimit.sh new file mode 100644 index 0000000..f95ea5a --- /dev/null +++ b/ulimit.sh @@ -0,0 +1,17 @@ +#!/usr/bin/ksh + +PATH=/bin:/usr/bin:/usr/sbin:/sbin +typeset -lui count=${1:-4000} +typeset -ilu err=0 + +trap 'echo "[${0##*/}: error count at $err]"' ERR + +while ((count-- > 0)) +do + ulimit -s || let err++ + ulimit -n || let err++ + ulimit -q || let err++ +done > /dev/null + +echo "[${0##*/}: error count at $err]" +((err == 0)) || exit 1 diff --git a/vmbalance b/vmbalance new file mode 100644 index 0000000..8cc12c6 --- /dev/null +++ b/vmbalance @@ -0,0 +1,47 @@ +#!/usr/bin/awk -f +# +# vmblance Awk script to detect endless growing memory alloctions +# in endless shell loops using in daemonized shell scripts +# +# Usage: +# +# strace -s 128 -e execve,mmap,mmap2,munmap -o '|./vmbalance' ksh leak1.sh +# +BEGIN { + FS="([[:blank:]]|[[:punct:]])" + ignore="" + script="" + sum=0 + allocs=0 + frees=0 + left=0 + peak=0 +} +/^execve/ { + if (FNR == 1) { + script = gensub(/.*SOURCES\/([[:alnum:]_-]+\.sh).*/, "\\1", "g", $0) + } +} +/^mmap(2|64)?\(/ { + if ($0 !~ /.*MAP_PRIVATE\|MAP_ANONYMOUS.*/) { + if (ignore) + ignore=ignore "|" $NF + else + ignore=$NF + } else { + sum+=$4 + allocs++ + if (peak < sum) + peak = sum + } +} +/^munmap(2|64)?\(/ { + if ($0 !~ ignore) { + sum-=$4 + frees++ + } +} +END { + left=allocs-frees + print script ": " sum " bytes summed up, " peak " peak value, " left " chunks left over, " allocs " allocated, and " frees " freed" > "/dev/fd/3" +} diff --git a/workaround-stupid-build-system.diff b/workaround-stupid-build-system.diff new file mode 100644 index 0000000..626e34b --- /dev/null +++ b/workaround-stupid-build-system.diff @@ -0,0 +1,292 @@ +--- src/cmd/INIT/Mamfile ++++ src/cmd/INIT/Mamfile 2008-02-14 12:08:37.000000000 +0000 +@@ -5,7 +5,7 @@ setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS + setv ARFLAGS rc + setv AS as + setv ASFLAGS +-setv CC cc ++setv CC gcc + setv mam_cc_FLAGS + setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?} + setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??} +@@ -27,7 +27,7 @@ setv NMAKE nmake + setv NMAKEFLAGS + setv PR pr + setv PRFLAGS +-setv SHELL /bin/sh ++setv SHELL /bin/bash + setv SILENT + setv TAR tar + setv YACC yacc +--- src/cmd/INIT/iffe.sh ++++ src/cmd/INIT/iffe.sh 2008-02-14 12:15:59.000000000 +0000 +@@ -1170,7 +1170,7 @@ case `(getopts '[-][123:xyz]' opt --xyz; + --*) echo $command: $1: unknown option >&2 + exit 2 + ;; +- -*) REM=`echo X$1 | sed 's,X-,,'` ++ -*) REM=`echo -$1 | sed 's,^--,,'` + ;; + *) break + ;; +--- src/cmd/INIT/mamake.c ++++ src/cmd/INIT/mamake.c 2008-02-14 12:08:37.000000000 +0000 +@@ -118,7 +118,7 @@ USAGE_LICENSE + #define set(b,o) ((b)->nxt=(b)->buf+(o)) + #define use(b) (*(b)->nxt=0,(b)->nxt=(b)->buf) + +-#define CHUNK 1024 ++#define CHUNK 2048 + #define KEY(a,b,c,d) ((((unsigned long)(a))<<15)|(((unsigned long)(b))<<10)|(((unsigned long)(c))<<5)|(((unsigned long)(d)))) + #define NOW ((unsigned long)time((time_t*)0)) + #define ROTATE(p,l,r,t) ((t)=(p)->l,(p)->l=(t)->r,(t)->r=(p),(p)=(t)) +@@ -338,14 +338,14 @@ report(int level, char* text, char* item + */ + + static void +-dont(Rule_t* r, int code, int keepgoing) ++dont(Rule_t* r, int code, int keepgoing, int line) + { + identify(stderr); + if (!code) + fprintf(stderr, "don't know how to make %s\n", r->name); + else + { +- fprintf(stderr, "*** exit code %d making %s%s\n", code, r->name, state.ignore ? " ignored" : ""); ++ fprintf(stderr, "*** exit code %d making %s%s at line %d\n", code, r->name, state.ignore ? " ignored" : "", line); + unlink(r->name); + if (state.ignore) + return; +@@ -1259,7 +1259,7 @@ run(Rule_t* r, register char* s) + if (x) + { + if (c = execute(s)) +- dont(r, c, state.keepgoing); ++ dont(r, c, state.keepgoing, __LINE__); + if (status((Buf_t*)0, 0, r->name, &st)) + { + r->time = st.st_mtime; +@@ -1633,7 +1633,7 @@ make(Rule_t* r) + } + r->flags |= RULE_made; + if (!(r->flags & (RULE_dontcare|RULE_error|RULE_exists|RULE_generated|RULE_implicit|RULE_virtual))) +- dont(r, 0, state.keepgoing); ++ dont(r, 0, state.keepgoing, __LINE__); + break; + case KEY('e','x','e','c'): + r->flags |= RULE_generated; +@@ -1726,7 +1726,7 @@ verify(Dict_item_t* item, void* handle) + Rule_t* r = (Rule_t*)item->value; + + if ((r->flags & (RULE_active|RULE_error|RULE_made)) == RULE_active) +- dont(r, 0, 1); ++ dont(r, 0, 1, __LINE__); + return 0; + } + +--- src/cmd/ksh93/Mamfile ++++ src/cmd/ksh93/Mamfile 2012-02-10 14:30:31.000000000 +0000 +@@ -7,7 +7,7 @@ setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS + setv ARFLAGS rc + setv AS as + setv ASFLAGS +-setv CC cc ++setv CC gcc + setv mam_cc_FLAGS + setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?} + setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??} +@@ -29,7 +29,7 @@ setv NMAKE nmake + setv NMAKEFLAGS + setv PR pr + setv PRFLAGS +-setv SHELL /bin/sh ++setv SHELL /bin/bash + setv SILENT + setv TAR tar + setv YACC yacc +@@ -1337,7 +1337,7 @@ prev +ljobs + prev +li + prev ${mam_libsocket} + prev ${mam_libsecdb} +-exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o ksh pmain.o ${mam_libshell} ${mam_libnsl} ${mam_libast} ++exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o ksh pmain.o ${mam_libshell} ${mam_libnsl} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libast} + done ksh generated + make shcomp + make shcomp.o +@@ -1361,7 +1361,7 @@ prev ${mam_libsocket} + prev ${mam_libsecdb} + setv CC.DLL -UCC.DLL + setv SH_DICT -DSH_DICT="\"libshell\"" +-exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o shcomp shcomp.o ${mam_libshell} ${mam_libnsl} ${mam_libast} ++exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o shcomp shcomp.o ${mam_libshell} ${mam_libnsl} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libast} + done shcomp generated + make suid_exec + make suid_exec.o +@@ -1377,14 +1377,14 @@ meta suid_exec.o %.c>%.o sh/suid_exec.c + prev sh/suid_exec.c + setv CC.DLL -UCC.DLL + setv _BLD_shell -U_BLD_shell +-exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DERROR_CONTEXT_T=Error_context_t -D_API_ast=20100309 -D_PACKAGE_ast -c sh/suid_exec.c ++exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -fPIE -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DERROR_CONTEXT_T=Error_context_t -D_API_ast=20100309 -D_PACKAGE_ast -c sh/suid_exec.c + done suid_exec.o generated + prev +ljobs + prev +li + prev ${mam_libsocket} + prev ${mam_libsecdb} + setv CC.DLL -UCC.DLL +-exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o suid_exec suid_exec.o ${mam_libast} ${mam_libnsl} ${mam_libast} ++exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -pie -o suid_exec suid_exec.o ${mam_libast} ${mam_libnsl} ${mam_libast} + done suid_exec generated + make shell + prev libshell.a archive +--- src/lib/libast/Mamfile ++++ src/lib/libast/Mamfile 2013-02-05 15:08:23.757451837 +0000 +@@ -5,7 +5,7 @@ setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS + setv ARFLAGS rc + setv AS as + setv ASFLAGS +-setv CC cc ++setv CC gcc + setv mam_cc_FLAGS ${mam_cc_DLL} -D_BLD_ast + setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?} + setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??} +@@ -27,7 +27,7 @@ setv NMAKE nmake + setv NMAKEFLAGS + setv PR pr + setv PRFLAGS +-setv SHELL /bin/sh ++setv SHELL /bin/bash + setv SILENT + setv TAR tar + setv YACC yacc +@@ -1003,7 +1003,7 @@ make lcgen + make port/lcgen.c + prev std/stdio.h implicit + done port/lcgen.c +-exec - ${CC} -o lcgen port/lcgen.c ++exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -o lcgen port/lcgen.c + done lcgen generated + make port/lc.tab + done port/lc.tab +@@ -7291,58 +7291,31 @@ exec - test '' = 'misc/magic.tab' || ${S + done ${INSTALLROOT}/lib/file/magic generated + prev comp/fmtmsg.h + prev ast_lib.h +-exec - case ${mam_cc_HOSTTYPE} in +-exec - win32.*)proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/fmtmsg.h > 1.${COTEMP}.x +-exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/fmtmsg.h 1.${COTEMP}.x +-exec - then rm -f 1.${COTEMP}.x +-exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/fmtmsg.h +-exec - fi +-exec - ;; +-exec - *) silent grep -l 'define[ ][ ]*_[hl][di][rb]_fmtmsg' ast_lib.h > /dev/null || { ++exec - silent grep -l 'define[ ][ ]*_[hl][di][rb]_fmtmsg' ast_lib.h > /dev/null || { + exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/fmtmsg.h > 1.${COTEMP}.x + exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/fmtmsg.h 1.${COTEMP}.x + exec - then rm -f 1.${COTEMP}.x + exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/fmtmsg.h + exec - fi + exec - } +-exec - ;; +-exec - esac + prev comp/libgen.h + prev ast_lib.h +-exec - case ${mam_cc_HOSTTYPE} in +-exec - win32.*)proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/libgen.h > 1.${COTEMP}.x +-exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/libgen.h 1.${COTEMP}.x +-exec - then rm -f 1.${COTEMP}.x +-exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/libgen.h +-exec - fi +-exec - ;; +-exec - *) silent grep -l 'define[ ][ ]*_[hl][di][rb]_libgen' ast_lib.h > /dev/null || { ++exec - silent grep -l 'define[ ][ ]*_[hl][di][rb]_libgen' ast_lib.h > /dev/null || { + exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/libgen.h > 1.${COTEMP}.x + exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/libgen.h 1.${COTEMP}.x + exec - then rm -f 1.${COTEMP}.x + exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/libgen.h + exec - fi + exec - } +-exec - ;; +-exec - esac + prev comp/syslog.h + prev ast_lib.h +-exec - case ${mam_cc_HOSTTYPE} in +-exec - win32.*)proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/syslog.h > 1.${COTEMP}.x +-exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/syslog.h 1.${COTEMP}.x +-exec - then rm -f 1.${COTEMP}.x +-exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/syslog.h +-exec - fi +-exec - ;; +-exec - *) silent grep -l 'define[ ][ ]*_[hl][di][rb]_syslog' ast_lib.h > /dev/null || { ++exec - silent grep -l 'define[ ][ ]*_[hl][di][rb]_syslog' ast_lib.h > /dev/null || { + exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/syslog.h > 1.${COTEMP}.x + exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/syslog.h 1.${COTEMP}.x + exec - then rm -f 1.${COTEMP}.x + exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/syslog.h + exec - fi + exec - } +-exec - ;; +-exec - esac + done install virtual + make test + done test dontcare virtual +--- src/lib/libcmd/Mamfile ++++ src/lib/libcmd/Mamfile 2013-02-05 15:13:53.797951789 +0000 +@@ -7,7 +7,7 @@ setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS + setv ARFLAGS rc + setv AS as + setv ASFLAGS +-setv CC cc ++setv CC gcc + setv mam_cc_FLAGS ${mam_cc_DLL} + setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?} + setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??} +@@ -29,7 +29,7 @@ setv NMAKE nmake + setv NMAKEFLAGS + setv PR pr + setv PRFLAGS +-setv SHELL /bin/sh ++setv SHELL /bin/bash + setv SILENT + setv TAR tar + setv YACC yacc +--- src/lib/libdll/Mamfile ++++ src/lib/libdll/Mamfile 2008-02-14 12:08:37.000000000 +0000 +@@ -7,7 +7,7 @@ setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS + setv ARFLAGS rc + setv AS as + setv ASFLAGS +-setv CC cc ++setv CC gcc + setv mam_cc_FLAGS ${mam_cc_DLL} + setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?} + setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??} +@@ -29,7 +29,7 @@ setv NMAKE nmake + setv NMAKEFLAGS + setv PR pr + setv PRFLAGS +-setv SHELL /bin/sh ++setv SHELL /bin/bash + setv SILENT + setv TAR tar + setv YACC yacc +--- src/lib/libpp/Mamfile ++++ src/lib/libpp/Mamfile 2012-01-24 18:31:22.000000000 +0000 +@@ -663,7 +663,7 @@ exec - . + exec - w + exec - q + exec - ! +-exec - ${CC} -o ${COTEMP}.exe 1.${COTEMP}.c ++exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -o ${COTEMP}.exe 1.${COTEMP}.c + exec - ./${COTEMP}.exe > pp.yacc + exec - rm -f 1.${COTEMP}.c ${COTEMP}.exe + done pp.yacc generated +@@ -705,7 +705,7 @@ exec - . + exec - w + exec - q + exec - ! +-exec - ${CC} -o ${COTEMP}.exe 1.${COTEMP}.c ++exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -o ${COTEMP}.exe 1.${COTEMP}.c + exec - ./${COTEMP}.exe > ppkey.yacc + exec - rm -f 1.${COTEMP}.c ${COTEMP}.exe + done ppkey.yacc generated