Miscellaneous helpers


Detailed Description

The misc family of functions provide wrappers not fitting in any other module and not being worth an own category for each of them.

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


Function Documentation

int ispath ( const char *  path  ) 

check if given path exists

Parameters:
[in] path path to check
Returns:
1 on success, 0 otherwise
See also:
stat(2)

Definition at line 21 of file ispath.c.

00022 {
00023         struct stat stats;
00024         return stat(path, &stats) == 0;
00025 }

int isdir ( const char *  path  ) 

check if given path is a directory

Parameters:
[in] path path to check
Returns:
1 on success, 0 otherwise
See also:
stat(2)

Definition at line 21 of file isdir.c.

00022 {
00023         struct stat stats;
00024         return stat(path, &stats) == 0 && S_ISDIR(stats.st_mode);
00025 }

int isfile ( const char *  path  ) 

check if given path is a regular file

Parameters:
[in] path path to check
Returns:
1 on success, 0 otherwise
See also:
stat(2)

Definition at line 21 of file isfile.c.

00022 {
00023         struct stat stats;
00024         return stat(path, &stats) == 0 && S_ISREG(stats.st_mode);
00025 }

int islink ( const char *  path  ) 

check if given path is a symbolic link

Parameters:
[in] path path to check
Returns:
1 on success, 0 otherwise
See also:
stat(2)

Definition at line 21 of file islink.c.

00022 {
00023         struct stat stats;
00024         return stat(path, &stats) == 0 && S_ISLNK(stats.st_mode);
00025 }

int ismount ( const char *  path  ) 

check if given path is a top-level mount point

Parameters:
[in] path path to check
Returns:
1 on success, 0 otherwise
See also:
stat(2)

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)

Parameters:
[in] path path to create
[in] mode file permissions
Returns:
0 on success, -1 on error with errno set
See also:
mkdir(2)

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)

Parameters:
[in] path path to create
[in] mode file permissions
Returns:
0 on success, -1 on error with errno set
See also:
mkdir(2)

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)

Parameters:
[in] path path to remove
Returns:
0 on success, -1 on error with errno set
See also:
unlink(2)

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

Parameters:
[in] path symlink to read
Returns:
on success a pointer to a string containing the destination of the link, NULL on error with errno set
See also:
unlink(2)

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

Parameters:
[in] srcfd filedescriptor to read from
[in] dstfd filedescriptor to write to
Returns:
0 on success, -1 on error with errno set

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 }


Generated on Tue Jun 19 20:38:45 2007 for lucid by  doxygen 1.5.2