'preventing errors when implementing the mv command and copying strings from argv
I implemented the move command from linux.
I did not try to prevent errors. The program would check if the source file named in argv [1] exists and can be opened, how can I do that?
I also think it's a problem copying strings from argv, because I need to call malloc and free which also use system calls and thus affect the performance of the program (if I'm not mistaken)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
int main(int argc, char **argv)
{
char *source, *destination, *new_source, *new_destination;
char *current_directory;
if (argc != 3) {
printf("usage- %s source destination\n", *argv);
exit(EXIT_FAILURE);
}
// work on copy
source = (char*)malloc(strlen(argv[1]) + 1);
strcpy(source, argv[1]);
destination = (char*)malloc(strlen(argv[2]) + 1);
strcpy(destination, argv[2]);
current_directory = getenv("PWD");
new_source = (char*)malloc(strlen(source) + 1 + strlen(current_directory) + 1);
strcpy(new_source,current_directory);
strcat(new_source,"/");
strcat(new_source,source);
new_destination = (char*)malloc(strlen(destination) + 1 + strlen(current_directory) + 1 + strlen(source) + 1);
strcpy(new_destination,current_directory);
strcat(new_destination,"/");
strcat(new_destination,destination);
strcat(new_destination,"/");
strcat(new_destination,source);
/*execute systemcall*/
if(rename(new_source,new_destination) != 0){
fprintf(stderr,"error: %s\n",strerror(errno));
}
free(new_source);
free(new_destination);
free(source);
free(destination);
exit(EXIT_SUCCESS)
Solution 1:[1]
The use-cases i see :
- src || target is a directory
- src || target is a symlink
- src || target are not accessible (bad rights)
Take a look at this snippet :
int main(int ac, char **av) {
if (ac < 3)
return (1); // bad arguments
int sfd, tfd = -1;
if ((sfd = open(av[1], O_RDONLY | O_SYMLINK)) < 0 || (tfd = open(av[2], O_WRONLY | O_CREAT | O_TRUNC | O_SYMLINK, 0666)) < 0)
return (2); // opens fail
struct stat sstat, tstat;
if (stat(av[1], &sstat) || S_ISDIR(sstat.st_mode) || !stat(av[2], &tstat) && S_ISDIR(tstat.st_mode))
return (3); // no source or source is a directory or target is a directory
char *sdata = malloc(sstat.st_size);
if (read(sfd, sdata, sstat.st_size) < 0)
return (4); // read fail
if (write(tfd, sdata, sstat.st_size) < 0)
return (5); // write fail
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
