bug-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bug in mapfile_stream.c


From: Sergey Poznyakoff
Subject: Bug in mapfile_stream.c
Date: Mon, 23 Apr 2001 13:41:10 +0300

Hello,

I've just come across a problem with mapfile_stream.c. When the user's
mailbox has zero size mmap fails on Solaris. On GNU/Linux it returns
NULL but subsequent munmap() fails, so the daemon replies with -ERR.
Solaris manpage on mmap clearly states that mmap returns EINVAL when:

     EINVAL    The arguments addr (if MAP_FIXED was specified) or
               off are not multiples of the page size as returned
               by sysconf().

               The field in flags is invalid (neither MAP_PRIVATE
               or MAP_SHARED is set).

               The argument len has a value less than or equal to
               0.
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Linux behaviour is not that consistent. It just states

       EINVAL We don't like start or length  or  offset.   (E.g.,
              they  are  too  large, or not aligned on a PAGESIZE
              boundary.)

The following patch fixes the situation:

Index: mailbox/mapfile_stream.c
===================================================================
RCS file: /cvs/mailutils/mailbox/mapfile_stream.c,v
retrieving revision 1.10
diff -c -r1.10 mapfile_stream.c
*** mapfile_stream.c    2001/04/18 04:34:42     1.10
--- mapfile_stream.c    2001/04/23 10:31:31
***************
*** 34,39 ****
--- 34,42 ----
  #ifdef _POSIX_MAPPED_FILES
  #include <sys/mman.h>
  
+ #ifndef MAP_FAILED
+ # define MAP_FAILED (void*)-1
+ #endif
  
  struct _mapfile_stream
  {
***************
*** 52,57 ****
--- 55,62 ----
      {
        munmap (mfs->ptr, mfs->size);
        close (mfs->fd);
+       mfs->ptr = MAP_FAILED;
+       mfs->fd = -1;
      }
    free (mfs);
  }
***************
*** 160,171 ****
      }
    if (ftruncate (mfs->fd, len) != 0)
      return errno;
!   mfs->ptr = mmap (0, len, mfs->flags, MAP_SHARED, mfs->fd, 0);
!   if (mfs->ptr == MAP_FAILED)
      {
!       int err = errno;
        close (mfs->fd);
!       return err;
      }
    mfs->size = len;
    return 0;
--- 165,185 ----
      }
    if (ftruncate (mfs->fd, len) != 0)
      return errno;
!   if (len == 0)
      {
!       mfs->ptr = MAP_FAILED;
        close (mfs->fd);
!       mfs->fd = -1;
!     }
!   else
!     {
!       mfs->ptr = mmap (0, len, mfs->flags, MAP_SHARED, mfs->fd, 0);
!       if (mfs->ptr == MAP_FAILED)
!       {
!         int err = errno;
!         close (mfs->fd);
!         return err;
!       }
      }
    mfs->size = len;
    return 0;
***************
*** 291,303 ****
        return err;
      }
    mfs->size = st.st_size;
!   mfs->ptr = mmap (0, mfs->size, mflag , MAP_SHARED, mfs->fd, 0);
!   if (mfs->ptr == MAP_FAILED)
      {
-       int err = errno;
-       close (mfs->fd);
        mfs->ptr = MAP_FAILED;
!       return err;
      }
    mfs->flags = mflag;
    stream_set_flags (stream, flags |MU_STREAM_NO_CHECK);
--- 313,334 ----
        return err;
      }
    mfs->size = st.st_size;
!   if (mfs->size == 0)
      {
        mfs->ptr = MAP_FAILED;
!       close (mfs->fd);
!       mfs->fd = -1;
!     }
!   else
!     {
!       mfs->ptr = mmap (0, mfs->size, mflag , MAP_SHARED, mfs->fd, 0);
!       if (mfs->ptr == MAP_FAILED)
!       {
!         int err = errno;
!         close (mfs->fd);
!         mfs->ptr = MAP_FAILED;
!         return err;
!       }
      }
    mfs->flags = mflag;
    stream_set_flags (stream, flags |MU_STREAM_NO_CHECK);



Cheers,
Sergey Poznyakoff




reply via email to

[Prev in Thread] Current Thread [Next in Thread]