![退会済みユーザー](https://ddjkaamml8q8x.cloudfront.net/profileImages/deletedUser/icnUserSample.jpeg)
###前提・実現したいこと
ls -r コマンドのC言語のソースコードを参考にして
cp -r コマンドを実装しているのですが
どこを変えていいのかわかりません…
###該当のソースコード
C
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <unistd.h> 5#include <dirent.h> 6#include <sys/types.h> 7#include <sys/stat.h> 8#include <errno.h> 9 10struct strbuf { 11 char *ptr; 12 size_t len; 13}; 14 15void traverse(struct strbuf *buf); 16void traverseSub(struct strbuf *buf, int first); 17struct strbuf *strbuf_new(void); 18void strbuf_realloc(struct strbuf *buf, size_t size); 19 20void print_error(char *s){ 21 fprintf(stderr, "%s: %s\n", s, strerror(errno)); 22} 23 24void die (const char *s){ 25 perror(s); 26 exit(1); 27} 28int main(int argc, char *argv[]){ 29 struct strbuf *pathbuf; 30 31 if(argc != 2){ 32 fprintf(stderr, "Usage: %s dir\n", argv[0]); 33 exit(1); 34 } 35 pathbuf = strbuf_new(); 36 strbuf_realloc(pathbuf, strlen(argv[1])); 37 strcpy(pathbuf->ptr, argv[1]); 38 traverse(pathbuf); 39 exit(0); 40} 41 42void traverse(struct strbuf *pathbuf){ 43 traverseSub(pathbuf, 1); 44} 45 46void traverseSub(struct strbuf *pathbuf, int first){ 47 DIR *d; 48 struct dirent *ent; 49 struct stat st; 50 51 d = opendir(pathbuf->ptr); 52 if (!d) { 53 switch (errno){ 54 case ENOTDIR: 55 return; 56 case ENOENT: 57 if(first){ 58 die(pathbuf->ptr); 59 } else { 60 return; 61 } 62 case EACCES: 63 puts(pathbuf->ptr); 64 print_error(pathbuf->ptr); 65 return; 66 default: 67 perror(pathbuf->ptr); 68 exit(1); 69 } 70 } 71 puts(pathbuf->ptr); 72 while(ent = readdir(d)){ 73 if(strcmp(ent->d_name, ".") == 0) 74 continue; 75 if(strcmp(ent->d_name, "..") == 0) 76 continue; 77 strbuf_realloc(pathbuf, pathbuf->len + 1 + strlen(ent->d_name) + 1); 78 // special handling for the root directory 79 if(strcmp(pathbuf->ptr, "/") != 0){ 80 strcat(pathbuf->ptr, "/"); 81 } 82 strcat(pathbuf->ptr, ent->d_name); 83 if(lstat(pathbuf->ptr, &st) < 0){ 84 switch (errno){ 85 case ENOENT: 86 break; 87 case EACCES: 88 print_error(pathbuf->ptr); 89 break; 90 default: 91 die(pathbuf->ptr); 92 } 93 } else { 94 if (S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode)) { 95 traverseSub(pathbuf, 0); 96 } else { 97 puts(pathbuf->ptr); 98 } 99 } 100 *strrchr(pathbuf->ptr, '/') = '\0'; 101 } 102 closedir(d); 103 } 104 105#define INITLEN 1024 106 107struct strbuf * strbuf_new(void){ 108 struct strbuf *buf; 109 110 buf = (struct strbuf*)malloc(sizeof(struct strbuf)); 111 if (!buf) { 112 die("malloc(3)"); 113 } 114 buf->ptr = malloc(INITLEN); 115 if(!buf->ptr){ 116 die("malloc(3)"); 117 } 118 buf->len = INITLEN; 119 return buf; 120} 121 122void strbuf_realloc(struct strbuf *buf, size_t len){ 123 char *tmp; 124 125 if(buf->len > len) 126 return; 127 tmp = realloc(buf->ptr, len); 128 if (!tmp) { 129 die("realloc(3)"); 130 } 131 buf->ptr = tmp; 132 buf->len = len; 133}
![退会済みユーザー](https://ddjkaamml8q8x.cloudfront.net/profileImages/deletedUser/icnUserSample.jpeg)
ソースコード中にコメントや、質問者ご自身の解釈を付記すれば、課題が浮かび上がると思います。
![guest](/img/icon/icnUserSample.jpg)
回答1件
あなたの回答
tips
プレビュー