1# 2# CDDL HEADER START 3# 4# The contents of this file are subject to the terms of the 5# Common Development and Distribution License (the "License"). 6# You may not use this file except in compliance with the License. 7# 8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9# or http://www.opensolaris.org/os/licensing. 10# See the License for the specific language governing permissions 11# and limitations under the License. 12# 13# When distributing Covered Code, include this CDDL HEADER in each 14# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15# If applicable, add the following below this CDDL HEADER, with the 16# fields enclosed by brackets "[]" replaced with your own identifying 17# information: Portions Copyright [yyyy] [name of copyright owner] 18# 19# CDDL HEADER END 20# 21 22# 23# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24# 25 26# 27# This test checks whether ksh93 does unneccesaty |libc::getpwnam()| 28# calls for "~(modifer)pattern"-style shell patterns 29# 30# This was reported as CR #6807179 ("ksh93 does unneccesary |libc::getpwnam()| lookups for ~(modifier) pattern patterns"): 31# ------------ snip ------------ 32# ksh93 does unneccesary |libc::getpwnam()| lookups for 33# ~(modifer)pattern patterns, e.g. [[ $foo == ~(E)hello.*world ]]. 34# The problem is that the shell ~(modifer)pattern is an extended 35# pattern syntax which allows to specify a "modifer" to change 36# the behaviour for "pattern". However the '~' at the beginning 37# of this string is causing a tilde expansion (or better: It's 38# filling an internal buffer as preparation for tilde expansion 39# and this code calls |libc::getpwnam()|) which shouldn't be 40# done in this case. 41# [1]=For example the "modifer" allows to specifcy "perl", 42# "fgrep", "grep", "egrep", "POSIX shell", "korn shell" and 43# other types of pattern matching systems (or select stuff 44# like archors, case-insensitive matching etc. etc.). 45# ------------ snip ------------ 46# 47 48# test setup 49function err_exit 50{ 51 print -u2 -n "\t" 52 print -u2 -r ${Command}[$1]: "${@:2}" 53 (( Errors < 127 && Errors++ )) 54} 55alias err_exit='err_exit $LINENO' 56 57set -o nounset 58Command=${0##*/} 59integer Errors=0 60 61typeset tmpfile 62 63tmpfile="$(mktemp -t "sun_solaris_cr_6807179_shellpattern_uses_getpwnam.${PPID}.$$.XXXXXX")" || err_exit "Cannot create temporary file." 64rm -f "${tmpfile}" 65 66 67# test 1: Check if the shell uses |libc::getpwnam()| for pattern "~(Elr)wo.*ld" 68truss -u :: -o "${tmpfile}" ${SHELL} -c '[[ ${hello} == ~(Elr)wo.*ld ]] ; true' || err_exit "truss returned failure=$?" 69[[ "$( < "${tmpfile}")" != *getpwnam* ]] || err_exit "truss log reports the use of getpwnam() for pattern ~(Elr)wo.*ld" 70rm "${tmpfile}" || err_exit "rm ${tmpfile} failed." 71 72 73# test 2: Check if the shell uses |libc::getpwnam()| for pattern "~(Si)wo*ld" 74truss -u :: -o "${tmpfile}" ${SHELL} -c '[[ ${hello} == ~(Si)wo*ld ]] ; true' || err_exit "truss returned failure=$?" 75[[ "$( < "${tmpfile}")" != *getpwnam* ]] || err_exit "truss log reports the use of getpwnam() for pattern ~(Si)wo*ld" 76rm "${tmpfile}" || err_exit "rm ${tmpfile} failed." 77 78 79# test 3: Same as test 1 but uses ~root/ as pattern which will force the use of |libc::getpwnam()| 80getent passwd root >/dev/null || err_exit "getent passwd root failed" # safeguard to make sure we get a warning if user root is missing 81 82truss -u :: -o "${tmpfile}" ${SHELL} -c '[[ ${hello} == ~root/ ]] ; true' || err_exit "truss returned failure=$?" 83[[ "$( < "${tmpfile}" )" == *getpwnam* ]] || err_exit "truss log reports the use of getpwnam() for pattern ~root/" 84rm "${tmpfile}" || err_exit "rm ${tmpfile} failed." 85 86 87# tests done 88exit $((Errors)) 89