Add time, gettimeofday, and getrusage system call support
authorMichael Meissner <gnu@the-meissners.org>
Mon, 3 Jun 1996 19:10:25 +0000 (19:10 +0000)
committerMichael Meissner <gnu@the-meissners.org>
Mon, 3 Jun 1996 19:10:25 +0000 (19:10 +0000)
sim/ppc/ChangeLog
sim/ppc/configure.in
sim/ppc/emul_unix.c

index 1786be3af7b2eca3e59702d80154582e4f3dd494..83caaf8faaa86ccca098fd9dccb06b3c0d73a9a4 100644 (file)
@@ -1,3 +1,15 @@
+Mon Jun  3 15:02:04 1996  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+       * emul_unix.c (do_unix_{time,gettimeofday,getrusage}): Add support
+       for time, gettimeofday, and getrusage system calls.
+       ({solaris,linux}_descriptors): Add new system calls.
+       (do_get{,e}{uid,gid}): Use gid_t/uid_t types.
+       (do_get{,p}pid): Use pic_t types.
+
+       * configure.in (AC_TYPE_{GETGROUPS,SIGNAL}): Define.
+       (AC_TYPE_{MODE,OFF,PID,SIZE,UID}_T): Define.
+       * config{.in,ure}: Regenerate.
+
 Sun Jun  2 11:21:17 1996  Michael Meissner  <meissner@tiktok.cygnus.com>
 
        * emul_unix.{h,c}: New files to provide Solaris and Linux system
index fb662a0f322962d823845ddc1ae712c321036873..05d9d7f3d347e8b3b61761e7ea7369954fa3c26b 100644 (file)
@@ -444,6 +444,14 @@ AC_STRUCT_ST_BLOCKS
 AC_STRUCT_ST_RDEV
 AC_STRUCT_TIMEZONE
 
+AC_TYPE_GETGROUPS
+AC_TYPE_MODE_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIGNAL
+AC_TYPE_SIZE_T
+AC_TYPE_UID_T
+
 AC_CHECK_FUNCS(cfgetispeed cfgetospeed cfsetispeed cfsetospeed chdir chmod chown dup dup2 fchmod fchown fcntl fstat fstatfs getdirentries getegid geteuid getgid getpid getppid getrusage gettimeofday getuid ioctl kill link lseek lstat mkdir pipe readlink rmdir setreuid setregid stat sigprocmask stat symlink tcgetattr tcsetattr tcsendbreak tcdrain tcflush tcflow tcgetpgrp tcsetpgrp time umask unlink)
 
 AC_CHECK_HEADERS(fcntl.h stdlib.h string.h strings.h sys/ioctl.h sys/mount.h sys/param.h sys/resource.h sys/stat.h sys/termio.h sys/termios.h sys/time.h sys/times.h sys/types.h time.h unistd.h)
index 6003204abfee0d40b2b5d51afa2eeac735b5f8eb..3a2c92d613e16bc2ac8144900b33acb053ea4d45 100644 (file)
@@ -141,8 +141,44 @@ struct _os_emul_data {
   emul_syscall *syscalls;
 };
 
-
+\f
 /* Emulation of simple UNIX system calls that are common on all systems.  */
+
+/* Structures that are common agmonst the UNIX varients */
+struct unix_timeval {
+  signed32 tv_sec;             /* seconds */
+  signed32 tv_usec;            /* microseconds */
+};
+
+struct unix_timezone {
+  signed32 tz_minuteswest;     /* minutes west of Greenwich */
+  signed32 tz_dsttime;         /* type of dst correction */
+};
+
+#define        UNIX_RUSAGE_SELF        0
+#define        UNIX_RUSAGE_CHILDREN    (-1)
+#define UNIX_RUSAGE_BOTH       (-2)    /* sys_wait4() uses this */
+
+struct unix_rusage {
+       struct unix_timeval ru_utime;   /* user time used */
+       struct unix_timeval ru_stime;   /* system time used */
+       signed32 ru_maxrss;             /* maximum resident set size */
+       signed32 ru_ixrss;              /* integral shared memory size */
+       signed32 ru_idrss;              /* integral unshared data size */
+       signed32 ru_isrss;              /* integral unshared stack size */
+       signed32 ru_minflt;             /* any page faults not requiring I/O */
+       signed32 ru_majflt;             /* any page faults requiring I/O */
+       signed32 ru_nswap;              /* swaps */
+       signed32 ru_inblock;            /* block input operations */
+       signed32 ru_oublock;            /* block output operations */
+       signed32 ru_msgsnd;             /* messages sent */
+       signed32 ru_msgrcv;             /* messages received */
+       signed32 ru_nsignals;           /* signals received */
+       signed32 ru_nvcsw;              /* voluntary context switches */
+       signed32 ru_nivcsw;             /* involuntary " */
+};
+
+
 static void
 do_unix_exit(os_emul_data *emul,
             unsigned call,
@@ -305,8 +341,8 @@ do_unix_getpid(os_emul_data *emul,
               cpu *processor,
               unsigned_word cia)
 {
-  int status = (int)getpid();
-  emul_write_status(processor, status, errno);
+  pid_t status = getpid();
+  emul_write_status(processor, (int)status, errno);
 }
 #endif
 
@@ -320,8 +356,8 @@ do_unix_getppid(os_emul_data *emul,
                cpu *processor,
                unsigned_word cia)
 {
-  int status = (int)getppid();
-  emul_write_status(processor, status, errno);
+  pid_t status = getppid();
+  emul_write_status(processor, (int)status, errno);
 }
 #endif
 
@@ -351,9 +387,9 @@ do_unix_getuid2(os_emul_data *emul,
                cpu *processor,
                unsigned_word cia)
 {
-  int uid  = (int)getuid();
-  int euid = (int)geteuid();
-  emul_write2_status(processor, uid, euid, errno);
+  uid_t uid  = getuid();
+  uid_t euid = geteuid();
+  emul_write2_status(processor, (int)uid, (int)euid, errno);
 }
 #endif
 
@@ -367,8 +403,8 @@ do_unix_getuid(os_emul_data *emul,
               cpu *processor,
               unsigned_word cia)
 {
-  int status = (int)getuid();
-  emul_write_status(processor, status, errno);
+  uid_t status = getuid();
+  emul_write_status(processor, (int)status, errno);
 }
 #endif
 
@@ -382,8 +418,8 @@ do_unix_geteuid(os_emul_data *emul,
                cpu *processor,
                unsigned_word cia)
 {
-  int status = (int)geteuid();
-  emul_write_status(processor, status, errno);
+  uid_t status = geteuid();
+  emul_write_status(processor, (int)status, errno);
 }
 #endif
 
@@ -465,21 +501,16 @@ do_unix_lseek(os_emul_data *emul,
              cpu *processor,
              unsigned_word cia)
 {
-  int fildes cpu_registers(processor)->gpr[arg0];
-  off_t offset = emul_read_gpr64(processor, arg0+2);
-  int whence = cpu_registers(processor)->gpr[arg0+4];
+  int fildes   = (int)cpu_registers(processor)->gpr[arg0];
+  off_t offset = (off_t)cpu_registers(processor)->gpr[arg0+1];
+  int whence   = (int)cpu_registers(processor)->gpr[arg0+2];
   off_t status;
 
   if (WITH_TRACE && ppc_trace[trace_os_emul])
     printf_filtered ("%d %ld %d", fildes, (long)offset, whence);
 
   status = lseek(fildes, offset, whence);
-  if (status == -1)
-    emul_write_status(processor, -1, errno);
-  else {
-    emul_write_status(processor, 0, 0); /* success */
-    emul_write_gpr64(processor, 3, status);
-  }
+  emul_write_status(processor, (int)status, errno);
 }
 #endif
 
@@ -494,9 +525,9 @@ do_unix_getgid2(os_emul_data *emul,
                cpu *processor,
                unsigned_word cia)
 {
-  int gid  = (int)getgid();
-  int egid = (int)getegid();
-  emul_write2_status(processor, gid, egid, errno);
+  gid_t gid  = getgid();
+  gid_t egid = getegid();
+  emul_write2_status(processor, (int)gid, (int)egid, errno);
 }
 #endif
 
@@ -510,8 +541,8 @@ do_unix_getgid(os_emul_data *emul,
               cpu *processor,
               unsigned_word cia)
 {
-  int status = (int)getgid();
-  emul_write_status(processor, status, 0);
+  gid_t status = getgid();
+  emul_write_status(processor, (int)status, errno);
 }
 #endif
 
@@ -525,8 +556,8 @@ do_unix_getegid(os_emul_data *emul,
                cpu *processor,
                unsigned_word cia)
 {
-  int status = (int)getegid();
-  emul_write_status(processor, status, errno);
+  gid_t status = getegid();
+  emul_write_status(processor, (int)status, errno);
 }
 #endif
 
@@ -540,7 +571,7 @@ do_unix_umask(os_emul_data *emul,
              cpu *processor,
              unsigned_word cia)
 {
-  int mask = cpu_registers(processor)->gpr[arg0];
+  mode_t mask = (mode_t)cpu_registers(processor)->gpr[arg0];
   int status = umask(mask);
 
   if (WITH_TRACE && ppc_trace[trace_os_emul])
@@ -695,6 +726,161 @@ do_unix_rmdir(os_emul_data *emul,
 }
 #endif
 
+#ifndef HAVE_TIME
+#define do_unix_time 0
+#else
+static void
+do_unix_time(os_emul_data *emul,
+            unsigned call,
+            const int arg0,
+            cpu *processor,
+            unsigned_word cia)
+{
+  unsigned_word tp = cpu_registers(processor)->gpr[arg0];
+  time_t now = time ((time_t *)0);
+  unsigned_word status = H2T_4(now);
+
+  if (WITH_TRACE && ppc_trace[trace_os_emul])
+    printf_filtered ("0x%lx", (long)tp);
+
+  emul_write_status(processor, (int)status, errno);
+
+  if (tp)
+    emul_write_buffer(&status, tp, sizeof(status), processor, cia);
+}
+#endif
+
+#if !defined(HAVE_GETTIMEOFDAY) || !defined(HAVE_SYS_TIME_H)
+#define do_unix_gettimeofday 0
+#else
+static void
+do_unix_gettimeofday(os_emul_data *emul,
+                    unsigned call,
+                    const int arg0,
+                    cpu *processor,
+                    unsigned_word cia)
+{
+  unsigned_word tv = cpu_registers(processor)->gpr[arg0];
+  unsigned_word tz = cpu_registers(processor)->gpr[arg0+1];
+  struct unix_timeval target_timeval;
+  struct timeval host_timeval;
+  struct unix_timezone target_timezone;
+  struct timezone host_timezone;
+  int status;
+
+  if (WITH_TRACE && ppc_trace[trace_os_emul])
+    printf_filtered ("0x%lx, 0x%lx", (long)tv, (long)tz);
+
+  /* Just in case the system doesn't set the timezone structure */
+  host_timezone.tz_minuteswest = 0;
+  host_timezone.tz_dsttime = 0;
+
+  status = gettimeofday(&host_timeval, &host_timezone);
+  if (status >= 0) {
+    if (tv) {
+      target_timeval.tv_sec = H2T_4(host_timeval.tv_sec);
+      target_timeval.tv_usec = H2T_4(host_timeval.tv_usec);
+      emul_write_buffer((void *) &target_timeval, tv, sizeof(target_timeval), processor, cia);
+    }
+
+    if (tz) {
+      target_timezone.tz_minuteswest = H2T_4(host_timezone.tz_minuteswest);
+      target_timezone.tz_dsttime = H2T_4(host_timezone.tz_dsttime);
+      emul_write_buffer((void *) &target_timezone, tv, sizeof(target_timezone), processor, cia);
+    }
+  }
+    
+  emul_write_status(processor, (int)status, errno);
+}
+#endif
+
+
+#ifndef HAVE_GETRUSAGE
+#define do_unix_getrusage 0
+#else
+static void
+do_unix_getrusage(os_emul_data *emul,
+                 unsigned call,
+                 const int arg0,
+                 cpu *processor,
+                 unsigned_word cia)
+{
+  signed_word who = (signed_word)cpu_registers(processor)->gpr[arg0];
+  unsigned_word usage = cpu_registers(processor)->gpr[arg0+1];
+  struct rusage host_rusage, host_rusage2;
+  struct unix_rusage target_rusage;
+  int status;
+
+  if (WITH_TRACE && ppc_trace[trace_os_emul])
+    printf_filtered ("%ld, 0x%lx", (long)who, (long)usage);
+
+  switch (who) {
+  default:
+    status = -1;
+    errno = EINVAL;
+    break;
+
+  case UNIX_RUSAGE_SELF:
+    status = getrusage(RUSAGE_SELF, &host_rusage);
+    break;
+
+  case UNIX_RUSAGE_CHILDREN:
+    status = getrusage(RUSAGE_CHILDREN, &host_rusage);
+    break;
+
+  case UNIX_RUSAGE_BOTH:
+    status = getrusage(RUSAGE_SELF, &host_rusage);
+    if (status >= 0) {
+      status = getrusage(RUSAGE_CHILDREN, &host_rusage2);
+      if (status >= 0) {
+       host_rusage.ru_utime.tv_sec += host_rusage2.ru_utime.tv_sec;
+       host_rusage.ru_utime.tv_usec += host_rusage2.ru_utime.tv_usec;
+       host_rusage.ru_stime.tv_sec += host_rusage2.ru_stime.tv_sec;
+       host_rusage.ru_stime.tv_usec += host_rusage2.ru_stime.tv_usec;
+       host_rusage.ru_maxrss += host_rusage2.ru_maxrss;
+       host_rusage.ru_ixrss += host_rusage2.ru_ixrss;
+       host_rusage.ru_idrss += host_rusage2.ru_idrss;
+       host_rusage.ru_isrss += host_rusage2.ru_isrss;
+       host_rusage.ru_minflt += host_rusage2.ru_minflt;
+       host_rusage.ru_majflt += host_rusage2.ru_majflt;
+       host_rusage.ru_nswap += host_rusage2.ru_nswap;
+       host_rusage.ru_inblock += host_rusage2.ru_inblock;
+       host_rusage.ru_oublock += host_rusage2.ru_oublock;
+       host_rusage.ru_msgsnd += host_rusage2.ru_msgsnd;
+       host_rusage.ru_msgrcv += host_rusage2.ru_msgrcv;
+       host_rusage.ru_nsignals += host_rusage2.ru_nsignals;
+       host_rusage.ru_nvcsw += host_rusage2.ru_nvcsw;
+       host_rusage.ru_nivcsw += host_rusage2.ru_nivcsw;
+      }
+    }
+  }
+
+  if (status >= 0) {
+    target_rusage.ru_utime.tv_sec = H2T_4(host_rusage2.ru_utime.tv_sec);
+    target_rusage.ru_utime.tv_usec = H2T_4(host_rusage2.ru_utime.tv_usec);
+    target_rusage.ru_stime.tv_sec = H2T_4(host_rusage2.ru_stime.tv_sec);
+    target_rusage.ru_stime.tv_usec = H2T_4(host_rusage2.ru_stime.tv_usec);
+    target_rusage.ru_maxrss = H2T_4(host_rusage2.ru_maxrss);
+    target_rusage.ru_ixrss = H2T_4(host_rusage2.ru_ixrss);
+    target_rusage.ru_idrss = H2T_4(host_rusage2.ru_idrss);
+    target_rusage.ru_isrss = H2T_4(host_rusage2.ru_isrss);
+    target_rusage.ru_minflt = H2T_4(host_rusage2.ru_minflt);
+    target_rusage.ru_majflt = H2T_4(host_rusage2.ru_majflt);
+    target_rusage.ru_nswap = H2T_4(host_rusage2.ru_nswap);
+    target_rusage.ru_inblock = H2T_4(host_rusage2.ru_inblock);
+    target_rusage.ru_oublock = H2T_4(host_rusage2.ru_oublock);
+    target_rusage.ru_msgsnd = H2T_4(host_rusage2.ru_msgsnd);
+    target_rusage.ru_msgrcv = H2T_4(host_rusage2.ru_msgrcv);
+    target_rusage.ru_nsignals = H2T_4(host_rusage2.ru_nsignals);
+    target_rusage.ru_nvcsw = H2T_4(host_rusage2.ru_nvcsw);
+    target_rusage.ru_nivcsw = H2T_4(host_rusage2.ru_nivcsw);
+    emul_write_buffer((void *) &target_rusage, usage, sizeof(target_rusage), processor, cia);
+  }
+    
+  emul_write_status(processor, status, errno);
+}
+#endif
+
 \f
 /* Common code for initializing the system call stuff */
 
@@ -772,11 +958,6 @@ typedef    unsigned32      solaris_nlink_t;
 #ifdef HAVE_SYS_STAT_H
 #define        SOLARIS_ST_FSTYPSZ 16           /* array size for file system type name */
 
-typedef struct {
-  solaris_time_t       tv_sec;
-  signed32             tv_usec;
-} solaris_timestruc_t;
-
 struct solaris_stat {
   solaris_dev_t                st_dev;
   signed32             st_pad1[3];     /* reserved for network id */
@@ -789,9 +970,9 @@ struct solaris_stat {
   signed32             st_pad2[2];
   solaris_off_t                st_size;
   signed32             st_pad3;        /* future off_t expansion */
-  solaris_timestruc_t  st_atim;
-  solaris_timestruc_t  st_mtim;
-  solaris_timestruc_t  st_ctim;
+  struct unix_timeval  st_atim;
+  struct unix_timeval  st_mtim;
+  struct unix_timeval  st_ctim;
   signed32             st_blksize;
   signed32             st_blocks;
   char                 st_fstype[SOLARIS_ST_FSTYPSZ];
@@ -1222,7 +1403,7 @@ static emul_syscall_descriptor solaris_descriptors[] = {
   /*  10 */ { do_unix_unlink, "unlink" },
   /*  11 */ { 0, "exec" },
   /*  12 */ { do_unix_chdir, "chdir" },
-  /*  13 */ { 0, "time" },
+  /*  13 */ { do_unix_time, "time" },
   /*  14 */ { 0, "mknod" },
   /*  15 */ { 0, "chmod" },
   /*  16 */ { 0, "chown" },
@@ -1366,7 +1547,7 @@ static emul_syscall_descriptor solaris_descriptors[] = {
   /* 153 */ { 0, "fchroot" },
   /* 154 */ { 0, "utimes" },
   /* 155 */ { 0, "vhangup" },
-  /* 156 */ { 0, "gettimeofday" },
+  /* 156 */ { do_unix_gettimeofday, "gettimeofday" },
   /* 157 */ { 0, "getitimer" },
   /* 158 */ { 0, "setitimer" },
   /* 159 */ { 0, "lwp_create" },
@@ -2152,7 +2333,7 @@ static emul_syscall_descriptor linux_descriptors[] = {
   /*  10 */ { do_unix_unlink, "unlink" },
   /*  11 */ { 0, "execve" },
   /*  12 */ { do_unix_chdir, "chdir" },
-  /*  13 */ { 0, "time" },
+  /*  13 */ { do_unix_time, "time" },
   /*  14 */ { 0, "mknod" },
   /*  15 */ { 0, "chmod" },
   /*  16 */ { 0, "chown" },
@@ -2216,8 +2397,8 @@ static emul_syscall_descriptor linux_descriptors[] = {
   /*  74 */ { 0, "sethostname" },
   /*  75 */ { 0, "setrlimit" },
   /*  76 */ { 0, "getrlimit" },
-  /*  77 */ { 0, "getrusage" },
-  /*  78 */ { 0, "gettimeofday" },
+  /*  77 */ { do_unix_getrusage, "getrusage" },
+  /*  78 */ { do_unix_gettimeofday, "gettimeofday" },
   /*  79 */ { 0, "settimeofday" },
   /*  80 */ { 0, "getgroups" },
   /*  81 */ { 0, "setgroups" },