The isdir(), isfile() and islink() functions wrap the stat(2) system call and checks if the path in the string pointed to by path is a directory, regular file or link, respectively.
The mkdirp() function creates any missing parent directories of the path in the string pointed to by path, before creating the directory itself. The mkdirnamep() function additionally calls dirname(3) on the path string before calling mkdirp().
The path_concat() function concatenates the strings pointed to by dirname and basename and checks the latter using str_path_isdot().
The runlink() function removes all files and directories in the path pointed to by the string path.
Functions | |
int | ispath (const char *path) |
check if given path exists | |
int | isdir (const char *path) |
check if given path is a directory | |
int | isfile (const char *path) |
check if given path is a regular file | |
int | islink (const char *path) |
check if given path is a symbolic link | |
int | ismount (const char *path) |
check if given path is a top-level mount point | |
int | mkdirnamep (const char *path, mode_t mode) |
recursive mkdir(2) with dirname(3) | |
int | mkdirp (const char *path, mode_t mode) |
recursive mkdir(2) | |
int | runlink (const char *path) |
recursive unlink(2) and rmdir(2) | |
char * | readsymlink (const char *path) |
read contents of symlink | |
int | copy_file (int srcfd, int dstfd) |
copy a file |
int ispath | ( | const char * | path | ) |
int isdir | ( | const char * | path | ) |
int isfile | ( | const char * | path | ) |
int islink | ( | const char * | path | ) |
int ismount | ( | const char * | path | ) |
check if given path is a top-level mount point
[in] | path | path to check |
Definition at line 23 of file ismount.c.
References mem_free(), str_equal(), str_isempty, and str_path_dirname().
00024 { 00025 struct stat sb_path, sb_parent; 00026 int rc = 1; 00027 00028 if (str_isempty(path)) 00029 return 0; 00030 00031 if (str_equal(path, "/")) 00032 return 1; 00033 00034 char *parent = str_path_dirname(path); 00035 00036 if (lstat(path, &sb_path) == -1 || 00037 !S_ISDIR(sb_path.st_mode) || 00038 lstat(parent, &sb_parent) == -1 || 00039 sb_path.st_dev == sb_parent.st_dev) 00040 rc = 0; 00041 00042 mem_free(parent); 00043 return rc; 00044 }
int mkdirnamep | ( | const char * | path, | |
mode_t | mode | |||
) |
recursive mkdir(2) with dirname(3)
[in] | path | path to create |
[in] | mode | file permissions |
dirname(3)
Definition at line 23 of file mkdirnamep.c.
References mem_free(), mkdirp(), str_isempty, and str_path_dirname().
00024 { 00025 if (str_isempty(path)) 00026 return errno = EINVAL, -1; 00027 00028 char *dname = str_path_dirname(path); 00029 int rc = mkdirp(dname, mode); 00030 00031 mem_free(dname); 00032 00033 return rc; 00034 }
int mkdirp | ( | const char * | path, | |
mode_t | mode | |||
) |
recursive mkdir(2)
[in] | path | path to create |
[in] | mode | file permissions |
Definition at line 26 of file mkdirp.c.
References open_read(), str_isempty, str_path_isdot(), strtok_for_each, strtok_free(), and strtok_init_str().
Referenced by chroot_mkdirp(), and mkdirnamep().
00027 { 00028 int ok = 1; 00029 struct stat sb; 00030 00031 if (str_isempty(path) || str_path_isdot(path)) 00032 return errno = EINVAL, -1; 00033 00034 strtok_t _st, *st = &_st, *p; 00035 00036 int curdir = open_read("."); 00037 00038 if (curdir == -1) 00039 return -1; 00040 00041 if (!strtok_init_str(st, path, "/", 0)) 00042 return -1; 00043 00044 strtok_for_each(st, p) { 00045 if (mkdir(p->token, 0755) == -1) { 00046 if (errno != EEXIST || stat(p->token, &sb) == -1) { 00047 ok = 0; 00048 break; 00049 } 00050 00051 if (!S_ISDIR(sb.st_mode)) { 00052 errno = ENOTDIR; 00053 ok = 0; 00054 break; 00055 } 00056 } 00057 00058 if (chdir(p->token) == -1) { 00059 ok = 0; 00060 break; 00061 } 00062 } 00063 00064 if (ok && chmod(".", mode) == -1) 00065 ok = 0; 00066 00067 fchdir(curdir); 00068 close(curdir); 00069 00070 strtok_free(st); 00071 return ok ? 0 : -1; 00072 }
int runlink | ( | const char * | path | ) |
recursive unlink(2) and rmdir(2)
[in] | path | path to remove |
rmdir(2)
Definition at line 26 of file runlink.c.
References _lucid_asprintf(), mem_free(), and runlink().
Referenced by runlink().
00027 { 00028 struct stat sb; 00029 00030 DIR *dp; 00031 struct dirent *d; 00032 00033 int status = 0; 00034 char *p, *new_path; 00035 00036 if (lstat(path, &sb) == -1) { 00037 if (errno == ENOENT) 00038 return 0; 00039 else 00040 return -1; 00041 } 00042 00043 if (S_ISDIR(sb.st_mode)) { 00044 if (!(dp = opendir(path))) 00045 return -1; 00046 00047 while ((d = readdir(dp))) { 00048 p = d->d_name; 00049 00050 if (p && p[0] == '.' && (!p[1] || (p[1] == '.' && !p[2]))) 00051 continue; 00052 00053 _lucid_asprintf(&new_path, "%s/%s", path, d->d_name); 00054 00055 if (runlink(new_path) == -1) 00056 status = -1; 00057 00058 mem_free(new_path); 00059 } 00060 00061 if (closedir(dp) == -1) 00062 return -1; 00063 00064 if (rmdir(path) == -1) 00065 return -1; 00066 00067 return status; 00068 } 00069 00070 if (unlink(path) == -1) 00071 return -1; 00072 00073 return 0; 00074 }
char* readsymlink | ( | const char * | path | ) |
read contents of symlink
[in] | path | symlink to read |
rmdir(2)
Definition at line 24 of file readsymlink.c.
References CHUNKSIZE, mem_alloc(), mem_free(), and mem_realloc().
00025 { 00026 int chunks = 1, len = 0; 00027 char *buf = mem_alloc(chunks * CHUNKSIZE + 1); 00028 00029 while (1) { 00030 len = readlink(path, buf, chunks * CHUNKSIZE); 00031 00032 if (len == -1) { 00033 mem_free(buf); 00034 return NULL; 00035 } 00036 00037 if (len >= chunks * CHUNKSIZE) { 00038 chunks++; 00039 buf = mem_realloc(buf, chunks * CHUNKSIZE + 1); 00040 } 00041 00042 else 00043 break; 00044 } 00045 00046 buf[len] = '\0'; 00047 00048 return buf; 00049 }
int copy_file | ( | int | srcfd, | |
int | dstfd | |||
) |
copy a file
[in] | srcfd | filedescriptor to read from |
[in] | dstfd | filedescriptor to write to |
Definition at line 66 of file copy_file.c.
References CHUNKSIZE.
00067 { 00068 int errno_orig; 00069 int rc = -1, bufsize = 0; 00070 void *srcbuf = MAP_FAILED, *dstbuf = MAP_FAILED; 00071 00072 /* install SIGBUS handler for mmap */ 00073 void (*oldhandler)(int) = signal(SIGBUS, __copy_file_sigbus_handler); 00074 00075 /* get file length */ 00076 struct stat sb; 00077 00078 if (fstat(srcfd, &sb) == -1) 00079 goto out; 00080 00081 /* create sparse file */ 00082 if (ftruncate(dstfd, sb.st_size) == -1) 00083 goto out; 00084 00085 if (sb.st_size < 1) { 00086 rc = 0; 00087 goto out; 00088 } 00089 00090 /* save environment for non-local jump */ 00091 if (sigsetjmp(__copy_file_sigjmp_env, 1) != 0) 00092 goto out; 00093 00094 int offset = 0; 00095 00096 while (offset < sb.st_size) { 00097 bufsize = sb.st_size - offset; 00098 bufsize = bufsize > CHUNKSIZE ? CHUNKSIZE : bufsize; 00099 00100 /* map source file */ 00101 srcbuf = mmap(0, bufsize, PROT_READ, MAP_SHARED, srcfd, offset); 00102 00103 if (srcbuf == MAP_FAILED) 00104 goto out; 00105 00106 /* map destination file */ 00107 dstbuf = mmap(0, bufsize, PROT_WRITE, MAP_SHARED, dstfd, offset); 00108 00109 if (dstbuf == MAP_FAILED) 00110 goto out; 00111 00112 offset += bufsize; 00113 00114 /* advise to sequential order (more aggressive read ahead) */ 00115 madvise(srcbuf, bufsize, MADV_SEQUENTIAL); 00116 madvise(dstbuf, bufsize, MADV_SEQUENTIAL); 00117 00118 /* copy memory area with sparse support */ 00119 __copy_file_sparse_memcpy(dstbuf, srcbuf, bufsize); 00120 00121 munmap(srcbuf, bufsize); 00122 srcbuf = MAP_FAILED; 00123 00124 munmap(dstbuf, bufsize); 00125 dstbuf = MAP_FAILED; 00126 } 00127 00128 rc = 0; 00129 00130 out: 00131 if (srcbuf && srcbuf != MAP_FAILED) 00132 munmap(srcbuf, bufsize); 00133 00134 if (dstbuf && dstbuf != MAP_FAILED) 00135 munmap(dstbuf, bufsize); 00136 00137 errno_orig = errno; 00138 signal(SIGBUS, oldhandler); 00139 errno = errno_orig; 00140 return rc; 00141 }