Reputation: 15
I'm trying to read a file using file descriptors (which is probably a lot more work than I need to do, but nonetheless..)
I'm trying to create an archiver similar to ar. I have a non empty file I'm trying to read from but when I try the read command to retrieve the first 8 bytes the return int is 0 which means it didn't read any bytes. And errno tells me everything went fine.
What I'm trying to do is read the string at the beginning of the file so I may run string comparisons.
Sorry about the spaghetti code, I'm still testing and trying to figure things out.
The problem is at the statement temp = read(archiveFD,buf,8); archiveFD points to my archive file, which is non empty but nothing is read.
command:
./a.out r ar.c archive.a
ar.c:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utime.h>
#include <errno.h>
#define BUF_SIZE 1024
int main(int argc, char *argv[]) {
int fileFD, archiveFD, openFlags;
mode_t filePerms;
ssize_t numRead;
char buf[BUF_SIZE];
char fileName[16];
const struct utimbuf *times;
char modTime[12];
char entry[29];
int temp;
char *line = NULL;
size_t len = 0;
if(strcmp(argv[1], "r") != 0 && strcmp(argv[1], "x") != 0 && strcmp(argv[1], "d") != 0 && strcmp(argv[1], "t") != 0) {
printf("%s","Not a valid command.\n");
return 0;
}
if(strcmp(argv[1], "r") == 0) {
if(argv[3] == NULL) {
printf("%s","Missing arguments.\n");
return 0;
}
fileFD = open(argv[2], O_RDONLY);
if(fileFD == -1) {
printf("%s","Error opening input file.\n");
return 0;
}
openFlags = O_CREAT | O_RDWR | O_TRUNC;
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
archiveFD = open(argv[3], openFlags, filePerms);
if(archiveFD == -1) {
printf("%s","Error opening archive file.\n");
return 0;
}
temp = read(archiveFD,buf,8);
//printf("%s",(char *) buf);
// if(strcmp("!<arch>\n",buf) != 0)
// write(archiveFD,"!<arch>\n",8); //begins archive
// printf("%s","here");
//}
printf("%d",temp);
printf("%s",strerror(errno));
//printf("%s",buf);
sprintf(fileName,"%-16s",argv[2]);
printf("%s",fileName);
utime(argv[2],times);
//strcpy(modTime,"12345678901234");
//printf("%s",modTime);
sprintf(modTime,"%-.12lld",(long long) times->modtime);
modTime[12] = '\0';
printf("%s",modTime);
sprintf(entry,"%s%s\n",fileName,modTime);
printf("%s",entry);
write(archiveFD,entry,29);
while((numRead = read(fileFD, buf, BUF_SIZE)) > 0)
if(write(archiveFD, buf, numRead) != numRead) {
printf("%s","Could not write whole buffer.\n");
return 0;
}
if(numRead == -1) {
printf("%s","Error reading.\n");
return 0;
}
if(close(fileFD) == -1) {
printf("%s","Error closing input file.\n");
return 0;
}
if(close(archiveFD) == -1) {
printf("%s","Error closing archive file.\n");
return 0;
}
}
return 0;
}`
archive.a:
ar.c 140737161196
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utime.h>
#include <errno.h>
#define BUF_SIZE 1024
int main(int argc, char *argv[]) {
int fileFD, archiveFD, openFlags;
mode_t filePerms;
ssize_t numRead;
char buf[BUF_SIZE];
char fileName[16];
const struct utimbuf *times;
char modTime[12];
char entry[29];
int temp;
char *line = NULL;
size_t len = 0;
if(strcmp(argv[1], "r") != 0 && strcmp(argv[1], "x") != 0 && strcmp(argv[1], "d") != 0 && strcmp(argv[1], "t") != 0) {
printf("%s","Not a valid command.\n");
return 0;
}
if(strcmp(argv[1], "r") == 0) {
if(argv[3] == NULL) {
printf("%s","Missing arguments.\n");
return 0;
}
fileFD = open(argv[2], O_RDONLY);
if(fileFD == -1) {
printf("%s","Error opening input file.\n");
return 0;
}
openFlags = O_CREAT | O_RDWR | O_TRUNC;
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
archiveFD = open(argv[3], openFlags, filePerms);
if(archiveFD == -1) {
printf("%s","Error opening archive file.\n");
return 0;
}
temp = read(archiveFD,buf,8);
//printf("%s",(char *) buf);
// if(strcmp("!<arch>\n",buf) != 0)
// write(archiveFD,"!<arch>\n",8); //begins archive
// printf("%s","here");
//}
printf("%d",temp);
printf("%s",strerror(errno));
//printf("%s",buf);
sprintf(fileName,"%-16s",argv[2]);
printf("%s",fileName);
utime(argv[2],times);
//strcpy(modTime,"12345678901234");
//printf("%s",modTime);
sprintf(modTime,"%-.12lld",(long long) times->modtime);
modTime[12] = '\0';
printf("%s",modTime);
sprintf(entry,"%s%s\n",fileName,modTime);
printf("%s",entry);
write(archiveFD,entry,29);
while((numRead = read(fileFD, buf, BUF_SIZE)) > 0)
if(write(archiveFD, buf, numRead) != numRead) {
printf("%s","Could not write whole buffer.\n");
return 0;
}
if(numRead == -1) {
printf("%s","Error reading.\n");
return 0;
}
if(close(fileFD) == -1) {
printf("%s","Error closing input file.\n");
return 0;
}
if(close(archiveFD) == -1) {
printf("%s","Error closing archive file.\n");
return 0;
}
}
return 0;
}
Upvotes: 1
Views: 5551
Reputation: 212268
In this block: (error checking omitted for brevity)
openFlags = O_CREAT | O_RDWR | O_TRUNC;
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
archiveFD = open(argv[3], openFlags, filePerms);
temp = read(archiveFD,buf,8);
I would absolutely expect read to return zero. You just opened the file with O_TRUNC
,
so even if the file wasn't empty, it is after you open it. If you do not want to discard all existing data, remove O_TRUNC
from openFlags.
Upvotes: 1