This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Expected behavior?
- From: Juan Piernas Canovas <juan dot piernascanovas at pnl dot gov>
- To: libc-alpha at sourceware dot org
- Date: Fri, 31 Aug 2007 18:32:28 -0700
- Subject: 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