delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2013/07/19/22:30:10

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
X-Received: by 10.224.64.202 with SMTP id f10mr8474537qai.2.1374286504234;
Fri, 19 Jul 2013 19:15:04 -0700 (PDT)
X-Received: by 10.49.40.167 with SMTP id y7mr841846qek.36.1374286504219; Fri,
19 Jul 2013 19:15:04 -0700 (PDT)
Newsgroups: comp.os.msdos.djgpp
Date: Fri, 19 Jul 2013 19:15:04 -0700 (PDT)
Complaints-To: groups-abuse AT google DOT com
Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=83.248.66.54; posting-account=aoTb7AoAAAD4q4_CcCBJFyBI0GVqJ3Jc
NNTP-Posting-Host: 83.248.66.54
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <36bd3498-4176-4ff5-ab3c-bb5ac9653073@googlegroups.com>
Subject: read() from a file descriptor returns wrong length if file contains
0x1a anywhere
From: fredrik DOT hultin AT gmail DOT com
Injection-Date: Sat, 20 Jul 2013 02:15:04 +0000
Bytes: 2629
Lines: 50
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

If a file contains 0x1f, read() will only return a "bytes read" length up to that point, even though it read longer than that. It will then seemingly erroneously report EOF on subsequent calls.

Eg. if a 200 byte file contains 0x1a on position 100, read() will return 100 even though it read 200 bytes. The next call to read() will then return 0, indicating EOF.

Is this some DOS:ism I'm unfamiliar with, or is it a bug in DJGPP?

Using the djcross 4.8.1 RPMs available from ftp://ftp.delorie.com/pub/djgpp/rpms/

Tested on FreeDOS 1.1 and DOSBox SVN.

code:

#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>

int main()
{
	// create a file with 0x1a in it
	FILE* f = fopen("test.tst", "w");
	assert(f);
	// if \x1a in this string is changed to anything else the 
	// program works as expected
	fputs("before \x1a after", f);
	fclose(f);

	// open a file descriptor to the file
	int fd = open("test.tst", O_RDONLY, 0);
	assert(fd >= 0);
	
	char buffer[32] = {0};
	int n = 0;

	// read while there's something left to read
	while( (n = read(fd, buffer, sizeof(buffer))) > 0){
		// here read returns 7 instead of the actual length of 
		// the file (14) and subsequent calls to read returns 0, 
		// indicating EOF
		printf("read str[%d]: '%.*s'\n", n, n, buffer);

		// the whole file has actually been read into the buffer 
		// which contains the correct data
		// (only the return value of read is broken)
		printf("in buffer:   '%.*s'\n", sizeof(buffer), buffer);
	}

	close(fd);

	return 0;
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019