X-Spam-Check-By: sourceware.org From: ericblake AT comcast DOT net (Eric Blake) To: Cliff Hones , cygwin AT cygwin DOT com Subject: Re: lseek + read = ENOENT Date: Fri, 20 Jan 2006 02:48:41 +0000 Message-Id: <012020060248.13997.43D04F890009515C000036AD22070009530A050E040D0C079D0A@comcast.net> Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com > This seems to be a bug in gcc. The off_t argument to lseek is a 64-bit > type, but instead of being sign-extended to 64 bits, the value passed > (-sizeof(data)) passed is only extended to 32-bits, so is actually +4294967292. No, it is not a bug in gcc. Read a good book on C, please. > > If you write: > int n = -sizeof(data); > lseek(fd, n, SEEK_END); > it works as expected. Mostly right, because there you are promoting a signed 32-bit number to a signed 64-bit number, which sign-extends. However, that approach is risky - if you have a file that is bigger than 2 GB, you will not get the correct result, because negation of an unsigned greater than 2GB results in a positive signed 32-bit value less than 2GB, instead of the intended negative 64-bit value with absolute value greater than 2GB. The safer fix is to call: lseek(fd, -(off_t)sizeof(data), SEEK_END); That is, perform the negation after the sign extension, instead of beforehand, since you know that 32-bit unsigned to 64-bit signed 0-extends, but that sizeof(data) is intended to be positive anyway, and 64-bit signed negation of a positive number is guaranteed to be safe. -- Eric Blake -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/