LCOV - code coverage report
Current view: top level - app/shared - fd_file_util.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 128 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 6 0.0 %

          Line data    Source code
       1             : #include "fd_file_util.h"
       2             : 
       3             : #include <stdio.h>
       4             : #include <errno.h>
       5             : #include <limits.h>
       6             : #include <dirent.h>
       7             : #include <fcntl.h>
       8             : #include <stdlib.h>
       9             : #include <unistd.h>
      10             : #include <sys/stat.h>
      11             : 
      12             : int
      13             : fd_file_util_read_ulong( char const * path,
      14           0 :                          ulong *      value ) {
      15           0 :   int fd = open( path, O_RDONLY );
      16           0 :   if( FD_UNLIKELY( -1==fd ) ) return -1;
      17             : 
      18           0 :   char buf[ 32UL ];
      19           0 :   long bytes_read = read(fd, buf, sizeof(buf)-1UL );
      20           0 :   if( FD_UNLIKELY( -1==bytes_read ) ) {
      21           0 :     close(fd);
      22           0 :     return -1;
      23           0 :   }
      24             : 
      25           0 :   if( FD_UNLIKELY( !bytes_read || (ulong)bytes_read>=sizeof(buf)-1UL ) ) {
      26           0 :     errno = EINVAL;
      27           0 :     close(fd);
      28           0 :     return -1;
      29           0 :   }
      30             : 
      31           0 :   buf[ bytes_read ] = '\0';
      32             : 
      33           0 :   if( FD_UNLIKELY( -1==close( fd ) ) ) return -1;
      34             : 
      35           0 :   char *endptr;
      36           0 :   errno = 0;
      37           0 :   ulong _value = strtoul( buf, &endptr, 10 );
      38           0 :   if( FD_UNLIKELY( errno==ERANGE ) ) return -1;
      39           0 :   if( FD_UNLIKELY( *endptr!='\n' && *endptr!='\0' ) ) {
      40           0 :     errno = EINVAL;
      41           0 :     return -1;
      42           0 :   }
      43             : 
      44           0 :   *value = _value;
      45           0 :   return 0;
      46           0 : }
      47             : 
      48             : int
      49             : fd_file_util_read_uint( char const * path,
      50           0 :                         uint *       value ) {
      51           0 :   ulong _value;
      52           0 :   int rc = fd_file_util_read_ulong( path, &_value );
      53           0 :   if( FD_UNLIKELY( -1==rc ) ) return -1;
      54           0 :   if( FD_UNLIKELY( _value>UINT_MAX ) ) {
      55           0 :     errno = ERANGE;
      56           0 :     return -1;
      57           0 :   }
      58           0 :   *value = (uint)_value;
      59           0 :   return 0;
      60           0 : }
      61             : 
      62             : int
      63             : fd_file_util_write_ulong( char const * path,
      64           0 :                           ulong        value ) {
      65           0 :   int fd = open( path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR );
      66           0 :   if( FD_UNLIKELY( -1==fd ) ) return -1;
      67             : 
      68           0 :   char buf[ 32UL ];
      69           0 :   int len = snprintf( buf, sizeof(buf), "%lu\n", value );
      70           0 :   FD_TEST( len>=0 && (ulong)len<sizeof(buf) );
      71             : 
      72           0 :   long written = write( fd, buf, (ulong)len );
      73           0 :   if( FD_UNLIKELY( -1==written ) ) {
      74           0 :     close( fd );
      75           0 :     return -1;
      76           0 :   } else if( FD_UNLIKELY( written!=len ) ) {
      77           0 :     errno = EINTR;
      78           0 :     close( fd );
      79           0 :     return -1;
      80           0 :   }
      81             : 
      82           0 :   if( FD_UNLIKELY( -1==close( fd ) ) ) return -1;
      83           0 :   return 0;
      84           0 : }
      85             : 
      86             : int
      87             : fd_file_util_mkdir_all( const char * _path,
      88             :                         uint         uid,
      89           0 :                         uint         gid ) {
      90           0 :   char path[ PATH_MAX+1UL ] = {0};
      91           0 :   strncpy( path, _path, PATH_MAX );
      92             : 
      93           0 :   char * p = path;
      94           0 :   if( FD_LIKELY( *p == '/' ) ) p++;
      95             : 
      96           0 :   while( FD_LIKELY( *p ) ) {
      97           0 :     if( FD_UNLIKELY( *p == '/' ) ) {
      98           0 :       *p = '\0';
      99             : 
     100           0 :       int error = mkdir( path, 0777 );
     101           0 :       if( FD_UNLIKELY( -1==error && errno!=EEXIST ) ) return -1;
     102           0 :       if( FD_LIKELY( !error ) ) {
     103             :         /* Only take ownership of directories that we actually created
     104             :            (to avoid, for example, chowning the root directory). */
     105           0 :         if( FD_UNLIKELY( -1==chown( path, uid, gid ) ) ) return -1;
     106           0 :         if( FD_UNLIKELY( -1==chmod( path, S_IRUSR | S_IWUSR | S_IXUSR ) ) ) return -1;
     107           0 :       }
     108             : 
     109           0 :       *p = '/';
     110           0 :     }
     111           0 :     p++;
     112           0 :   }
     113             : 
     114           0 :   int error = mkdir( path, 0777 );
     115           0 :   if( FD_UNLIKELY( error && errno!=EEXIST ) ) return -1;
     116           0 :   if( FD_LIKELY( !error ) ) {
     117           0 :     if( FD_UNLIKELY( chown( path, uid, gid ) ) ) return -1;
     118           0 :     if( FD_UNLIKELY( chmod( path, S_IRUSR | S_IWUSR | S_IXUSR ) ) ) return -1;
     119           0 :   }
     120             : 
     121           0 :   return 0;
     122           0 : }
     123             : 
     124             : int
     125             : fd_file_util_rmtree( char const * path,
     126           0 :                      int          remove_root ) {
     127           0 :   DIR * dir = opendir( path );
     128           0 :   if( FD_UNLIKELY( !dir ) ) {
     129           0 :     if( FD_LIKELY( errno==ENOENT ) ) return 0;
     130           0 :     return -1;
     131           0 :   }
     132             : 
     133           0 :   struct dirent * entry;
     134           0 :   errno = 0;
     135           0 :   while(( entry = readdir( dir ) )) {
     136           0 :     if( FD_LIKELY( !strcmp( entry->d_name, "." ) || !strcmp( entry->d_name, ".." ) ) ) continue;
     137             : 
     138           0 :     char path1[ PATH_MAX ];
     139           0 :     if( FD_UNLIKELY( !fd_cstr_printf_check( path1, PATH_MAX, NULL, "%s/%s", path, entry->d_name ) ) ) {
     140           0 :       errno = ERANGE;
     141           0 :       closedir( dir ); /* Ignore error code, fd is always closed */
     142           0 :       return -1;
     143           0 :     }
     144             : 
     145           0 :     struct stat st;
     146           0 :     if( FD_UNLIKELY( lstat( path1, &st ) ) ) {
     147           0 :       if( FD_LIKELY( errno==ENOENT ) ) continue;
     148           0 :       closedir( dir ); /* Ignore error code, fd is always closed */
     149           0 :       return -1;
     150           0 :     }
     151             : 
     152           0 :     if( FD_UNLIKELY( S_ISDIR( st.st_mode ) ) ) {
     153           0 :       fd_file_util_rmtree( path1, 1 );
     154           0 :     } else {
     155           0 :       if( FD_UNLIKELY( -1==unlink( path1 ) && errno!=ENOENT ) ) {
     156           0 :         closedir( dir ); /* Ignore error code, fd is always closed */
     157           0 :         return -1;
     158           0 :       }
     159           0 :     }
     160           0 :   }
     161             : 
     162           0 :   if( FD_UNLIKELY( -1==closedir( dir ) ) )            return -1;
     163           0 :   if( FD_UNLIKELY( errno && errno!=ENOENT ) )         return -1;
     164           0 :   if( FD_LIKELY( remove_root && -1==rmdir( path ) ) ) return -1;
     165             : 
     166           0 :   return 0;
     167           0 : }
     168             : 
     169             : int
     170           0 : fd_file_util_self_exe( char path[ static PATH_MAX ] ) {
     171           0 :   long count = readlink( "/proc/self/exe", path, PATH_MAX );
     172           0 :   if( FD_UNLIKELY( -1==count ) ) return -1;
     173           0 :   if( FD_UNLIKELY( count>=PATH_MAX ) ) {
     174           0 :     errno = ERANGE;
     175           0 :     return -1;
     176           0 :   }
     177             : 
     178           0 :   path[ count ] = '\0';
     179           0 :   return 0;
     180           0 : }

Generated by: LCOV version 1.14