Package: acpi-support-base
Version: 0.137-7
Severity: normal
Tags: patch

A small part of this patch touches the same area as bug#603796.
Added annotations in various areas that need reviewing.

Motivation:

* performance improvements: uses more shell builtins instead of forking
  (yes, it's more code but it runs faster)
* error handling improvements: reports errors to the system log in an
  attempt to make trouble shooting easier (surprisingly many commands were
  simply ignoring errors)
* attempts to correct a sed regex greedyness problem

Yes, I tested the changes on a desktop and a norebook.  Shell used was
dash, with options '-e' and '-u'.

It is not easy to distinguish between function local variables and global
variables.  A naming convention does not seem to exist either.  A proper
cleanup would be needed too, to improve readability.


-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing')
Architecture: i386 (i686)

Kernel: Linux 2.6.32-5-686 (SMP w/2 CPU cores)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/bash

Versions of packages acpi-support-base depends on:
ii  acpid                      1:2.0.7-1     Advanced Configuration and Power I
ii  console-tools [console-uti 1:0.2.3dbs-69 Linux console and font utilities

acpi-support-base recommends no packages.

Versions of packages acpi-support-base suggests:
ii  acpi-support                  0.137-7    scripts for handling many ACPI eve

-- no debconf information

Cheers,

-- 
Cristian
--- usr/share/acpi-support/power-funcs.orig	2010-11-17 09:56:51.000000000 +0100
+++ usr/share/acpi-support/power-funcs	2010-11-21 14:05:44.000000000 +0100
@@ -5,43 +5,123 @@
 PATH="$PATH:/usr/bin/X11"
 POWERSTATE="/var/lib/acpi-support/powerstate"
 
+pwf_error() {
+	logger -t${0##*/} -perr -- power-funcs: $*
+	exit 1
+}
+
 # getXuser gets the X user belonging to the display in $displaynum.
 # If you want the foreground X user, use getXconsole!
 
 getXuser() {
-	user=`pinky -fw | awk '{ if ($2 == "?:'$displaynum'" || $(NF) == ":'$displaynum'" || $2 == "?:'$displaynum'.0" || $(NF) == ":'$displaynum'.0"  ) { print $1; exit; } }'`
-
-	if [ x"$user" = x"" ]; then
-		startx=`pgrep -n startx`
-		if [ x"$startx" != x"" ]; then
-			user=`ps -o user --no-headers $startx`
-		fi
+	plist=$(pinky -fw) || pwf_error "pinky lost"
+	user=
+	while read l; do
+		set -- $l
+		eval lastpp=\$$#
+		for ds in $2 $lastpp; do
+			case $ds in
+				:$displaynum)
+					user=$1
+					break
+					;;
+			esac
+		done
+		[ -z "$user" ] || break
+		for ds in $2 $lastpp; do
+			case $ds in
+				:$displaynum.0)
+					user=$1
+					break
+					;;
+			esac
+		done
+		[ -z "$user" ] || break
+	done <<-EOF
+		$plist
+	EOF
+
+	if [ -z "$user" ]; then
+		startx=$(pgrep -n startx || :)
+		[ -z "$startx" ] || user=$(ps -o user --no-headers $startx || :)
 	fi
-	if [ x"$user" != x"" ]; then
-        	userhome=`getent passwd $user | cut -d: -f6`
-        	export XAUTHORITY=$userhome/.Xauthority
-	else
-		export XAUTHORITY=""
-	fi
-	export XUSER=$user
+
+	XAUTHORITY=
+	[ -z "$user" ] || {
+		passwd_line=$(getent passwd $user) || pwf_error "getent lost"
+		local IFS=:
+		set -- $passwd_line
+        	[ -z "$6" ] || XAUTHORITY="$6/.Xauthority"
+	}
+	XUSER=$user
+	export XAUTHORITY XUSER
 }
 
 # getXconsole gets the foreground (console) X user
 getXconsole() {
-	console=`fgconsole`;
-	displaynum=`ps t tty$console | sed -n -re 's,.*/X .*:([0-9]+).*,\1,p'`
-	if [ x"$displaynum" != x"" ]; then
-		export DISPLAY=":$displaynum"
-		getXuser
-	fi
+	activeVT=$(fgconsole) || pwf_error "can't get active VT"
+	case $activeVT in
+		''|*[!0-9]*)
+			pwf_error "invalid active VT '$activeVT'"
+			;;
+	esac
+
+	cmdl="ps wt tty$activeVT --no-headers"
+	xproc=$($cmdl) || pwf_error "'$cmdl' failure"
+	[ "$xproc" ] || pwf_error "X process not found"
+
+# less error prone display detection method?
+# after a 'startx', something like this may show up:
+# '9859 tty7 Ss+ 46:22 /usr/bin/X -nolisten tcp :0 -auth /tmp/serverauth.hHIwM1r8IL'
+# (display is 8th word) but a gdm may show different:
+# '1647 tty7 Ss+ 2:16 /usr/bin/X :0 -audit 0 -auth /var/lib/gdm/:0.Xauth -nolisten tcp vt7'
+# (display is 6th word, and there's also a display like string in the 10th word)
+# the original greedy sed regex:
+#	displaynum=`ps t tty$console | sed -n -re 's,.*/X .*:([0-9]+).*,\1,p'`
+# matches the ':0' substring in the '-auth' option argument 
+# '/var/lib/gdm/:0.Xauth' in the example above, instead of the expected ':0'
+# argument
+	set -- $xproc
+	# skip first 4 positional parameters
+	shift 4
+	# 1st positional parameter now should be X
+	case $1 in
+		*/X)
+			shift
+			;;
+		*)
+			pwf_error "mismatch, */X expected"
+			;;
+	esac
+	# match the 1st of the remaining positional parameters that looks like
+	# a display number
+	displaynum=
+	while [ $1 ]; do
+		case $1 in
+			:[0-9]*)
+				displaynum=$1
+				break
+				;;
+		esac
+		shift
+	done
+	[ "$displaynum" ] || pwf_error "display number detection failed"
+
+	displaynum=${displaynum##*:}
+	displaynum=${displaynum%%.*}
+	case $displaynum in
+		*[!0-9]*)
+			pwf_error "invalid display number '$displaynum'"
+			;;
+	esac
+
+	export DISPLAY=":$displaynum"
+	getXuser
 }
 
 ac_adapters() {
     for x in /sys/class/power_supply/*; do
-       if [ -d "$x" ] ; then
-            read type < $x/type
-            test "$type" = "Mains" && echo $x
-        fi
+	[ ! -d "$x" ] || ! read type <$x/type || [ "$type" != Mains ] || echo $x
     done
 }
 
@@ -55,17 +135,15 @@
 
         for x in $(ac_adapters); do
             POWER_SUPPLY_PRESENT=1
-            if grep -q 1 $x/online ; then
-                ONLINE_POWER_SUPPLY_PRESENT=1
-            fi
+	    ! read _olpsp <$x/online || [ "$_olpsp" != 1 ] ||
+		ONLINE_POWER_SUPPLY_PRESENT=1
         done
 
         for x in /proc/acpi/ac_adapter/*; do
             if [ -d "$x" ] ; then
                 POWER_SUPPLY_PRESENT=1
-                if grep -q on-line $x/state ; then
-                    ONLINE_POWER_SUPPLY_PRESENT=1
-                fi
+		! read _olpsp <$x/state || [ "$_olpsp" != on-line ] ||
+			ONLINE_POWER_SUPPLY_PRESENT=1
             fi
         done
         if [ $POWER_SUPPLY_PRESENT = 1 ] && [ $ONLINE_POWER_SUPPLY_PRESENT = 0 ] ; then
@@ -78,16 +156,24 @@
 #check our state has actually changed
 checkStateChanged() {
 # do we have our state stashed?
+# XXX:	if vaiable STATE is unset, set it to the null string
+	: ${STATE=${STATE:-}}
+# XXX:	make sure variable STATE has a non-null value
+	[ "$STATE" ] || getState
         if [ -f "$POWERSTATE" ]; then
-                OLDSTATE=$(cat $POWERSTATE) 
+# XXX:	unset or empty variable STATE and an existing but empty POWERSTATE file
+#	and the function will probably have undesired side effects
+                read OLDSTATE <$POWERSTATE || :
                 if [ "$STATE" = "$OLDSTATE" ]; then
                        exit 0
                 else
 #stash the new state
+# XXX:	unset or empty variable STATE, will create an empty POWERSTATE file
                         echo "$STATE" > $POWERSTATE
                 fi
         else
 #we need to stash the new state
+# XXX:	unset or empty variable STATE, will create an empty POWERSTATE file
                 echo "$STATE" > $POWERSTATE
         fi
 }

Reply via email to