Unix utilities (rewriting cp)

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
ajtgarber
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 97
Joined: Wed Jun 10, 2009 8:56 am

Unix utilities (rewriting cp)

Post by ajtgarber »

I've decided to start rewriting Unix utilities using Unix library calls in C so that I can become more familiar with the library calls and C, and I've run into a bit of a snag. I've rewritten cp so that it actually copies the file, but when I try to use cat to see the contents of the file it always tells me that it doesn't have permissions. How can I transfer the permissions of the first file into the destination file? Right now I have it (hopefully) changing the user and group of the destination file to be the same as the user who ran my cp clone (the group that is copied is probably just the group that my clone is in).

Code:

Code: Select all

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

int main(int argc, char* argv[]) {
	if(argc < 2) {
		printf("Usage: %s <from> <to>\n", argv[0]);
		return 1;
	}
	int sourcefd = open(argv[1], O_RDONLY);
	int destinationfd = open(argv[2], O_WRONLY | O_CREAT);
	if(sourcefd == -1 || destinationfd == -1) {
		printf("Cannot open a file, dumping descriptors:\n");
		printf("sourcefd: %i\n", sourcefd);
		printf("destinationfd: %i\n", destinationfd);
		return 1;
	}
	int chownVal = fchown(destinationfd, (uid_t)getuid(), (gid_t)getgid());
	if(chownVal == -1) {
		printf("Unable to chown to current user :(\n");
	}

	char* buffer = (char*) malloc(sizeof(char*) * 1024); //make a 1KB buffer
	int numRead;
	while( (numRead = read(sourcefd, buffer, 1024)) > 0) {
		write(destinationfd, buffer, numRead);
	}

	//clean up
	close(sourcefd);
	close(destinationfd);
	free(buffer);

	return 0;
}
Permissions of copied file: (ls -l)
--wx--x--T 1 ajtgarber ajtgarber 911 Dec 8 14:05 copied.c
Another thing that confuses me is that the copied file has the executable flag set, even though its just a .c file and I don't
think I told it to give the new file that permission
ajtgarber
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 97
Joined: Wed Jun 10, 2009 8:56 am

Re: Unix utilities (rewriting cp)

Post by ajtgarber »

I found how to do it, posting so people can possibly find this in the future:

Using the stat call I got a stat structure about the input file, then I passed the st_mode value from the structure
into the chmod cal.

Code:

Code: Select all

struct stat st;
int statVal = fstat(sourcefd, &st);
if(statVal == -1) {
	printf("Unable to stat %s\n", argv[1]);
}
int chmodVal = fchmod(destinationfd, st.st_mode);
if(chmodVal == -1) {
	printf("Unable to chmod %s\n", argv[2]);
}
Gotta love the man pages :P
man -s 2 stat
Post Reply