]> rtime.felk.cvut.cz Git - l4.git/commitdiff
update
authorl4check <l4check@d050ee49-bd90-4346-b210-929a50b99cfc>
Wed, 23 Jun 2010 08:50:53 +0000 (08:50 +0000)
committerl4check <l4check@d050ee49-bd90-4346-b210-929a50b99cfc>
Wed, 23 Jun 2010 08:50:53 +0000 (08:50 +0000)
git-svn-id: http://svn.tudos.org/repos/oc/tudos/trunk@8 d050ee49-bd90-4346-b210-929a50b99cfc

12 files changed:
kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp
kernel/fiasco/src/kern/ia32/thread-ia32.cpp
l4/Makefile
l4/pkg/bootstrap/server/src/ldscript.inc
l4/pkg/l4re/include/env.h
l4/pkg/l4re_vfs/include/impl/ns_fs.h
l4/pkg/l4re_vfs/include/impl/ns_fs_impl.h
l4/pkg/l4re_vfs/include/impl/ro_file.h
l4/pkg/l4re_vfs/include/impl/ro_file_impl.h
l4/pkg/tmpfs/lib/src/fs.cc
l4/tool/bin/qemu-x86-launch
l4/tool/lib/L4/ModList.pm

index 058e0fc7214ee1ce1f67e9490a566736ac7b6d30..77f8b6f446fd0d58f20af9e25b1dd7b611f81306 100644 (file)
@@ -19,7 +19,7 @@ Thread::fast_return_to_user(Mword ip, Mword sp, bool = true)
 }
 
 IMPLEMENT inline
-Mword 
+Mword
 Thread::user_sp() const
 { return regs()->sp(); }
 
@@ -102,7 +102,7 @@ Thread::copy_utcb_to_ts(L4_msg_tag const &tag, Thread *snd, Thread *rcv,
   if (EXPECT_FALSE(rcv->exception_triggered()))
     {
       // triggered exception pending
-      Mem::memcpy_mwords (&ts->_gs, snd_utcb->values, s > 12 ? 12 : s);
+      Mem::memcpy_mwords(&ts->_gs, snd_utcb->values, s > 12 ? 12 : s);
       if (EXPECT_TRUE(s > 15))
        {
          Continuation::User_return_frame const *s
@@ -178,57 +178,57 @@ Thread::user_ip(Mword ip)
 
 PRIVATE inline
 int
-Thread::check_trap13_kernel (Trap_state *ts)
+Thread::check_trap13_kernel(Trap_state *ts)
 {
-  if (EXPECT_FALSE (ts->_trapno == 13 && (ts->_err & 3) == 0))
+  if (EXPECT_FALSE(ts->_trapno == 13 && (ts->_err & 3) == 0))
     {
       // First check if user loaded a segment register with 0 because the
       // resulting exception #13 can be raised from user _and_ kernel. If
       // the user tried to load another segment selector, the thread gets
       // killed.
       // XXX Should we emulate this too? Michael Hohmuth: Yes, we should.
-      if (EXPECT_FALSE (!(ts->_ds & 0xffff)))
+      if (EXPECT_FALSE(!(ts->_ds & 0xffff)))
        {
-         Cpu::set_ds (Gdt::data_segment ());
+         Cpu::set_ds(Gdt::data_segment());
          return 0;
        }
-      if (EXPECT_FALSE (!(ts->_es & 0xffff)))
+      if (EXPECT_FALSE(!(ts->_es & 0xffff)))
        {
-         Cpu::set_es (Gdt::data_segment ());
+         Cpu::set_es(Gdt::data_segment());
          return 0;
        }
-      if (EXPECT_FALSE (!(ts->_fs & 0xffff)))
+      if (EXPECT_FALSE(!(ts->_fs & 0xffff)))
        {
          ts->_fs = Utcb_init::utcb_segment();
          return 0;
        }
-      if (EXPECT_FALSE (!(ts->_gs & 0xffff)))
+      if (EXPECT_FALSE(!(ts->_gs & 0xffff)))
        {
          ts->_gs = Utcb_init::utcb_segment();
          return 0;
        }
-      if (EXPECT_FALSE (ts->_ds & 0xfff8) == Gdt::gdt_code_user)
+      if (EXPECT_FALSE(ts->_ds & 0xfff8) == Gdt::gdt_code_user)
        {
          WARN("%p eip=%08lx: code selector ds=%04lx",
                this, ts->ip(), ts->_ds & 0xffff);
-         Cpu::set_ds (Gdt::data_segment ());
+         Cpu::set_ds(Gdt::data_segment());
          return 0;
        }
-      if (EXPECT_FALSE (ts->_ds & 0xfff8) == Gdt::gdt_code_user)
+      if (EXPECT_FALSE(ts->_es & 0xfff8) == Gdt::gdt_code_user)
        {
          WARN("%p eip=%08lx: code selector es=%04lx",
                this, ts->ip(), ts->_es & 0xffff);
-         Cpu::set_es (Gdt::data_segment ());
+         Cpu::set_es(Gdt::data_segment());
          return 0;
        }
-      if (EXPECT_FALSE (ts->_ds & 0xfff8) == Gdt::gdt_code_user)
+      if (EXPECT_FALSE(ts->_fs & 0xfff8) == Gdt::gdt_code_user)
        {
          WARN("%p eip=%08lx: code selector fs=%04lx",
                this, ts->ip(), ts->_fs & 0xffff);
          ts->_fs = Utcb_init::utcb_segment();
          return 0;
        }
-      if (EXPECT_FALSE (ts->_ds & 0xfff8) == Gdt::gdt_code_user)
+      if (EXPECT_FALSE(ts->_gs & 0xfff8) == Gdt::gdt_code_user)
        {
          WARN("%p eip=%08lx: code selector gs=%04lx",
                this, ts->ip(), ts->_gs & 0xffff);
index 9a5428a074adc38f3eb61cb2ead917fb41b422a0..3066221ef6ee021aa8d6cbbf55f265784d1d63f9 100644 (file)
@@ -103,7 +103,7 @@ Thread::user_flags() const
 
 PRIVATE inline
 int
-Thread::is_privileged_for_debug (Trap_state * /*ts*/)
+Thread::is_privileged_for_debug(Trap_state * /*ts*/)
 {
 #if 0
   return ((ts->flags() & EFLAGS_IOPL) == EFLAGS_IOPL_U);
@@ -126,7 +126,7 @@ Thread::is_privileged_for_debug (Trap_state * /*ts*/)
     @param ip pagefault address */
 IMPLEMENT inline
 bool
-Thread::pagein_tcb_request (Return_frame *regs)
+Thread::pagein_tcb_request(Return_frame *regs)
 {
   unsigned long new_ip = regs->ip();
   if (*(Unsigned8*)new_ip == 0x48) // REX.W
@@ -195,7 +195,7 @@ Thread::print_page_fault_error(Mword e)
  */
 PUBLIC
 int
-Thread::handle_slow_trap (Trap_state *ts)
+Thread::handle_slow_trap(Trap_state *ts)
 { 
   Address ip;
   int from_user = ts->cs() & 3;
@@ -230,7 +230,7 @@ Thread::handle_slow_trap (Trap_state *ts)
   if (!check_trap13_kernel (ts))
     return 0;
 
-  if (EXPECT_FALSE (!from_user))
+  if (EXPECT_FALSE(!from_user))
     {
       // get also here if a pagefault was not handled by the user level pager
       if (ts->_trapno == 14)
@@ -239,13 +239,13 @@ Thread::handle_slow_trap (Trap_state *ts)
       goto generic_debug;      // we were in kernel mode -- nothing to emulate
     }
 
-  if (EXPECT_FALSE (ts->_trapno == 2))
+  if (EXPECT_FALSE(ts->_trapno == 2))
     goto generic_debug;        // NMI always enters kernel debugger
 
-  if (EXPECT_FALSE (ts->_trapno == 0xffffffff))
+  if (EXPECT_FALSE(ts->_trapno == 0xffffffff))
     goto generic_debug;        // debugger interrupt
 
-  check_f00f_bug (ts);
+  check_f00f_bug(ts);
 
   // so we were in user mode -- look for something to emulate
   
@@ -267,7 +267,7 @@ Thread::handle_slow_trap (Trap_state *ts)
 
   _recover_jmpbuf = &pf_recovery;
 
-  switch (handle_io_page_fault (ts, from_user))
+  switch (handle_io_page_fault(ts, from_user))
     {
     case 1: goto success;
     case 2: goto fail;
@@ -290,7 +290,7 @@ Thread::handle_slow_trap (Trap_state *ts)
     }
 
   // just print out some warning, we do the normal exception handling
-  handle_sysenter_trap (ts, ip, from_user);
+  handle_sysenter_trap(ts, ip, from_user);
 
   // check for general protection exception
   if (ts->_trapno == 13 && (ts->_err & 0xffff) == 0)
@@ -330,7 +330,7 @@ Thread::handle_slow_trap (Trap_state *ts)
       if (EXPECT_FALSE
          (is_privileged
           && (ip < Kmem::mem_user_max - 2)
-          && (mem_space()->peek ((Unsigned16*) ip, from_user)) == 0x300f
+          && (mem_space()->peek((Unsigned16*) ip, from_user)) == 0x300f
           && (Cpu::cpus.cpu(cpu()).can_wrmsr())))
         {
          printf("Detected wrmsr at %lx\n", ip);
@@ -349,13 +349,13 @@ Thread::handle_slow_trap (Trap_state *ts)
       if (EXPECT_FALSE
          (is_privileged
           && (ip < Kmem::mem_user_max - 2)
-          && (mem_space()->peek ((Unsigned16*) ip, from_user)) == 0x320f
+          && (mem_space()->peek((Unsigned16*) ip, from_user)) == 0x320f
           && (Cpu::cpus.cpu(cpu()).can_wrmsr())))
         {
           printf("Detected rdmsr at %lx\n", ip);
           if (0)
             {
-              do_rdmsr_in_kernel (ts);
+              do_rdmsr_in_kernel(ts);
 
               // consume instruction and continue
               ts->consume_instruction(2);
@@ -375,7 +375,7 @@ check_exception:
   // let's see if we have a trampoline to invoke
   if (ts->_trapno < 0x20 && ts->_trapno < _idt_limit)
     {
-      Idt_entry e = mem_space()->peek (_idt + ts->_trapno, 1);
+      Idt_entry e = mem_space()->peek(_idt + ts->_trapno, 1);
 
       if ((e.ist() & 0xe0) == 0x00
           && (e.access() & 0x1f) == 0x0f) // gate descriptor ok?
@@ -392,7 +392,7 @@ check_exception:
                 {
                   // someone interfered and changed our state
                  assert (state() & Thread_cancel);
-                  state_del (Thread_cancel);
+                  state_del(Thread_cancel);
                 }
 
               goto success;     // we've consumed the trap
@@ -402,7 +402,7 @@ check_exception:
 
   // backward compatibility cruft: check for those insane "int3" debug
   // messaging command sequences
-  if (ts->_trapno == 3 && is_privileged_for_debug (ts))
+  if (ts->_trapno == 3 && is_privileged_for_debug(ts))
     {
       if (int3_handler && int3_handler(ts))
        goto success;
@@ -427,7 +427,7 @@ fail_nomsg:
     ts->dump();
 
   if (Config::conservative)
-    kdb_ke ("thread killed");
+    kdb_ke("thread killed");
 
   halt();
 
@@ -439,9 +439,9 @@ generic_debug:
   _recover_jmpbuf = 0;
 
   if (!nested_trap_handler)
-    return handle_not_nested_trap (ts);
+    return handle_not_nested_trap(ts);
 
-  return call_nested_trap_handler (ts);
+  return call_nested_trap_handler(ts);
 }
 
 /**
@@ -455,8 +455,8 @@ generic_debug:
  */
 extern "C" FIASCO_FASTCALL
 int
-thread_page_fault (Address pfa, Mword error_code, Address ip, Mword flags,
-                  Return_frame *regs)
+thread_page_fault(Address pfa, Mword error_code, Address ip, Mword flags,
+                 Return_frame *regs)
 {
 
   // XXX: need to do in a different way, if on debug stack e.g.
@@ -481,7 +481,7 @@ thread_page_fault (Address pfa, Mword error_code, Address ip, Mword flags,
   else 
     {
       // page fault in kernel memory region
-      if (Kmem::is_kmem_page_fault (pfa, error_code))
+      if (Kmem::is_kmem_page_fault(pfa, error_code))
        {
          // We've interrupted a context in the kernel with disabled interrupts,
          // the page fault address is in the kernel region, the error code is
@@ -491,7 +491,7 @@ thread_page_fault (Address pfa, Mword error_code, Address ip, Mword flags,
          // Remain cli'd !!!
        }
       else if (!Config::conservative &&
-              !Kmem::is_kmem_page_fault (pfa, error_code))
+              !Kmem::is_kmem_page_fault(pfa, error_code))
        {
           // No error -- just enable interrupts.
          Proc::sti();
@@ -506,7 +506,7 @@ thread_page_fault (Address pfa, Mword error_code, Address ip, Mword flags,
        }
     }
 
-  return current_thread()->handle_page_fault (pfa, error_code, ip, regs);
+  return current_thread()->handle_page_fault(pfa, error_code, ip, regs);
 }
 
 /** The catch-all trap entry point.  Called by assembly code when a 
@@ -530,7 +530,7 @@ thread_handle_trap(Trap_state *ts, unsigned)
 
 IMPLEMENT inline
 bool
-Thread::handle_sigma0_page_fault (Address pfa)
+Thread::handle_sigma0_page_fault(Address pfa)
 {
   size_t size;
 
@@ -636,7 +636,7 @@ IMPLEMENTATION [(ia32,amd64,ux) && !io]:
 
 PRIVATE inline
 int
-Thread::handle_io_page_fault (Trap_state *, bool)
+Thread::handle_io_page_fault(Trap_state *, bool)
 { return 0; }
 
 PRIVATE inline
@@ -669,7 +669,7 @@ static
 void
 int3_handler_init()
 {
-  Thread::set_int3_handler (Thread::handle_int3);
+  Thread::set_int3_handler(Thread::handle_int3);
 }
 
 IMPLEMENT static inline NEEDS ["gdt.h"]
@@ -737,7 +737,7 @@ Thread::set_int3_handler(int (*handler)(Trap_state *ts))
  */
 PUBLIC static
 int
-Thread::handle_int3 (Trap_state *ts)
+Thread::handle_int3(Trap_state *ts)
 {
   Mem_space *s   = current_mem_space();
   int from_user  = ts->cs() & 3;
@@ -854,7 +854,7 @@ Thread::handle_int3 (Trap_state *ts)
 
 PRIVATE inline
 void
-Thread::check_f00f_bug (Trap_state *ts)
+Thread::check_f00f_bug(Trap_state *ts)
 {
   // If we page fault on the IDT, it must be because of the F00F bug.
   // Figure out exception slot and raise the corresponding exception.
@@ -879,9 +879,8 @@ Thread::check_io_bitmap_delimiter_fault(Trap_state *ts)
       // page fault in the first byte following the IO bitmap
       // map in the cpu_page read_only at the place
       Mem_space::Status result =
-       mem_space()->v_insert (
-           Mem_space::Phys_addr(mem_space()->virt_to_phys_s0
-             ((void*)Kmem::io_bitmap_delimiter_page())),
+       mem_space()->v_insert(
+           Mem_space::Phys_addr(mem_space()->virt_to_phys_s0((void*)Kmem::io_bitmap_delimiter_page())),
            Mem_space::Addr::create(Mem_layout::Io_bitmap + Mem_layout::Io_port_max / 8),
            Mem_space::Size::create(Config::PAGE_SIZE),
            Pt_entry::global());
@@ -907,25 +906,25 @@ Thread::check_io_bitmap_delimiter_fault(Trap_state *ts)
 
 PRIVATE inline
 bool
-Thread::handle_sysenter_trap (Trap_state *ts, Address eip, bool from_user)
+Thread::handle_sysenter_trap(Trap_state *ts, Address eip, bool from_user)
 {
   if (EXPECT_FALSE
       ((ts->_trapno == 6 || ts->_trapno == 13)
        && (ts->_err & 0xffff) == 0
        && (eip < Kmem::mem_user_max - 2)
-       && (mem_space()->peek ((Unsigned16*) eip, from_user)) == 0x340f))
+       && (mem_space()->peek((Unsigned16*) eip, from_user)) == 0x340f))
     {
       // somebody tried to do sysenter on a machine without support for it
-      WARN ("tcb=%p killed:\n"
-           "\033[1;31mSYSENTER not supported on this machine\033[0m",
-           this);
+      WARN("tcb=%p killed:\n"
+          "\033[1;31mSYSENTER not supported on this machine\033[0m",
+          this);
 
       if (Cpu::have_sysenter())
        // GP exception if sysenter is not correctly set up..
-        WARN ("MSR_SYSENTER_CS: %llx", Cpu::rdmsr (MSR_SYSENTER_CS));
+        WARN("MSR_SYSENTER_CS: %llx", Cpu::rdmsr(MSR_SYSENTER_CS));
       else
        // We get UD exception on processors without SYSENTER/SYSEXIT.
-        WARN ("SYSENTER/EXIT not available.");
+        WARN("SYSENTER/EXIT not available.");
 
       return false;
     }
@@ -935,12 +934,12 @@ Thread::handle_sysenter_trap (Trap_state *ts, Address eip, bool from_user)
 
 PRIVATE inline
 bool
-Thread::trap_is_privileged (Trap_state *)
+Thread::trap_is_privileged(Trap_state *)
 { return space()->has_io_privileges(); }
 
 PRIVATE inline
 void
-Thread::do_wrmsr_in_kernel (Trap_state *ts)
+Thread::do_wrmsr_in_kernel(Trap_state *ts)
 {
   // do "wrmsr (msr[ecx], edx:eax)" in kernel
   Cpu::wrmsr (ts->value(), ts->value3(), ts->value2());
@@ -948,26 +947,26 @@ Thread::do_wrmsr_in_kernel (Trap_state *ts)
 
 PRIVATE inline
 void
-Thread::do_rdmsr_in_kernel (Trap_state *ts)
+Thread::do_rdmsr_in_kernel(Trap_state *ts)
 {
   // do "rdmsr (msr[ecx], edx:eax)" in kernel
-  Unsigned64 msr = Cpu::rdmsr (ts->value2());
+  Unsigned64 msr = Cpu::rdmsr(ts->value2());
   ts->value((Unsigned32) msr);
   ts->value3((Unsigned32) (msr >> 32));
 }
 
 PRIVATE inline
 int
-Thread::handle_not_nested_trap (Trap_state *ts)
+Thread::handle_not_nested_trap(Trap_state *ts)
 {
   // no kernel debugger present
-  printf (" %p IP="L4_PTR_FMT" Trap=%02lx [Ret/Esc]\n",
-         this, ts->ip(), ts->_trapno);
+  printf(" %p IP="L4_PTR_FMT" Trap=%02lx [Ret/Esc]\n",
+        this, ts->ip(), ts->_trapno);
 
   int r;
   // cannot use normal getchar because it may block with hlt and irq's
   // are off here
-  while ((r=Kconsole::console()->getchar (false)) == -1)
+  while ((r=Kconsole::console()->getchar(false)) == -1)
     Proc::pause();
 
   if (r == '\033')
index f8eba633eaa59074de2a87e597fdab19f448d660..aab5e2c8b19f54fedbc806c9d9a96be63d85118a 100644 (file)
@@ -336,6 +336,12 @@ qemu:
          SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)"   \
          $(L4DIR)/tool/bin/qemu-x86-launch $$ml "$$e" $(QEMU_OPTIONS)
 
+kexec:
+       $(VERBOSE)$(entryselection);                                  \
+        L4DIR=$(L4DIR)                                   \
+         SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)"   \
+         $(L4DIR)/tool/bin/kexec-launch $$ml "$$e"
+
 ux:
        $(VERBOSE)if [ "$(ARCH)" != "x86" ]; then                   \
          echo "This mode can only be used with architecture x86."; \
@@ -373,7 +379,7 @@ grub2iso:
          SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)"    \
          $(L4DIR)/tool/bin/gengrub2iso --timeout=0 $$ml               \
             $(OBJ_BASE)/images/$$(echo $$e | tr '[ ]' '[_]').iso "$$e"
-       
+
 .PHONY: image qemu ux switch_ram_base grub1iso grub2iso
 
 switch_ram_base:
index a87fcb3b08175debe8700636bccdc8d2765837cb..718fd55371a3cb6ba5dbfd40980cbb67482bbce6 100644 (file)
@@ -2,6 +2,7 @@
    Common functionality for linker scripts in bootstrap */
 
 #define CTORS                             \
+    . = ALIGN(8);                         \
     PROVIDE (__CTORS_BEGIN = .);          \
     KEEP (*(SORT(.ctors.*)))              \
     KEEP (*(.ctors))                      \
index 6ca4ceed73aafd14a897a347d8fd3fbfc8642aff..dbd061329cd5e380dba74e52a8a5f2efab4fc958 100644 (file)
@@ -35,8 +35,9 @@ typedef struct l4re_env_cap_entry_t
    * \brief The capability selector for the obeject.
    */
   l4_cap_idx_t cap;
+
   /**
-   * \brief Some falgs for the object.
+   * \brief Some flags for the object.
    * \note Currently unused.
    */
   l4_umword_t flags;
index 0f6d9e9355d3072855f05a44490409efdf84ce1a..b288ac8be979e60b14dc8fb2fd64b11c03397178 100644 (file)
@@ -39,14 +39,16 @@ protected:
 class Env_dir : public Ns_base_dir
 {
 public:
-  explicit Env_dir(L4Re::Env const *env) : _env(env) {}
+  explicit Env_dir(L4Re::Env const *env)
+  : _env(env), _current_cap_entry(env->initial_caps()) {}
 
   ssize_t readv(const struct iovec*, int) throw() { return -EISDIR; }
   ssize_t writev(const struct iovec*, int) throw() { return -EISDIR; }
-  int fstat64(struct stat64 *) const throw() { return -EINVAL; }
+  int fstat64(struct stat64 *) const throw();
   int faccessat(const char *path, int mode, int flags) throw();
   int get_entry(const char *path, int flags, mode_t mode,
                 Ref_ptr<L4Re::Vfs::File> *) throw();
+  ssize_t getdents(char *, size_t) throw();
 
   ~Env_dir() throw() {}
 
@@ -55,7 +57,7 @@ private:
   int get_ds(const char *path, L4Re::Auto_cap<L4Re::Dataspace>::Cap *ds) throw();
 
   L4Re::Env const *_env;
-
+  Env::Cap_entry const *_current_cap_entry;
 };
 
 class Ns_dir : public Ns_base_dir
@@ -65,7 +67,7 @@ public:
 
   ssize_t readv(const struct iovec*, int) throw() { return -EISDIR; }
   ssize_t writev(const struct iovec*, int) throw() { return -EISDIR; }
-  int fstat64(struct stat64 *) const throw() { return -EINVAL; }
+  int fstat64(struct stat64 *) const throw();
   int faccessat(const char *path, int mode, int flags) throw();
   int get_entry(const char *path, int flags, mode_t mode,
                 Ref_ptr<L4Re::Vfs::File> *) throw();
index 7482ad96c69b85881c77b2d9cf84560c8b206dda..8cb099244818e4293e8c379422237be2f42254ef 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <l4/re/dataspace>
 #include <l4/re/util/env_ns>
-#include <cstring>
+#include <dirent.h>
 
 namespace L4Re { namespace Core {
 
@@ -112,6 +112,25 @@ Ns_dir::faccessat(const char *path, int mode, int flags) throw()
   return 0;
 }
 
+int Ns_dir::
+fstat64(struct stat64 *b) const throw()
+{
+  b->st_dev = 1;
+  b->st_ino = 1;
+  b->st_mode = S_IRWXU | S_IFDIR;
+  b->st_nlink = 0;
+  b->st_uid = 0;
+  b->st_gid = 0;
+  b->st_rdev = 0;
+  b->st_size = 0;
+  b->st_blksize = 0;
+  b->st_blocks = 0;
+  b->st_atime = 0;
+  b->st_mtime = 0;
+  b->st_ctime = 0;
+  return 0;
+}
+
 int
 Env_dir::get_ds(const char *path, L4Re::Auto_cap<L4Re::Dataspace>::Cap *ds) throw()
 {
@@ -221,4 +240,62 @@ Env_dir::faccessat(const char *path, int mode, int flags) throw()
   return 0;
 }
 
+int
+Env_dir::fstat64(struct stat64 *b) const throw()
+{
+  b->st_dev = 1;
+  b->st_ino = 1;
+  b->st_mode = S_IRWXU | S_IFDIR;
+  b->st_nlink = 0;
+  b->st_uid = 0;
+  b->st_gid = 0;
+  b->st_rdev = 0;
+  b->st_size = 0;
+  b->st_blksize = 0;
+  b->st_blocks = 0;
+  b->st_atime = 0;
+  b->st_mtime = 0;
+  b->st_ctime = 0;
+  return 0;
+}
+
+ssize_t
+Env_dir::getdents(char *buf, size_t sz) throw()
+{
+  struct dirent64 *d = (struct dirent64 *)buf;
+  ssize_t ret = 0;
+
+  while (d
+         && _current_cap_entry
+         && _current_cap_entry->flags != ~0UL)
+    {
+      unsigned l = strlen(_current_cap_entry->name) + 1;
+      if (l > sizeof(d->d_name))
+        l = sizeof(d->d_name);
+
+      unsigned n = offsetof (struct dirent64, d_name) + l;
+
+      if (n <= sz)
+        {
+          d->d_ino = 1;
+          d->d_off = 0;
+          memcpy(d->d_name, _current_cap_entry->name, l);
+          d->d_name[l - 1] = 0;
+          d->d_reclen = n;
+          ret += n;
+          sz  -= n;
+          d    = (struct dirent64 *)((unsigned long)d + n);
+          _current_cap_entry++;
+        }
+      else
+        return ret;
+    }
+
+  // bit of a hack because we should only (re)set this when opening the dir
+  if (!ret)
+    _current_cap_entry = _env->initial_caps();
+
+  return ret;
+}
+
 }}
index d6e05f7a96e316dab4e9e5bd17c0d10c144af522..b5ff4841a9e709c2bd96a2d71116215fbaa8d5a6 100644 (file)
@@ -44,6 +44,8 @@ public:
   off64_t lseek64(off64_t, int) throw();
   int fstat64(struct stat64 *buf) const throw();
 
+  int ioctl(unsigned long, va_list) throw();
+
   int get_status_flags() const throw()
   { return O_RDONLY; }
 
index 7f900174f5c54fe80b4e77a76df5f118940d2ac0..0804ea2d39d52441f27f5f96a1b23a4468d5c9ec 100644 (file)
@@ -17,6 +17,8 @@
 #include "ds_util.h"
 #include "ro_file.h"
 
+#include <sys/ioctl.h>
+
 #include <l4/re/env>
 
 namespace L4Re { namespace Core {
@@ -139,4 +141,17 @@ Ro_file::lseek64(off64_t offset, int whence) throw()
   return _f_pos;
 }
 
+int
+Ro_file::ioctl(unsigned long v, va_list args) throw()
+{
+  switch (v)
+    {
+    case FIONREAD: // return amount of data still available
+      int *available = va_arg(args, int *);
+      *available = _size - _f_pos;
+      return 0;
+    };
+  return -EINVAL;
+}
+
 }}
index f3c5ae33c7773ac8893dcf0aa5351e1cd4449a9e..efeca5bf2900c7eabe2becb5891563304d91a159 100644 (file)
@@ -12,6 +12,7 @@
 #include <l4/cxx/avl_tree>
 
 #include <sys/stat.h>
+#include <sys/ioctl.h>
 #include <errno.h>
 
 #include <cstdio>
@@ -177,6 +178,7 @@ public:
   ssize_t writev(const struct iovec*, int iovcnt) throw();
   off64_t lseek64(off64_t, int) throw();
   int fstat64(struct stat64 *buf) const throw();
+  int ioctl(unsigned long, va_list) throw();
 
 private:
   Ref_ptr<Pers_file> _file;
@@ -218,7 +220,6 @@ int Tmpfs_file::fstat64(struct stat64 *buf) const throw()
   return 0;
 }
 
-
 off64_t Tmpfs_file::lseek64(off64_t offset, int whence) throw()
 {
   switch (whence)
@@ -235,6 +236,21 @@ off64_t Tmpfs_file::lseek64(off64_t offset, int whence) throw()
   return _pos;
 }
 
+int
+Tmpfs_file::ioctl(unsigned long v, va_list args) throw()
+{
+  switch (v)
+    {
+    case FIONREAD: // return amount of data still available
+      int *available = va_arg(args, int *);
+      *available = _file->data().size() - _pos;
+      return 0;
+    };
+  return -EINVAL;
+}
+
+
+
 
 int
 Tmpfs_dir::get_entry(const char *name, int flags, mode_t mode,
index 2376e3b27f63a1cd8475d4b19265c19be30a74aa..5cc1c20bc90ce48bc0f08a29d808d86d009c344b 100755 (executable)
@@ -28,23 +28,10 @@ sub get_file($$)
   my $command = shift;
   my $cmdline = shift;
 
-  my $fp = L4::ModList::search_file_or_die($command, $module_path);
+  my $fp = L4::ModList::get_file_uncompressed_or_die($command, $module_path,
+                                                     $unzip_tmp);
 
   $cmdline =~ s/^\S+\s*//;
-
-  open F, $fp || die "connot open '$fp': $!";
-  my $buf;
-  read F, $buf, 2;
-  close F;
-
-  if (unpack("n", $buf) == 0x1f8b) {
-    (my $tf = $fp) =~ s|.*/||;
-    $tf = $unzip_tmp.'/'.$tf;
-    print "'$fp' is a zipped file, uncompressing to '$tf'\n";
-    system("zcat $fp >$tf");
-    $fp = $tf;
-  }
-
   $fp.' '.$cmdline;
 }
 
index 8053c66b48acee7cc1e2ffd383f620d8e9f800de..928d32a6537b9bab190c206fc3ed0f87d3c5504e 100644 (file)
@@ -272,6 +272,33 @@ sub search_file_or_die($$)
   $f;
 }
 
+sub get_file_uncompressed_or_die($$$)
+{
+  my $command = shift;
+  my $paths   = shift;
+  my $tmpdir  = shift;
+
+  my $fp = L4::ModList::search_file_or_die($command, $paths);
+
+  open F, $fp || die "connot open '$fp': $!";
+  my $buf;
+  read F, $buf, 2;
+  close F;
+
+  if (unpack("n", $buf) == 0x1f8b) {
+    (my $tf = $fp) =~ s|.*/||;
+    $tf = $tmpdir.'/'.$tf;
+    print "'$fp' is a zipped file, uncompressing to '$tf'\n";
+    system("zcat $fp >$tf");
+    $fp = $tf;
+  }
+
+  $fp;
+}
+
+
+
+
 sub generate_grub1_entry($$%)
 {
   my $entryname = shift;