]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
sched_do_syscalls: properly handle invalid fd in read/write, rather
authorJulian Seward <jseward@acm.org>
Thu, 23 May 2002 16:52:11 +0000 (16:52 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 23 May 2002 16:52:11 +0000 (16:52 +0000)
than dying with an assertion failure.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@314

coregrind/vg_scheduler.c
vg_scheduler.c

index 5f023dae2617a79ed05f5a6bc55bb642fbb915d1..801502b91633a2e1786f1cd7282eeeda4148e1fc 100644 (file)
@@ -601,6 +601,13 @@ Bool fd_is_blockful ( Int fd )
    return (res & VKI_O_NONBLOCK) ? False : True;
 }
 
+static
+Bool fd_is_valid ( Int fd )
+{
+   Int res = VG_(fcntl)( fd, VKI_F_GETFL, 0 );
+   return VG_(is_kerror)(res) ? False : True;
+}
+
 
 
 /* Possibly do a for tid.  Return values are:
@@ -826,6 +833,22 @@ void sched_do_syscall ( ThreadId tid )
       We later poll for I/O completion using select().  */
 
    fd = VG_(threads)[tid].m_ebx /* arg1 */;
+
+   /* Deal with error case immediately. */
+   if (!fd_is_valid(fd)) {
+      VG_(message)(Vg_UserMsg, 
+         "Warning: invalid file descriptor %d in syscall %s",
+         fd, syscall_no == __NR_read ? "read()" : "write()" );
+      VG_(check_known_blocking_syscall)(tid, syscall_no, NULL /* PRE */);
+      KERNEL_DO_SYSCALL(tid, res);
+      VG_(check_known_blocking_syscall)(tid, syscall_no, &res /* POST */);
+      /* We're still runnable. */
+      vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
+      return;
+   }
+
+   /* From here onwards we know that fd is valid. */
+
    orig_fd_blockness = fd_is_blockful(fd);
    set_fd_nonblocking(fd);
    vg_assert(!fd_is_blockful(fd));
index 5f023dae2617a79ed05f5a6bc55bb642fbb915d1..801502b91633a2e1786f1cd7282eeeda4148e1fc 100644 (file)
@@ -601,6 +601,13 @@ Bool fd_is_blockful ( Int fd )
    return (res & VKI_O_NONBLOCK) ? False : True;
 }
 
+static
+Bool fd_is_valid ( Int fd )
+{
+   Int res = VG_(fcntl)( fd, VKI_F_GETFL, 0 );
+   return VG_(is_kerror)(res) ? False : True;
+}
+
 
 
 /* Possibly do a for tid.  Return values are:
@@ -826,6 +833,22 @@ void sched_do_syscall ( ThreadId tid )
       We later poll for I/O completion using select().  */
 
    fd = VG_(threads)[tid].m_ebx /* arg1 */;
+
+   /* Deal with error case immediately. */
+   if (!fd_is_valid(fd)) {
+      VG_(message)(Vg_UserMsg, 
+         "Warning: invalid file descriptor %d in syscall %s",
+         fd, syscall_no == __NR_read ? "read()" : "write()" );
+      VG_(check_known_blocking_syscall)(tid, syscall_no, NULL /* PRE */);
+      KERNEL_DO_SYSCALL(tid, res);
+      VG_(check_known_blocking_syscall)(tid, syscall_no, &res /* POST */);
+      /* We're still runnable. */
+      vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
+      return;
+   }
+
+   /* From here onwards we know that fd is valid. */
+
    orig_fd_blockness = fd_is_blockful(fd);
    set_fd_nonblocking(fd);
    vg_assert(!fd_is_blockful(fd));