]> granicus.if.org Git - strace/commitdiff
2004-09-13 Ulrich Drepper <drepper@redhat.com>, Dmitry V. Levin <ldv@altlinux.org>
authorRoland McGrath <roland@redhat.com>
Wed, 6 Oct 2004 22:27:43 +0000 (22:27 +0000)
committerRoland McGrath <roland@redhat.com>
Wed, 6 Oct 2004 22:27:43 +0000 (22:27 +0000)
* time.c [LINUX] (print_rtc): New function, for printing rtc_time
structure.
[LINUX] (rtc_ioctl): New function, for parsing RTC_* ioctls.
* ioctl.c [LINUX] (ioctl_decode): Call rtc_ioctl.
* defs.h [LINUX]: Declare rtc_ioctl.
Fixes RH#58606.

defs.h
ioctl.c
time.c

diff --git a/defs.h b/defs.h
index 2158bf86470206c7c511314d54a767effaeb7b27..fd3a3800ca610de3f90f117857464b6a34ea9a0b 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -476,6 +476,9 @@ extern int term_ioctl P((struct tcb *, long, long));
 extern int sock_ioctl P((struct tcb *, long, long));
 extern int proc_ioctl P((struct tcb *, int, int));
 extern int stream_ioctl P((struct tcb *, int, int));
+#ifdef LINUX
+extern int rtc_ioctl P((struct tcb *, long, long));
+#endif
 
 extern void tv_tv P((struct timeval *, int, int));
 extern int tv_nz P((struct timeval *));
diff --git a/ioctl.c b/ioctl.c
index 814caf0c1eb0d28b23c97355177e1bbf17ffae1c..aba69c7f0e36c29d561673c1a903f274878d75d3 100644 (file)
--- a/ioctl.c
+++ b/ioctl.c
@@ -149,6 +149,10 @@ long code, arg;
        case 'S':
                return stream_ioctl(tcp, code, arg);
 #endif /* HAVE_SYS_STREAM_H */
+#ifdef LINUX
+       case 'p':
+               return rtc_ioctl(tcp, code, arg);
+#endif
        default:
                break;
        }
diff --git a/time.c b/time.c
index d273f0c876cfcdd6dbadba56a0f0d86c17a2ddbf..5176f53645e7a26be7d484bae6c3f48e19bb5cf1 100644 (file)
--- a/time.c
+++ b/time.c
@@ -34,6 +34,8 @@
 #ifdef LINUX
 #include <linux/version.h>
 #include <sys/timex.h>
+#include <linux/ioctl.h>
+#include <linux/rtc.h>
 #endif /* LINUX */
 
 void
@@ -519,4 +521,95 @@ struct tcb *tcp;
        }
        return 0;
 }
+
+static void
+print_rtc(tcp, rt)
+struct tcb *tcp;
+const struct rtc_time *rt;
+{
+       tprintf("{tm_sec=%d, tm_min=%d, tm_hour=%d, "
+               "tm_mday=%d, tm_mon=%d, tm_year=%d, ",
+               rt->tm_sec, rt->tm_min, rt->tm_hour,
+               rt->tm_mday, rt->tm_mon, rt->tm_year);
+       if (!abbrev(tcp))
+               tprintf("tm_wday=%d, tm_yday=%d, tm_isdst=%d}",
+                       rt->tm_wday, rt->tm_yday, rt->tm_isdst);
+       else
+               tprintf("...}");
+}
+
+int
+rtc_ioctl(tcp, code, arg)
+struct tcb *tcp;
+long code;
+long arg;
+{
+       switch (code) {
+       case RTC_ALM_SET:
+       case RTC_SET_TIME:
+               if (entering(tcp)) {
+                       struct rtc_time rt;
+                       if (umove(tcp, arg, &rt) < 0)
+                               tprintf(", %#lx", arg);
+                       else {
+                               tprintf(", ");
+                               print_rtc(tcp, &rt);
+                       }
+               }
+               break;
+       case RTC_ALM_READ:
+       case RTC_RD_TIME:
+               if (exiting(tcp)) {
+                       struct rtc_time rt;
+                       if (syserror(tcp) || umove(tcp, arg, &rt) < 0)
+                               tprintf(", %#lx", arg);
+                       else {
+                               tprintf(", ");
+                               print_rtc(tcp, &rt);
+                       }
+               }
+               break;
+       case RTC_IRQP_SET:
+       case RTC_EPOCH_SET:
+               if (entering(tcp))
+                       tprintf(", %lu", arg);
+               break;
+       case RTC_IRQP_READ:
+       case RTC_EPOCH_READ:
+               if (exiting(tcp))
+                       tprintf(", %lu", arg);
+               break;
+       case RTC_WKALM_SET:
+               if (entering(tcp)) {
+                       struct rtc_wkalrm wk;
+                       if (umove(tcp, arg, &wk) < 0)
+                               tprintf(", %#lx", arg);
+                       else {
+                               tprintf(", {enabled=%d, pending=%d, ",
+                                       wk.enabled, wk.pending);
+                               print_rtc(tcp, &wk.time);
+                               tprintf("}");
+                       }
+               }
+               break;
+       case RTC_WKALM_RD:
+               if (exiting(tcp)) {
+                       struct rtc_wkalrm wk;
+                       if (syserror(tcp) || umove(tcp, arg, &wk) < 0)
+                               tprintf(", %#lx", arg);
+                       else {
+                               tprintf(", {enabled=%d, pending=%d, ",
+                                       wk.enabled, wk.pending);
+                               print_rtc(tcp, &wk.time);
+                               tprintf("}");
+                       }
+               }
+               break;
+       default:
+               if (entering(tcp))
+                       tprintf(", %#lx", arg);
+               break;
+       }
+       return 1;
+}
 #endif /* LINUX */