Skip to contentSkip to conversation

generic sys_old_select

PATCH In review Christoph Hellwig 7 participants 8 messages Feb 1, 2010 – Feb 8, 2010

Subsystems (8)
Arm (32-bit) x86 VFS s390 +4 more subsystems
lore
Share & tools
lore
#0 lore raw

PATCH 1/6 generic sys_old_select

Add a generic implementation of the old select syscall, which expects it's argument in a memory block and switch all architectures over to use it.

arch/arm/kernel/calls.S +1 -1
Index: linux-2.6/arch/arm/kernel/calls.S
===================================================================
@@ -91,7 +91,7 @@
 		CALL(sys_settimeofday)
 /* 80 */	CALL(sys_getgroups16)
 		CALL(sys_setgroups16)
-		CALL(OBSOLETE(old_select))	/* used by libc4 */
+		CALL(OBSOLETE(sys_old_select))	/* used by libc4 */
 		CALL(sys_symlink)
 		CALL(sys_ni_syscall)		/* was sys_lstat */
 /* 85 */	CALL(sys_readlink)
arch/m68k/kernel/entry.S +1 -1
Index: linux-2.6/arch/m68k/kernel/entry.S
===================================================================
@@ -510,7 +510,7 @@ sys_call_table:
 	.long sys_settimeofday
 	.long sys_getgroups16	/* 80 */
 	.long sys_setgroups16
-	.long old_select
+	.long sys_old_select
 	.long sys_symlink
 	.long sys_lstat
 	.long sys_readlink	/* 85 */
arch/m68knommu/kernel/syscalltable.S +1 -1
Index: linux-2.6/arch/m68knommu/kernel/syscalltable.S
===================================================================
@@ -100,7 +100,7 @@ ENTRY(sys_call_table)
 	.long sys_settimeofday
 	.long sys_getgroups16	/* 80 */
 	.long sys_setgroups16
-	.long old_select
+	.long sys_old_select
 	.long sys_symlink
 	.long sys_lstat
 	.long sys_readlink	/* 85 */
arch/x86/kernel/syscall_table_32.S +1 -1
Index: linux-2.6/arch/x86/kernel/syscall_table_32.S
===================================================================
@@ -81,7 +81,7 @@ ENTRY(sys_call_table)
 	.long sys_settimeofday
 	.long sys_getgroups16	/* 80 */
 	.long sys_setgroups16
-	.long old_select
+	.long sys_old_select
 	.long sys_symlink
 	.long sys_lstat
 	.long sys_readlink	/* 85 */
arch/x86/include/asm/sys_ia32.h +0 -2
Index: linux-2.6/arch/x86/include/asm/sys_ia32.h
===================================================================
@@ -40,8 +40,6 @@ asmlinkage long sys32_rt_sigprocmask(int
 				     compat_sigset_t __user *, unsigned int);
 asmlinkage long sys32_alarm(unsigned int);
 
-struct sel_arg_struct;
-asmlinkage long sys32_old_select(struct sel_arg_struct __user *);
 asmlinkage long sys32_waitpid(compat_pid_t, unsigned int *, int);
 asmlinkage long sys32_sysfs(int, u32, u32);
 
arch/arm/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/arm/include/asm/unistd.h
===================================================================
@@ -443,6 +443,7 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_OLD_SELECT
 
 #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
 #define __ARCH_WANT_SYS_TIME
arch/h8300/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/h8300/include/asm/unistd.h
===================================================================
@@ -348,6 +348,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_SELECT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
arch/m68k/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/m68k/include/asm/unistd.h
===================================================================
@@ -359,6 +359,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_SELECT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
arch/x86/include/asm/unistd_32.h +1 -0
Index: linux-2.6/arch/x86/include/asm/unistd_32.h
===================================================================
@@ -366,6 +366,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_SELECT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
arch/ia64/ia32/sys_ia32.c +0 -19
Index: linux-2.6/arch/ia64/ia32/sys_ia32.c
===================================================================
@@ -1107,25 +1107,6 @@ sys32_alarm (unsigned int seconds)
 	return alarm_setitimer(seconds);
 }
 
-struct sel_arg_struct {
-	unsigned int n;
-	unsigned int inp;
-	unsigned int outp;
-	unsigned int exp;
-	unsigned int tvp;
-};
-
-asmlinkage long
-sys32_old_select (struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
-				 compat_ptr(a.exp), compat_ptr(a.tvp));
-}
-
 #define SEMOP		 1
 #define SEMGET		 2
 #define SEMCTL		 3
arch/x86/ia32/sys_ia32.c +0 -18
Index: linux-2.6/arch/x86/ia32/sys_ia32.c
===================================================================
@@ -332,24 +332,6 @@ asmlinkage long sys32_alarm(unsigned int
 	return alarm_setitimer(seconds);
 }
 
-struct sel_arg_struct {
-	unsigned int n;
-	unsigned int inp;
-	unsigned int outp;
-	unsigned int exp;
-	unsigned int tvp;
-};
-
-asmlinkage long sys32_old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
-				 compat_ptr(a.exp), compat_ptr(a.tvp));
-}
-
 asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr,
 			      int options)
 {
fs/select.c +17 -0
Index: linux-2.6/fs/select.c
===================================================================
@@ -691,6 +691,23 @@ SYSCALL_DEFINE6(pselect6, int, n, fd_set
 }
 #endif /* HAVE_SET_RESTORE_SIGMASK */
 
+#ifdef __ARCH_WANT_SYS_OLD_SELECT
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set __user *inp, *outp, *exp;
+	struct timeval __user *tvp;
+};
+
+SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+#endif
+
 struct poll_list {
 	struct poll_list *next;
 	int len;
arch/h8300/kernel/syscalls.S +1 -1
Index: linux-2.6/arch/h8300/kernel/syscalls.S
===================================================================
@@ -96,7 +96,7 @@ SYMBOL_NAME_LABEL(sys_call_table)	
 	.long SYMBOL_NAME(sys_settimeofday)
 	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
 	.long SYMBOL_NAME(sys_setgroups16)
-	.long SYMBOL_NAME(old_select)
+	.long SYMBOL_NAME(sys_old_select)
 	.long SYMBOL_NAME(sys_symlink)
 	.long SYMBOL_NAME(sys_lstat)
 	.long SYMBOL_NAME(sys_readlink)		/* 85 */
arch/mn10300/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/mn10300/include/asm/unistd.h
===================================================================
@@ -375,6 +375,7 @@
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_SELECT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
arch/mn10300/kernel/entry.S +1 -1
Index: linux-2.6/arch/mn10300/kernel/entry.S
===================================================================
@@ -468,7 +468,7 @@ ENTRY(sys_call_table)
 	.long sys_settimeofday
 	.long sys_getgroups16	/* 80 */
 	.long sys_setgroups16
-	.long old_select
+	.long sys_old_select
 	.long sys_symlink
 	.long sys_lstat
 	.long sys_readlink	/* 85 */
include/linux/syscalls.h +2 -0
Index: linux-2.6/include/linux/syscalls.h
===================================================================
@@ -34,6 +34,7 @@ struct pollfd;
 struct rlimit;
 struct rusage;
 struct sched_param;
+struct sel_arg_struct;
 struct semaphore;
 struct sembuf;
 struct shmid_ds;
@@ -638,6 +639,7 @@ asmlinkage long sys_poll(struct pollfd _
 				long timeout);
 asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
 			fd_set __user *exp, struct timeval __user *tvp);
+asmlinkage long sys_old_select(struct sel_arg_struct __user * arg);
 asmlinkage long sys_epoll_create(int size);
 asmlinkage long sys_epoll_create1(int flags);
 asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
arch/arm/kernel/sys_arm.c +0 -21
Index: linux-2.6/arch/arm/kernel/sys_arm.c
===================================================================
@@ -54,27 +54,6 @@ out:
 	return error;
 }
 
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls.
- */
-
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set __user *inp, *outp, *exp;
-	struct timeval __user *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
 #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
arch/h8300/kernel/sys_h8300.c +0 -16
Index: linux-2.6/arch/h8300/kernel/sys_h8300.c
===================================================================
@@ -60,22 +60,6 @@ out:
 	return error;
 }
 
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set *inp, *outp, *exp;
-	struct timeval *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
arch/m68k/kernel/sys_m68k.c +0 -16
Index: linux-2.6/arch/m68k/kernel/sys_m68k.c
===================================================================
@@ -75,22 +75,6 @@ out:
 	return error;
 }
 
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set __user *inp, *outp, *exp;
-	struct timeval __user *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
arch/ia64/ia32/ia32_entry.S +1 -1
Index: linux-2.6/arch/ia64/ia32/ia32_entry.S
===================================================================
@@ -260,7 +260,7 @@ ia32_syscall_table:
 	data8 compat_sys_settimeofday
 	data8 sys32_getgroups16	  /* 80 */
 	data8 sys32_setgroups16
-	data8 sys32_old_select
+	data8 compat_sys_old_select
 	data8 sys_symlink
 	data8 sys_ni_syscall
 	data8 sys_readlink	  /* 85 */
arch/m68knommu/kernel/sys_m68k.c +0 -16
Index: linux-2.6/arch/m68knommu/kernel/sys_m68k.c
===================================================================
@@ -61,22 +61,6 @@ out:
 	return error;
 }
 
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set *inp, *outp, *exp;
-	struct timeval *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
arch/mn10300/kernel/sys_mn10300.c +0 -18
Index: linux-2.6/arch/mn10300/kernel/sys_mn10300.c
===================================================================
@@ -32,24 +32,6 @@ asmlinkage long old_mmap(unsigned long a
 	return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 }
 
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set *inp;
-	fd_set *outp;
-	fd_set *exp;
-	struct timeval *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
arch/x86/ia32/ia32entry.S +1 -1
Index: linux-2.6/arch/x86/ia32/ia32entry.S
===================================================================
@@ -586,7 +586,7 @@ ia32_sys_call_table:
 	.quad compat_sys_settimeofday
 	.quad sys_getgroups16	/* 80 */
 	.quad sys_setgroups16
-	.quad sys32_old_select
+	.quad compat_sys_old_select
 	.quad sys_symlink
 	.quad sys_lstat
 	.quad sys_readlink		/* 85 */
arch/x86/include/asm/syscalls.h +0 -2
Index: linux-2.6/arch/x86/include/asm/syscalls.h
===================================================================
@@ -52,12 +52,10 @@ unsigned long sys_sigreturn(struct pt_re
 
 /* kernel/sys_i386_32.c */
 struct mmap_arg_struct;
-struct sel_arg_struct;
 struct oldold_utsname;
 struct old_utsname;
 
 asmlinkage int old_mmap(struct mmap_arg_struct __user *);
-asmlinkage int old_select(struct sel_arg_struct __user *);
 asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
 asmlinkage int sys_uname(struct old_utsname __user *);
 asmlinkage int sys_olduname(struct oldold_utsname __user *);
arch/x86/kernel/sys_i386_32.c +0 -17
Index: linux-2.6/arch/x86/kernel/sys_i386_32.c
===================================================================
@@ -58,23 +58,6 @@ out:
 	return err;
 }
 
-
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set __user *inp, *outp, *exp;
-	struct timeval __user *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
fs/compat.c +18 -0
Index: linux-2.6/fs/compat.c
===================================================================
@@ -1795,6 +1795,24 @@ asmlinkage long compat_sys_select(int n,
 	return ret;
 }
 
+struct compat_sel_arg_struct {
+	compat_ulong_t n;
+	compat_ulong_t inp;
+	compat_ulong_t outp;
+	compat_ulong_t exp;
+	compat_ulong_t tvp;
+};
+
+asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg)
+{
+	struct compat_sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
+				 compat_ptr(a.exp), compat_ptr(a.tvp));
+}
+
 #ifdef HAVE_SET_RESTORE_SIGMASK
 static long do_compat_pselect(int n, compat_ulong_t __user *inp,
 	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
arch/s390/kernel/entry.h +0 -1
Index: linux-2.6/arch/s390/kernel/entry.h
===================================================================
@@ -28,7 +28,6 @@ struct new_utsname;
 struct mmap_arg_struct;
 struct fadvise64_64_args;
 struct old_sigaction;
-struct sel_arg_struct;
 
 long sys_mmap2(struct mmap_arg_struct __user  *arg);
 long sys_s390_old_mmap(struct mmap_arg_struct __user *arg);
arch/um/sys-i386/syscalls.c +0 -18
Index: linux-2.6/arch/um/sys-i386/syscalls.c
===================================================================
@@ -44,24 +44,6 @@ long old_mmap_i386(struct mmap_arg_struc
 	return err;
 }
 
-struct sel_arg_struct {
-	unsigned long n;
-	fd_set __user *inp;
-	fd_set __user *outp;
-	fd_set __user *exp;
-	struct timeval __user *tvp;
-};
-
-long old_select(struct sel_arg_struct __user *arg)
-{
-	struct sel_arg_struct a;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-	/* sys_select() does the appropriate kernel locking */
-	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
 /*
  * The prototype on i386 is:
  *
include/linux/compat.h +3 -0
Index: linux-2.6/include/linux/compat.h
===================================================================
@@ -23,6 +23,7 @@
 typedef __compat_uid32_t	compat_uid_t;
 typedef __compat_gid32_t	compat_gid_t;
 
+struct compat_sel_arg_struct;
 struct rusage;
 
 struct compat_itimerspec { 
@@ -249,6 +250,8 @@ asmlinkage long compat_sys_select(int n,
 		compat_ulong_t __user *outp, compat_ulong_t __user *exp,
 		struct compat_timeval __user *tvp);
 
+asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg);
+
 asmlinkage long compat_sys_wait4(compat_pid_t pid,
 				 compat_uint_t __user *stat_addr, int options,
 				 struct compat_rusage __user *ru);
#2 lore raw
In reply to Christoph Hellwig
Quoted 5 lines · Christoph Hellwig

Index: linux-2.6/fs/compat.c
===================================================================

fs/compat.c asmlinkage long compat_sys_select(int n, · line 1804

Quoted 10 lines
fs/compat.c +7 -0
@@ -1795,6 +1795,24 @@ asmlinkage long compat_sys_select(int n,
 	return ret;
 }
 
+struct compat_sel_arg_struct {
+	compat_ulong_t n;
+	compat_ulong_t inp;
+	compat_ulong_t outp;
+	compat_ulong_t exp;
+	compat_ulong_t tvp;
+};

Shouldn't the last four be compat_uptr_t?

Andreas.

Signature · 3 lines
Andreas Schwab, [email protected]
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
#3 lore raw
Quoted 8 lines · Andreas Schwab
Quoted 8 lines

Index: linux-2.6/fs/compat.c
===================================================================

fs/compat.c +0 -0
@@ -1795,6 +1795,24 @@ asmlinkage long compat_sys_select(int n,
 	return ret;
 }
 
Quoted 9 lines

fs/compat.c asmlinkage long compat_sys_select(int n, · line 1804

Quoted 7 lines
fs/compat.c +7 -0
+struct compat_sel_arg_struct {
+	compat_ulong_t n;
+	compat_ulong_t inp;
+	compat_ulong_t outp;
+	compat_ulong_t exp;
+	compat_ulong_t tvp;
+};

Shouldn't the last four be compat_uptr_t?

Strictly speaking yes, although it doesn't matter for the generated code. The patch below makes it use the strictly correct type:

fs/compat.c +4 -4
Index: linux-2.6/fs/compat.c
===================================================================
@@ -1797,10 +1797,10 @@ asmlinkage long compat_sys_select(int n,
 
 struct compat_sel_arg_struct {
 	compat_ulong_t n;
-	compat_ulong_t inp;
-	compat_ulong_t outp;
-	compat_ulong_t exp;
-	compat_ulong_t tvp;
+	compat_uptr_t inp;
+	compat_uptr_t outp;
+	compat_uptr_t exp;
+	compat_uptr_t tvp;
 };
 
 asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg)
Acked-by on v1 1/6
#4 lore raw
In reply to Christoph Hellwig
Quoted 2 lines · Christoph Hellwig

Add a generic implementation of the old select syscall, which expects it's argument in a memory block and switch all architectures over to use it.

Looks fine to me.

Signature · 3 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:
Acked-by on v1 1/6
#5 lore raw
In reply to Christoph Hellwig
Quoted 5 lines · Christoph Hellwig

Add a generic implementation of the old select syscall, which expects it's argument in a memory block and switch all architectures over to use it.

For the m68knommu parts

Signature · 5 lines
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     [email protected]
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com
#6 lore raw
In reply to Christoph Hellwig

Hi,

On 02/01/2010 10:55 AM, Christoph Hellwig wrote:
[snip]

Quoted 1 line

+asmlinkage long sys_old_select(struct sel_arg_struct __user * arg);

A trival style problem: "foo * bar"

--
Regards
dave