From 54ca44b456c14a9eef317915dc3466a9ef6832fbcac6e5f3073c7e5a3c2851cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Schr=C3=B6der?= Date: Thu, 1 Aug 2024 12:13:15 +0000 Subject: [PATCH] - 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 --- .gitattributes | 23 + .gitignore | 1 + Agreement | 14 + CPL | 245 +++ EPL | 221 ++ INIT.2012-08-01.tar.bz2 | 3 + Warning | 26 + ast-base.2012-08-01.tar.bz2 | 3 + astksh_builtin_poll20120806_001.diff | 887 ++++++++ cpp.patch | 24 + ifs-crash.sh | 56 + ksh-locale.patch | 8 + ksh-rpmlintrc | 14 + ksh.changes | 2843 ++++++++++++++++++++++++++ ksh.spec | 904 ++++++++ ksh93-alias-k.dif | 13 + ksh93-aso.dif | 25 + ksh93-backtick.dif | 151 ++ ksh93-builtin.dif | 187 ++ ksh93-cdpwd.dif | 19 + ksh93-compat.dif | 83 + ksh93-disable-vfork.dif | 11 + ksh93-dttree-crash.dif | 960 +++++++++ ksh93-edpredict.dif | 40 + ksh93-env.dif | 22 + ksh93-fdstatus.dif | 1631 +++++++++++++++ ksh93-filedefined.dif | 35 + ksh93-foreground-prgrp.dif | 13 + ksh93-fs3d.dif | 62 + ksh93-gcc.dif | 65 + ksh93-gmt2utc.dif | 70 + ksh93-heredoc.dif | 11 + ksh93-heredoclex.dif | 19 + ksh93-ia64.dif | 40 + ksh93-int16double.dif | 22 + ksh93-joblock.dif | 31 + ksh93-jobs.dif | 35 + ksh93-jpold.dif | 10 + ksh93-limit-name-len.dif | 31 + ksh93-limits.dif | 122 ++ ksh93-longenv.dif | 65 + ksh93-malloc-hook.dif | 15 + ksh93-no-posix_spawn.dif | 11 + ksh93-no-sysctl.dif | 13 + ksh93-nvtree-free.dif | 11 + ksh93-optimizeleak.dif | 15 + ksh93-path-skip.dif | 13 + ksh93-pathtemp.dif | 114 ++ ksh93-profile.dif | 64 + ksh93-putval.dif | 15 + ksh93-redirectleak.dif | 20 + ksh93-reg.dif | 18 + ksh93-s390.dif | 22 + ksh93-sfio.dif | 263 +++ ksh93-shift_ijs.dif | 429 ++++ ksh93-signals.dif | 50 + ksh93-spawnlock.dif | 40 + ksh93-stkalias.dif | 33 + ksh93-stkfreeze.dif | 30 + ksh93-stkset-abort.dif | 11 + ksh93-subshellpwd.dif | 11 + ksh93-suid_exec.dif | 147 ++ ksh93-test.dif | 36 + ksh93-typedef.dif | 37 + ksh93-uname.dif | 128 ++ ksh93-uninitialized.dif | 361 ++++ ksh93-unset-f.dif | 12 + ksh93-untrustedenv.dif | 51 + ksh93-vi.dif | 60 + ksh93-vm.dif | 45 + ksh93.dif | 515 +++++ leak1.sh | 47 + leak2.sh | 65 + leak3.sh | 22 + sigexec.c | 227 ++ ulimit.sh | 17 + vmbalance | 47 + workaround-stupid-build-system.diff | 292 +++ 78 files changed, 12352 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Agreement create mode 100644 CPL create mode 100644 EPL create mode 100644 INIT.2012-08-01.tar.bz2 create mode 100644 Warning create mode 100644 ast-base.2012-08-01.tar.bz2 create mode 100644 astksh_builtin_poll20120806_001.diff create mode 100644 cpp.patch create mode 100644 ifs-crash.sh create mode 100644 ksh-locale.patch create mode 100644 ksh-rpmlintrc create mode 100644 ksh.changes create mode 100644 ksh.spec create mode 100644 ksh93-alias-k.dif create mode 100644 ksh93-aso.dif create mode 100644 ksh93-backtick.dif create mode 100644 ksh93-builtin.dif create mode 100644 ksh93-cdpwd.dif create mode 100644 ksh93-compat.dif create mode 100644 ksh93-disable-vfork.dif create mode 100644 ksh93-dttree-crash.dif create mode 100644 ksh93-edpredict.dif create mode 100644 ksh93-env.dif create mode 100644 ksh93-fdstatus.dif create mode 100644 ksh93-filedefined.dif create mode 100644 ksh93-foreground-prgrp.dif create mode 100644 ksh93-fs3d.dif create mode 100644 ksh93-gcc.dif create mode 100644 ksh93-gmt2utc.dif create mode 100644 ksh93-heredoc.dif create mode 100644 ksh93-heredoclex.dif create mode 100644 ksh93-ia64.dif create mode 100644 ksh93-int16double.dif create mode 100644 ksh93-joblock.dif create mode 100644 ksh93-jobs.dif create mode 100644 ksh93-jpold.dif create mode 100644 ksh93-limit-name-len.dif create mode 100644 ksh93-limits.dif create mode 100644 ksh93-longenv.dif create mode 100644 ksh93-malloc-hook.dif create mode 100644 ksh93-no-posix_spawn.dif create mode 100644 ksh93-no-sysctl.dif create mode 100644 ksh93-nvtree-free.dif create mode 100644 ksh93-optimizeleak.dif create mode 100644 ksh93-path-skip.dif create mode 100644 ksh93-pathtemp.dif create mode 100644 ksh93-profile.dif create mode 100644 ksh93-putval.dif create mode 100644 ksh93-redirectleak.dif create mode 100644 ksh93-reg.dif create mode 100644 ksh93-s390.dif create mode 100644 ksh93-sfio.dif create mode 100644 ksh93-shift_ijs.dif create mode 100644 ksh93-signals.dif create mode 100644 ksh93-spawnlock.dif create mode 100644 ksh93-stkalias.dif create mode 100644 ksh93-stkfreeze.dif create mode 100644 ksh93-stkset-abort.dif create mode 100644 ksh93-subshellpwd.dif create mode 100644 ksh93-suid_exec.dif create mode 100644 ksh93-test.dif create mode 100644 ksh93-typedef.dif create mode 100644 ksh93-uname.dif create mode 100644 ksh93-uninitialized.dif create mode 100644 ksh93-unset-f.dif create mode 100644 ksh93-untrustedenv.dif create mode 100644 ksh93-vi.dif create mode 100644 ksh93-vm.dif create mode 100644 ksh93.dif create mode 100644 leak1.sh create mode 100644 leak2.sh create mode 100644 leak3.sh create mode 100644 sigexec.c create mode 100644 ulimit.sh create mode 100644 vmbalance create mode 100644 workaround-stupid-build-system.diff 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