]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] alpha: osf getrusage, readv, writev [8/10]
authorIvan Kokshaysky <ink@jurassic.park.msu.ru>
Sat, 10 Aug 2002 09:03:17 +0000 (02:03 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sat, 10 Aug 2002 09:03:17 +0000 (02:03 -0700)
- osf_getrusage() updated for new utime/stime fields of the task_struct;
- compatibility wrappers for OSF/1 v4 readv/writev syscalls:
  forward port from 2.4.19.

arch/alpha/Config.help
arch/alpha/config.in
arch/alpha/kernel/entry.S
arch/alpha/kernel/osf_sys.c
include/asm-alpha/a.out.h
include/linux/personality.h

index 922ce70ac5fda3056923061f7d51b3c5be7581c5..e4ffe8437f203d1252effebeb52409bd704b65df 100644 (file)
@@ -438,6 +438,12 @@ CONFIG_BINFMT_AOUT
   because some crucial programs on your system might still be in A.OUT
   format.
 
+OSF/1 v4 readv/writev compatibility
+CONFIG_OSF4_COMPAT
+  Say Y if you are using OSF/1 binaries (like Netscape and Acrobat)
+  with v4 shared libraries freely available from Compaq. If you're
+  going to use shared libraries from Tru64 version 5.0 or later, say N.
+
 CONFIG_BINFMT_EM86
   Say Y here if you want to be able to execute Linux/Intel ELF
   binaries just like native Alpha binaries on your Alpha machine. For
index e4cf0a6850d61c47dc0bfaeae3a31155f133514b..6b6d24bcafb40b832a50c54c219142d6c08c5fec 100644 (file)
@@ -265,6 +265,10 @@ if [ "$CONFIG_PROC_FS" != "n" ]; then
 fi
  
 tristate 'Kernel support for a.out (ECOFF) binaries' CONFIG_BINFMT_AOUT
+if [ "$CONFIG_BINFMT_AOUT" != "n" ]; then
+       bool '  OSF/1 v4 readv/writev compatibility' CONFIG_OSF4_COMPAT
+fi
+
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 tristate 'Kernel support for Linux/Intel ELF binaries' CONFIG_BINFMT_EM86
index 099430641f4a22dfef46ea2052660f56f4470566..144cafd1086a9c56048f1720d907b02367fb7630 100644 (file)
@@ -851,8 +851,13 @@ sys_call_table:
        .quad osf_getrusage
        .quad sys_getsockopt
        .quad alpha_ni_syscall
+#ifdef CONFIG_OSF4_COMPAT
+       .quad osf_readv                         /* 120 */
+       .quad osf_writev
+#else
        .quad sys_readv                         /* 120 */
        .quad sys_writev
+#endif
        .quad osf_settimeofday
        .quad sys_fchown
        .quad sys_fchmod
index 9dd48b15441c8599bf5077880009de938b432b31..0e66b34b1d80549b457b56fae543693073a4d6ae 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/file.h>
 #include <linux/types.h>
 #include <linux/ipc.h>
+#include <linux/namei.h>
 
 #include <asm/fpu.h>
 #include <asm/io.h>
@@ -956,6 +957,13 @@ static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
                 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
 }
 
+static inline void
+jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value)
+{
+       value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+       value->tv_sec = jiffies / HZ;
+}
+
 asmlinkage int osf_gettimeofday(struct timeval32 *tv, struct timezone *tz)
 {
        if (tv) {
@@ -1163,32 +1171,24 @@ asmlinkage int osf_getrusage(int who, struct rusage32 *ru)
        memset(&r, 0, sizeof(r));
        switch (who) {
        case RUSAGE_SELF:
-               r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_utime);
-               r.ru_utime.tv_usec = CT_TO_USECS(current->times.tms_utime);
-               r.ru_stime.tv_sec = CT_TO_SECS(current->times.tms_stime);
-               r.ru_stime.tv_usec = CT_TO_USECS(current->times.tms_stime);
+               jiffies_to_timeval32(current->utime, &r.ru_utime);
+               jiffies_to_timeval32(current->stime, &r.ru_stime);
                r.ru_minflt = current->min_flt;
                r.ru_majflt = current->maj_flt;
                r.ru_nswap = current->nswap;
                break;
        case RUSAGE_CHILDREN:
-               r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
-               r.ru_utime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
-               r.ru_stime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
-               r.ru_stime.tv_usec = CT_TO_USECS(current->times.tms_cstime);
+               jiffies_to_timeval32(current->cutime, &r.ru_utime);
+               jiffies_to_timeval32(current->cstime, &r.ru_stime);
                r.ru_minflt = current->cmin_flt;
                r.ru_majflt = current->cmaj_flt;
                r.ru_nswap = current->cnswap;
                break;
        default:
-               r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_utime +
-                                              current->times.tms_cutime);
-               r.ru_utime.tv_usec = CT_TO_USECS(current->times.tms_utime +
-                                                current->times.tms_cutime);
-               r.ru_stime.tv_sec = CT_TO_SECS(current->times.tms_stime +
-                                              current->times.tms_cstime);
-               r.ru_stime.tv_usec = CT_TO_USECS(current->times.tms_stime +
-                                                current->times.tms_cstime);
+               jiffies_to_timeval32(current->utime + current->cutime,
+                                  &r.ru_utime);
+               jiffies_to_timeval32(current->stime + current->cstime,
+                                  &r.ru_stime);
                r.ru_minflt = current->min_flt + current->cmin_flt;
                r.ru_majflt = current->maj_flt + current->cmaj_flt;
                r.ru_nswap = current->nswap + current->cnswap;
@@ -1390,3 +1390,44 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 
        return addr;
 }
+
+#ifdef CONFIG_OSF4_COMPAT
+extern ssize_t sys_readv(unsigned long, const struct iovec *, unsigned long);
+extern ssize_t sys_writev(unsigned long, const struct iovec *, unsigned long);
+
+/* Clear top 32 bits of iov_len in the user's buffer for
+   compatibility with old versions of OSF/1 where iov_len
+   was defined as int. */
+static int
+osf_fix_iov_len(const struct iovec *iov, unsigned long count)
+{
+       unsigned long i;
+
+       for (i = 0 ; i < count ; i++) {
+               int *iov_len_high = (int *)&iov[i].iov_len + 1;
+
+               if (put_user(0, iov_len_high))
+                       return -EFAULT;
+       }
+       return 0;
+}
+
+asmlinkage ssize_t
+osf_readv(unsigned long fd, const struct iovec * vector, unsigned long count)
+{
+       if (unlikely(personality(current->personality) == PER_OSF4))
+               if (osf_fix_iov_len(vector, count))
+                       return -EFAULT;
+       return sys_readv(fd, vector, count);
+}
+
+asmlinkage ssize_t
+osf_writev(unsigned long fd, const struct iovec * vector, unsigned long count)
+{
+       if (unlikely(personality(current->personality) == PER_OSF4))
+               if (osf_fix_iov_len(vector, count))
+                       return -EFAULT;
+       return sys_writev(fd, vector, count);
+}
+
+#endif
index b0361104b2907fdec25d1e0632d48e3aae528261..709ea3e381c35236a3bb2885e26a4036280b996a 100644 (file)
@@ -95,8 +95,8 @@ struct exec
    Worse, we have to notice the start address before swapping to use
    /sbin/loader, which of course is _not_ a TASO application.  */
 #define SET_AOUT_PERSONALITY(BFPM, EX) \
-       set_personality (BFPM->sh_bang || EX.ah.entry < 0x100000000 \
-                        ? PER_LINUX_32BIT : PER_LINUX)
+       set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
+                          ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
 
 #define STACK_TOP \
   (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
index 230d39460364ee1ef5d87fe1b9d01fcfb618ae15..192f073b0a5a26ba56fc1d115dea6079764b56e1 100644 (file)
@@ -62,6 +62,7 @@ enum {
        PER_RISCOS =            0x000c,
        PER_SOLARIS =           0x000d | STICKY_TIMEOUTS,
        PER_UW7 =               0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+       PER_OSF4 =              0x000f,                  /* OSF/1 v4 */
        PER_MASK =              0x00ff,
 };