bscopy: Implement recursive mkdir (mkdir -p)
This commit is contained in:
parent
2d892495d6
commit
e91bbc1ff7
42
bscopy.c
42
bscopy.c
@ -28,7 +28,6 @@ size_t fcopy (size_t block, char* in_filename, char* out_filename);
|
|||||||
/* fcreate: create a new file at filename, if it doesn't exist.
|
/* fcreate: create a new file at filename, if it doesn't exist.
|
||||||
If file is attempted to be created in a nonexistent directory,
|
If file is attempted to be created in a nonexistent directory,
|
||||||
recursively create directories until the error is resolved.
|
recursively create directories until the error is resolved.
|
||||||
I have no time for grading mistakes due to user error.
|
|
||||||
args:
|
args:
|
||||||
size: size of file in bytes
|
size: size of file in bytes
|
||||||
filename: path to file
|
filename: path to file
|
||||||
@ -36,6 +35,13 @@ size_t fcopy (size_t block, char* in_filename, char* out_filename);
|
|||||||
size_t: difference between number of bytes requested and actually created (should be zero)
|
size_t: difference between number of bytes requested and actually created (should be zero)
|
||||||
*/
|
*/
|
||||||
int fcreate(size_t size, char* filename);
|
int fcreate(size_t size, char* filename);
|
||||||
|
/* dircreate: recursive mkdir (aka mkdir -p)
|
||||||
|
args:
|
||||||
|
path: path to directory
|
||||||
|
returns:
|
||||||
|
depth: number of directories created
|
||||||
|
*/
|
||||||
|
int dircreate(char* path);
|
||||||
|
|
||||||
int main (int argc, char** argv) {
|
int main (int argc, char** argv) {
|
||||||
int block_size = 1;
|
int block_size = 1;
|
||||||
@ -59,7 +65,7 @@ int main (int argc, char** argv) {
|
|||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
printf ("Copy %s to %s with blocksize of %d.\n", in, out, block_size);
|
printf ("Copy %s to %s with blocksize of %d.\n", in, out, block_size);
|
||||||
// start the clock
|
// start the clock
|
||||||
clock_t time = clock();
|
clock_t time = clock();
|
||||||
@ -69,6 +75,9 @@ int main (int argc, char** argv) {
|
|||||||
time = clock() - time;
|
time = clock() - time;
|
||||||
printf ("Copy of %.3f MBytes took %f seconds\n", (double)size / (1024*1024), (double) time / CLOCKS_PER_SEC);
|
printf ("Copy of %.3f MBytes took %f seconds\n", (double)size / (1024*1024), (double) time / CLOCKS_PER_SEC);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
|
*/
|
||||||
|
// Test dircreate
|
||||||
|
printf("dircreate returned %d\n",dircreate(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fcopy (size_t block, char *in_filename, char *out_filename) {
|
size_t fcopy (size_t block, char *in_filename, char *out_filename) {
|
||||||
@ -107,25 +116,37 @@ int min(int a, int b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recursive mkdir
|
// Recursive mkdir
|
||||||
int dircreate(char* path) {
|
int dircreate_recurse(char* path, int depth) {
|
||||||
|
if (depth == 2) {
|
||||||
|
printf("If you see this message, you've asked to create an awful lot of directories.\n");
|
||||||
|
}
|
||||||
while (mkdir(path, 0700)) {
|
while (mkdir(path, 0700)) {
|
||||||
switch (errno){
|
switch (errno){
|
||||||
case EEXIST:
|
case EEXIST:
|
||||||
return 0;
|
// path exists. Success!
|
||||||
|
return depth;
|
||||||
case ENOENT: {
|
case ENOENT: {
|
||||||
char subpath[0x1000] = {0}, *last_slash;
|
char subpath[0x1000] = {0}, *last_slash;
|
||||||
size_t l = 0;
|
size_t l = 0;
|
||||||
|
// get the length of the substring
|
||||||
last_slash = strrchr(path, '/');
|
last_slash = strrchr(path, '/');
|
||||||
l = path - (last_slash == NULL ? path : last_slash);
|
l = (last_slash == NULL ? path : last_slash) - path;
|
||||||
strncpy(subpath, path, min(l, 0x1000)); // construct the substring
|
strncpy(subpath, path, min(l, 0x1000)); // construct the substring
|
||||||
dircreate(subpath); // recurse
|
depth++;
|
||||||
|
// if at first you don't succeed, try and try again
|
||||||
|
depth = dircreate_recurse(subpath, depth); // recurse
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
printf("Could not create directory: %s\n", strerror(errno));
|
printf("Could not create directory %s: Error %d (%s)\n", path, errno, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return depth;
|
||||||
|
}
|
||||||
|
// wrap dircreate_recurse
|
||||||
|
int dircreate(char* path) {
|
||||||
|
return dircreate_recurse(path, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fcreate(size_t size, char* filename) {
|
int fcreate(size_t size, char* filename) {
|
||||||
@ -139,7 +160,7 @@ int fcreate(size_t size, char* filename) {
|
|||||||
// then, try to create a file in that directory
|
// then, try to create a file in that directory
|
||||||
uint8_t buffer[0x400] = {0}; // Assemble a buffer
|
uint8_t buffer[0x400] = {0}; // Assemble a buffer
|
||||||
FILE *file = fopen(filename, "w"); // Open for writing
|
FILE *file = fopen(filename, "w"); // Open for writing
|
||||||
F_ERROR(file, -1); // abort if error
|
F_ERROR(file, -1); // abort if error
|
||||||
// Copy 1024-byte chunks up until the desired filesize < 1024 bytes away
|
// Copy 1024-byte chunks up until the desired filesize < 1024 bytes away
|
||||||
while (size > 0x400) {
|
while (size > 0x400) {
|
||||||
size -= fwrite(buffer, 0x400, size/0x400, file);
|
size -= fwrite(buffer, 0x400, size/0x400, file);
|
||||||
@ -148,5 +169,6 @@ int fcreate(size_t size, char* filename) {
|
|||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
size -= fwrite(buffer, size, 1, file);
|
size -= fwrite(buffer, size, 1, file);
|
||||||
}
|
}
|
||||||
|
// Return the number of unwritten bytes, if any
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user