This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Expected behavior?


Hi all,

Before submitting a bug, I would like to know if the following is an expected behavior. I have written a small program (attached) which basically multiplies a set of doubles stored in an input file by a scalar, and saves the resulting doubles in an output file. As arguments, the user has to specify an offset and a size. The offset is the starting point in both the input and output files, and the size says how many bytes to read from the input file, and write to the output file. Obviously, if the output file is empty and the offset is not equal 0, we will be creating a sparse file.

I have also attached a script which runs the program twice by creating two processes at the same time. Both processes use the same input and output files, and receive the same scalar and size values, but different offsets. With the give parameters, the processes read and write different "disjoint" portions of the input and output files. Note that the output file will be a sparse one because the processes leave "holes" in the file. The script also checks whether the content of the output file is correct or not.

The problem that I'm having is that the output file is not created correctly, and I am pretty sure that the problem is in the fwrite function. The first doubles (in an indefinite amount) written by sometimes the first process, sometimes the second, and sometimes both processes, are always 0.0, what seems to mean that there is a hole where there should not be. That occurs randomly.

Please, note that we are talking about independent processes which must not share any information about the file (such as the file pointer).

Does anyone have any clue about what is happening?

BTW, I do not have any problem if I use the "low-level" open, read, write and close functions. And I have got the problem in three different Linux distributions (SLES 10.2-sp1, RHEL 4, Fedora Core 6) with different glibc versions.

Thanks in advance,

Juan.

PS. I can send the input file if needed, but it does not contains anything special, just random numbers.
#include <stdio.h>
#include <stdlib.h>

#define DOUBLESIZE sizeof(double)

void multiply(FILE *fin, FILE *fout, double scalar, long total)
{
	double number;

	fread(&number, DOUBLESIZE, 1, fin);
	while (!feof(fin)) {
		number *= scalar;
		fwrite(&number, DOUBLESIZE, 1, fout);
		total--;
		if (total == 0)
			return;
		fread(&number, DOUBLESIZE, 1, fin);
	}
}

int main(int argc, char *argv[])
{
	FILE *fileIn;
	FILE *fileOut;
	double scalar;
	char *endptr;
	long skip, total;

	switch (argc) {
		case 6:
			fileIn = fopen(argv[2], "r+");
			if (!fileIn) {
				fprintf(stderr, "Unable to open %s\n", argv[2]);
				exit(2);
			}
			fileOut = fopen(argv[3], "w+");
			if (!fileOut) {
				fprintf(stderr, "Unable to open %s\n", argv[3]);
				exit(2);
			}
			break;
		default:
			fprintf(stderr, "Usage: %s scalar source destination skip size\n", argv[0]);
			exit(1);
	}

	scalar = strtod(argv[1], &endptr);
	if (*endptr) {
		fprintf(stderr, "%s is not a valid floating point number\n", argv[1]);
		exit(3);
	}

	skip = strtol(argv[4], &endptr, 0);
	if (*endptr) {
		fprintf(stderr, "%s is not a valid integer number\n", argv[1]);
		exit(3);
	}

	total = strtol(argv[5], &endptr, 0);
	if (*endptr) {
		fprintf(stderr, "%s is not a valid integer number\n", argv[1]);
		exit(3);
	}

	if (fseek(fileIn, skip, SEEK_SET) != 0) {
		fprintf(stderr, "fseek failed\n");
		exit(3);
	}

	if (fseek(fileOut, skip, SEEK_SET) != 0) {
		fprintf(stderr, "fseek failed\n");
		exit(3);
	}

	total /= DOUBLESIZE;
	multiply(fileIn, fileOut, scalar, total);

	fclose(fileIn);
	fclose(fileOut);

	return 0;
}

Attachment: script.sh
Description: application/shellscript


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]