I have a while loop in which I am reading from an archive file and extracting the first file.
int fd = open(argv[2], O_RDWR | O_CREAT, 0666);
char name_buffer[16];
char size_buffer[10];
// go to the first header
lseek(fd, SARMAG, SEEK_CUR);
// store the number of bits read in a struct current_header
// until its size equal to the size of the entire
// header, or in other words, until the entire
// header is read
while ((num_read = read(fd, (char*) ¤t_header,
sizeof(struct ar_hdr))) == sizeof(struct ar_hdr))
{
// scans the current string in header and stores
// in nameStr array
sscanf(current_header.ar_name, "%s", name_buffer);
sscanf(current_header.ar_date, "%s", date_buffer);
sscanf(current_header.ar_uid, "%s", uid_buffer);
sscanf(current_header.ar_gid, "%s", gid_buffer);
int mode;
sscanf(current_header.ar_mode, "%o", &mode);
sscanf(current_header.ar_size, "%s", size_buffer);
sscanf(current_header.ar_fmag, "%s", fmag_buffer);
new_file_fd = open(name_buffer, O_WRONLY | O_CREAT | O_TRUNC);
int size = atoi(size_buffer);
char buf[size];
size_t count = size;
while ((n_read = read(fd, buf, size)) > 0)
{
n_write = 0;
do {
n = write(new_file_fd, &buf[n_write], n_read - n_write);
n_write += n;
} while (n_write < n_read);
}
close(new_file_fd);
}
lseek(fd, size + (size%2), SEEK_CUR);
For a given archive file with the structure:
!<arch>
File1 1382142494 501 20 100644 29 `
Testing 123
File2 1382142504 501 20 100644 23 `
Testing 246
The expected output should be a file "File1" that contains only the contents "Testing123". Instead, I get File1 with the contents: Testing 123
File2 1382142504 501 20 100644 23 `
Testing 246
For some reason, even though I've specified the amount of bits to read and write (parameter 3 is "size" which returns 29 -- the size of File1) it keeps reading and writing past 29 bytes.
Any ideas why this might be happening?
while ((n_read = read(fd, buf, size)) > 0)
You need to update size within the loop.
size -= n_read
Otherwise you're just going to continue looping until you get to the end of the file. The reason you need to loop a call to read() is just that it doesn't guarantee it will read the specified number of bytes on the first call, it only guarantees it won't exceed that. So you need to keep calling it until you've read all the bytes you want. But you do need to update the bytes parameter since the file descriptor fd
will keep advancing to the end of the file otherwise.