Subject: c-client & iovec references

From: David Simmons <[email-masked]>
Date: Tue, 17 Oct 1995 16:45:14 -0500 (CDT)

The newer (experimental) versions of the Linux kernel provide a
/usr/include/linux/uio.h header file which defines the struct iovec.
The iov_base element of this struct is typed "void *".
Previously, linux typed this element as __ptr_t, supposedly incorrectly,
because the c-client OS dependency file os_lnx.h claims this is
incorrect, and defines it otherwise to be of type "caddr_t".  This
conflicts with the new kernel, which references linux/uio.h from other
files.  I fixed it by putting an "#include/uio.h" in the os_lnx.h and
commenting out the iovec definition.  This isn't a good fix, because
this would prevent c-client from being compiled under the older
release kernels.

Enough of the linux woes; on to the more general problem.  There is a
bit of code at several points in the c-client toolkit that causes problems:
	if ((iov[j].iov_base)[iov[j].iov_len - 2] == '\n') ...

With the linux's "void *" type for iov_base, and perhaps other operating
systems as well, this expression causes the compiler to attempt to
dereference "void *" and use a type "void" in a comparison.  This causes
an error.  Casting iov[j].iov_base to (char *) results in a correct
expression, regardless of whether iov_base is "void *", "__ptr_t",
or "caddr_t".  Maybe this cast should be added to the c-client code...
The problem currently manifests itself in bezerk.c (lines 885 and 1748)
and mmdf.c (lines 858 and 1693); line numbers reflect the IMAP4-ALPHA
release of the toolkit.

Any ideas?
(I'm assuming this is the correct forum to discuss c-client development
issues...)

--
David Simmons, [email-masked]
Internet Consultant, Aris Technology, Inc.
Visit my home page!  http://www.aris.com/~simmons/

---

From: Mark Crispin <[email-masked]>
Date: Tue, 17 Oct 1995 14:51:14 -0700 (PDT)

My position on this is that Linux's definition is still wrong.  The iov_base
element in this struct is caddr_t or char* in every other version of UNIX.

What's more, even Linux agrees that the buffer for write() is a char*

Apparently, socket.h is the guilty party responsible for including uio.h,
since c-client itself does not include it.  My suggestion is to write a
"#define iovec blurdybloop" "#undef iovec" around the include of socket.h, and
continue using the correct definition of iovec as given in the c-client
sources.  Another possibility is to do "#define _SYS_UIO.H" to prevent uio.h
from ever being included (you may need to verify the symbol name).  Let me
know if either works out.

My suggestion is that you report this bad definition of struct iovec as a bug
to the people developing Linux.  Since writev() is a C library function and
not a system call on Linux (or rather, it's in section 3 of the manual instead
of section 2), presumably the Linux people include it for compatibility and
thus should feel responsible for providing a compatible prototype.