Red Hat Bugzilla – Bug 47504
read/write -1 bytes
Last modified: 2007-04-18 12:34:30 EDT
Description of Problem:
When rpm reads or writes to/from a package it will always pass the value -1
to read or write as the (unsigned) number of bytes to read/write. On linux
this appears to work (accidentaly I would hope) but solaris to catches this
and returns an error (errno 22, Invalid Argument).
rpm -qp somepackage.rpm
rpm -ba somepackage.spec
This will work on linux, but fail on solaris
I think this is because neither fd->contentLength nor fd->bytesRemain is
ever set to anything but -1 before fdRead or fdWrite is called.
It appears to work if the sign bit of fd->bytesRemain is masked out, but
this is a hack and I am working on a patch with a "better" way to fix this.
Can you append the output of an example with --rpmiodebug set?
That should be enough for me to figger what's up and get a fix
in place, as the rpmio code is guaranteed to make your head hurt :-)
Created attachment 22827 [details]
this is the output from rpm -qp ~/rpms/sed-3.02-9.src.rpm --rpmiodebug
Here's the relevant piece:
=> Ferror(2f6d0) rc 0 | UFD 6 fp 0
==> Fileno(2f6d0) rc 6 | UFD 6 fp 0
==> fdRead(2f6d0,efffe190,96) rc -1 | UFD 6 fp 0
*** read: rc -1 errno 22 Invalid argument ""
error: read failed: Invalid argument (22)
==> Fclose(2f6d0) | UFD 6 fp
Here's the code:
rc = read(fdFileno(fd), buf, (count > fd->bytesRemain ? fd->bytesRemain :
The underlying issue is multiplexing mutiple I/O streams across an open file
descriptor of, say, a persistent HTTP/1.1 connection, so fdRead() needs to
simulate EOF based on ContentLength:. value, if present.
So the problem seems to be with the ssize_t prototype being treated
differently on Solaris in read(2) (from rpmio/rpmio_internal.h)
Ah yes, the comparison on linux is (casts added for clatity) unsigned
((size_t)count) > ((ssize_t)fd->bytes_remain)
so the problem is (I predict) that size_t is int, not unsigned, on
Solaris. If that's the case, I can get an unsigned cast in place
throughout rpmio comparisons in a jiffy.
Well a size_t is being defined as an unsigned int in sys/types.h, and when I
tried it that cast had no effect.
after rereading the manpage for read I noticed this line:
If the value of nbyte is greater than SSIZE_MAX, the result
It looks to me like the implementation in solaris 2.6 just considers this to be
Since we use rpm on a lot of platforms (including Solaris) too, I just built rpm
on a Solaris 2.8 box, and I can't reproduce this problem. Do you have Solaris
and is the problem happening there too? Other than some build issues, rpm from
CVS has worked for the few tests I've tried.
I tried building rpm from CVS on 2.6, but the db-3.3.11 build (part of rpm)
Solaris' `ar' command to core dump, and I can't take any of our 2.6 systems down
to apply the latest patch bundle to see if the problem goes away.
Unfortunately I only have access to 2.6 systems here so I can't say anything
about 2.7 or 2.8.
I cannot reach the CVS server from work so I've been working with the rawhide
packages and building them with the GNUpro tools so I don't know whether the
patches from Sun would fix your problem.
FWIW I'm using GNU ar 2.9-gnupro-99r1
Other than this one, I have not found any problems with rpms behavior beyond
some build issues (most of them have already gotten into CVS). I have a rather
trivial patch that fixes this problem if you get past your build problem.
So far this problem is localized to a single solaris 2.6 box (sorry Nathan),
I'm gonna defer this problem until someone tells me what the right
thing to do is.