LCOV - code coverage report
Current view: top level - cmdline - portable.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 2 2 100.0 %
Date: 2025-10-28 11:59:11 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2011 Andrea Mazzoleni
       3             :  *
       4             :  * This program is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 3 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #ifndef __PORTABLE_H
      19             : #define __PORTABLE_H
      20             : 
      21             : #if HAVE_CONFIG_H
      22             : #include "config.h" /* Use " to include first in the same directory of this file */
      23             : #endif
      24             : 
      25             : /***************************************************************************/
      26             : /* Config */
      27             : 
      28             : #ifdef __MINGW32__
      29             : /**
      30             :  * Enable the GNU printf functions instead of using the MSVCRT ones.
      31             :  *
      32             :  * Note that this is the default if _POSIX is also defined.
      33             :  * To disable it you have to set it to 0.
      34             :  */
      35             : #define __USE_MINGW_ANSI_STDIO 1
      36             : 
      37             : /**
      38             :  * Define the MSVCRT version targeting Windows Vista.
      39             :  */
      40             : #define __MSVCRT_VERSION__ 0x0600
      41             : 
      42             : /**
      43             :  * Include Windows Vista headers.
      44             :  *
      45             :  * Like for InitializeCriticalSection().
      46             :  */
      47             : #define _WIN32_WINNT 0x600
      48             : 
      49             : /**
      50             :  * Enable the rand_s() function.l
      51             :  */
      52             : #define _CRT_RAND_S
      53             : 
      54             : #include <windows.h>
      55             : #endif
      56             : 
      57             : /**
      58             :  * Specify the format attribute for printf.
      59             :  */
      60             : #ifdef __MINGW32__
      61             : #if defined(__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO == 1
      62             : #define attribute_printf gnu_printf /* GNU format */
      63             : #else
      64             : #define attribute_printf ms_printf /* MSVCRT format */
      65             : #endif
      66             : #else
      67             : #define attribute_printf printf /* GNU format is the default one */
      68             : #endif
      69             : 
      70             : /**
      71             :  * Compiler extension
      72             :  */
      73             : #ifndef __always_inline
      74             : #define __always_inline inline __attribute__((always_inline))
      75             : #endif
      76             : 
      77             : #ifndef __noreturn
      78             : #define __noreturn __attribute__((noreturn))
      79             : #endif
      80             : 
      81             : 
      82             : /**
      83             :  * Architecture for inline assembly.
      84             :  */
      85             : #if HAVE_ASSEMBLY
      86             : #if defined(__i386__)
      87             : #define CONFIG_X86 1
      88             : #define CONFIG_X86_32 1
      89             : #endif
      90             : 
      91             : #if defined(__x86_64__)
      92             : #define CONFIG_X86 1
      93             : #define CONFIG_X86_64 1
      94             : #endif
      95             : #endif
      96             : 
      97             : /**
      98             :  * Includes some platform specific headers.
      99             :  */
     100             : #if HAVE_SYS_PARAM_H
     101             : #include <sys/param.h>
     102             : #endif
     103             : 
     104             : #if HAVE_SYS_MOUNT_H
     105             : #include <sys/mount.h>
     106             : #endif
     107             : 
     108             : #if HAVE_SYS_VFS_H
     109             : #include <sys/vfs.h>
     110             : #endif
     111             : 
     112             : #if HAVE_SYS_STATFS_H
     113             : #include <sys/statfs.h>
     114             : #endif
     115             : 
     116             : #if HAVE_SYS_FILE_H
     117             : #include <sys/file.h>
     118             : #endif
     119             : 
     120             : #if HAVE_SYS_IOCTL_H
     121             : #include <sys/ioctl.h>
     122             : #endif
     123             : 
     124             : #if HAVE_LINUX_FS_H
     125             : #include <linux/fs.h>
     126             : #endif
     127             : 
     128             : #if HAVE_LINUX_FIEMAP_H
     129             : #include <linux/fiemap.h>
     130             : #endif
     131             : 
     132             : #if HAVE_BLKID_BLKID_H
     133             : #include <blkid/blkid.h>
     134             : #if HAVE_BLKID_DEVNO_TO_DEVNAME && HAVE_BLKID_GET_TAG_VALUE
     135             : #define HAVE_BLKID 1
     136             : #endif
     137             : #endif
     138             : 
     139             : /**
     140             :  * Includes some standard headers.
     141             :  */
     142             : #include <stdio.h>
     143             : #include <stdlib.h> /* On many systems (e.g., Darwin), `stdio.h' is a prerequisite. */
     144             : #include <stdarg.h>
     145             : #include <string.h>
     146             : #include <ctype.h>
     147             : #include <fcntl.h>
     148             : #include <assert.h>
     149             : #include <errno.h>
     150             : #include <signal.h>
     151             : #include <limits.h>
     152             : 
     153             : #if HAVE_STDINT_H
     154             : #include <stdint.h>
     155             : #endif
     156             : 
     157             : #if HAVE_INTTYPES_H
     158             : #include <inttypes.h>
     159             : #endif
     160             : 
     161             : #if HAVE_UNISTD_H
     162             : #include <unistd.h>
     163             : #endif
     164             : 
     165             : #if TIME_WITH_SYS_TIME
     166             : #include <sys/time.h>
     167             : #include <time.h>
     168             : #else
     169             : #if HAVE_SYS_TIME_H
     170             : #include <sys/time.h>
     171             : #else
     172             : #include <time.h>
     173             : #endif
     174             : #endif
     175             : 
     176             : #if HAVE_MACH_MACH_TIME_H
     177             : #include <mach/mach_time.h>
     178             : #endif
     179             : 
     180             : #if HAVE_DIRENT_H
     181             : #include <dirent.h>
     182             : #define NAMLEN(dirent) strlen((dirent)->d_name)
     183             : #else
     184             : #define dirent direct
     185             : #define NAMLEN(dirent) (dirent)->d_namlen
     186             : #if HAVE_SYS_NDIR_H
     187             : #include <sys/ndir.h>
     188             : #endif
     189             : #if HAVE_SYS_DIR_H
     190             : #include <sys/dir.h>
     191             : #endif
     192             : #if HAVE_NDIR_H
     193             : #include <ndir.h>
     194             : #endif
     195             : #endif
     196             : 
     197             : #if HAVE_SYS_TYPES_H
     198             : #include <sys/types.h>
     199             : #endif
     200             : 
     201             : #if HAVE_SYS_MKDEV
     202             : #include <sys/mkdev.h>
     203             : #endif
     204             : 
     205             : #if HAVE_SYS_SYSMACROS_H
     206             : #include <sys/sysmacros.h>
     207             : #endif
     208             : 
     209             : #if HAVE_SYS_STAT_H
     210             : #include <sys/stat.h>
     211             : #endif
     212             : 
     213             : #if HAVE_SYS_WAIT_H
     214             : #include <sys/wait.h>
     215             : #endif
     216             : #ifndef WEXITSTATUS
     217             : #define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
     218             : #endif
     219             : #ifndef WIFEXITED
     220             : #define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
     221             : #endif
     222             : 
     223             : #if HAVE_GETOPT_H
     224             : #include <getopt.h>
     225             : #endif
     226             : 
     227             : #if HAVE_FNMATCH_H
     228             : #include <fnmatch.h>
     229             : #else
     230             : #include "fnmatch.h"
     231             : #endif
     232             : 
     233             : #if HAVE_MATH_H
     234             : #include <math.h>
     235             : #endif
     236             : 
     237             : #if HAVE_EXECINFO_H
     238             : #include <execinfo.h>
     239             : #endif
     240             : 
     241             : #ifdef __APPLE__
     242             : #include <CoreFoundation/CoreFoundation.h>
     243             : #include <DiskArbitration/DiskArbitration.h>
     244             : #endif
     245             : 
     246             : /**
     247             :  * Enable thread use.
     248             :  */
     249             : #ifdef _WIN32
     250             : #define HAVE_THREAD 1
     251             : typedef void* windows_thread_t;
     252             : typedef CRITICAL_SECTION windows_mutex_t;
     253             : typedef CONDITION_VARIABLE windows_cond_t;
     254             : typedef void* windows_key_t;
     255             : /* remap to pthread */
     256             : #define thread_id_t windows_thread_t
     257             : #define thread_mutex_t windows_mutex_t
     258             : #define thread_cond_t windows_cond_t
     259             : #define pthread_mutex_init windows_mutex_init
     260             : #define pthread_mutex_destroy windows_mutex_destroy
     261             : #define pthread_mutex_lock windows_mutex_lock
     262             : #define pthread_mutex_unlock windows_mutex_unlock
     263             : #define pthread_cond_init windows_cond_init
     264             : #define pthread_cond_destroy windows_cond_destroy
     265             : #define pthread_cond_signal windows_cond_signal
     266             : #define pthread_cond_broadcast windows_cond_broadcast
     267             : #define pthread_cond_wait windows_cond_wait
     268             : #define pthread_create windows_create
     269             : #define pthread_join windows_join
     270             : #else
     271             : #if HAVE_PTHREAD_H
     272             : #include <pthread.h>
     273             : #endif
     274             : #if HAVE_PTHREAD_CREATE
     275             : #define HAVE_THREAD 1
     276             : typedef pthread_t thread_id_t;
     277             : typedef pthread_mutex_t thread_mutex_t;
     278             : typedef pthread_cond_t thread_cond_t;
     279             : #endif
     280             : #endif
     281             : 
     282             : /**
     283             :  * Disable case check in Windows.
     284             :  */
     285             : #ifdef _WIN32
     286             : #define FNM_CASEINSENSITIVE_FOR_WIN FNM_CASEFOLD
     287             : #else
     288             : #define FNM_CASEINSENSITIVE_FOR_WIN 0
     289             : #endif
     290             : 
     291             : #if HAVE_IO_H
     292             : #include <io.h>
     293             : #endif
     294             : 
     295             : #if HAVE_GETOPT_LONG
     296             : #define SWITCH_GETOPT_LONG(a, b) a
     297             : #else
     298             : #define SWITCH_GETOPT_LONG(a, b) b
     299             : #endif
     300             : 
     301             : /**
     302             :  * Enables lock file support.
     303             :  */
     304             : #if HAVE_FLOCK && HAVE_FTRUNCATE
     305             : #define HAVE_LOCKFILE 1
     306             : #endif
     307             : 
     308             : /**
     309             :  * Basic block position type.
     310             :  * With 32 bits and 128k blocks you can address 256 TB.
     311             :  */
     312             : typedef uint32_t block_off_t;
     313             : 
     314             : /**
     315             :  * Basic data position type.
     316             :  * It's signed as file size and offset are usually signed.
     317             :  */
     318             : typedef int64_t data_off_t;
     319             : 
     320             : /**
     321             :  * Includes specific support for Windows or Linux.
     322             :  */
     323             : #ifdef __MINGW32__
     324             : #include "mingw.h"
     325             : #else
     326             : #include "unix.h"
     327             : #endif
     328             : 
     329             : /**
     330             :  * Include list support to have tommy_node.
     331             :  */
     332             : #include "tommyds/tommylist.h"
     333             : 
     334             : /**
     335             :  * Another name for link() to avoid confusion with local variables called "link".
     336             :  */
     337          12 : static inline int hardlink(const char* a, const char* b)
     338             : {
     339          12 :         return link(a, b);
     340             : }
     341             : 
     342             : /**
     343             :  * Get the device UUID.
     344             :  * Return 0 on success.
     345             :  */
     346             : int devuuid(uint64_t device, const char* path, char* uuid, size_t size);
     347             : 
     348             : /**
     349             :  * Physical offset not yet read.
     350             :  */
     351             : #define FILEPHY_UNREAD_OFFSET 0
     352             : 
     353             : /**
     354             :  * Special value returned when the file-system doesn't report any offset for unknown reason.
     355             :  */
     356             : #define FILEPHY_UNREPORTED_OFFSET 1
     357             : 
     358             : /**
     359             :  * Special value returned when the file doesn't have a real offset.
     360             :  * For example, because it's stored in the NTFS MFT.
     361             :  */
     362             : #define FILEPHY_WITHOUT_OFFSET 2
     363             : 
     364             : /**
     365             :  * Value indicating real offsets. All offsets greater or equal at this one are real.
     366             :  */
     367             : #define FILEPHY_REAL_OFFSET 3
     368             : 
     369             : /**
     370             :  * Get the physical address of the specified file.
     371             :  * This is expected to be just a hint and not necessarily correct or unique.
     372             :  * Return 0 on success.
     373             :  */
     374             : int filephy(const char* path, uint64_t size, uint64_t* physical);
     375             : 
     376             : /**
     377             :  * Check if the underline file-system support persistent inodes.
     378             :  * Return -1 on error, 0 on success.
     379             :  */
     380             : int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space);
     381             : 
     382             : /**
     383             :  * Get the tick counter value.
     384             :  *
     385             :  * Note that the frequency is unspecified, because the time measure
     386             :  * is meant to be used to compare the ratio between usage times.
     387             :  */
     388             : uint64_t tick(void);
     389             : 
     390             : /**
     391             :  * Get the tick counter value in millisecond.
     392             :  */
     393             : uint64_t tick_ms(void);
     394             : 
     395             : /**
     396             :  * Initializes the system.
     397             :  */
     398             : void os_init(int opt);
     399             : 
     400             : /**
     401             :  * Deinitialize the system.
     402             :  */
     403             : void os_done(void);
     404             : 
     405             : /**
     406             :  * Abort the process with a stacktrace.
     407             :  */
     408             : void os_abort(void) __noreturn;
     409             : 
     410             : /**
     411             :  * Clear the screen.
     412             :  */
     413             : void os_clear(void);
     414             : 
     415             : /**
     416             :  * Log file.
     417             :  *
     418             :  * This stream if fully buffered.
     419             :  *
     420             :  * If no log file is selected, it's 0.
     421             :  */
     422             : extern FILE* stdlog;
     423             : 
     424             : /**
     425             :  * Exit codes for testing.
     426             :  */
     427             : extern int exit_success;
     428             : extern int exit_failure;
     429             : extern int exit_sync_needed;
     430             : #undef EXIT_SUCCESS
     431             : #undef EXIT_FAILURE
     432             : #define EXIT_SUCCESS exit_success
     433             : #define EXIT_FAILURE exit_failure
     434             : #define EXIT_SYNC_NEEDED exit_sync_needed
     435             : 
     436             : /**
     437             :  * Fill memory with pseudo-random values.
     438             :  */
     439             : int randomize(void* ptr, size_t size);
     440             : 
     441             : /**
     442             :  * Standard SMART attributes.
     443             :  */
     444             : #define SMART_START_STOP_COUNT 4
     445             : #define SMART_REALLOCATED_SECTOR_COUNT 5
     446             : #define SMART_POWER_ON_HOURS 9
     447             : #define SMART_AIRFLOW_TEMPERATURE_CELSIUS 190
     448             : #define SMART_TEMPERATURE_CELSIUS 194
     449             : 
     450             : /**
     451             :  * Additional SMART attributes.
     452             :  */
     453             : #define SMART_ERROR 256 /**< ATA Error count. */
     454             : #define SMART_SIZE 257 /**< Size in bytes. */
     455             : #define SMART_ROTATION_RATE 258 /**< Rotation speed. 0 for SSD. */
     456             : #define SMART_FLAGS 259 /**< Flags returned by smartctl. */
     457             : 
     458             : /**
     459             :  * SMART attributes count.
     460             :  */
     461             : #define SMART_COUNT 260
     462             : 
     463             : #define SMART_IGNORE_MAX 4 /**< Max number of ignored smart attributes */
     464             : 
     465             : /**
     466             :  * Flags returned by smartctl.
     467             :  */
     468             : #define SMARTCTL_FLAG_UNSUPPORTED (1 << 0) /**< Device not recognized, requiring the -d option. */
     469             : #define SMARTCTL_FLAG_OPEN (1 << 1) /**< Device open or identification failed. */
     470             : #define SMARTCTL_FLAG_COMMAND (1 << 2) /**< Some SMART or ATA commands failed. This is a common error, also happening with full info gathering. */
     471             : #define SMARTCTL_FLAG_FAIL (1 << 3) /**< SMART status check returned "DISK FAILING". */
     472             : #define SMARTCTL_FLAG_PREFAIL (1 << 4) /**< We found prefail Attributes <= threshold. */
     473             : #define SMARTCTL_FLAG_PREFAIL_LOGGED (1 << 5) /**< SMART status check returned "DISK OK" but we found that some (usage or prefail) Attributes have been <= threshold at some time in the past. */
     474             : #define SMARTCTL_FLAG_ERROR (1 << 6) /**< The device error log contains records of errors. */
     475             : #define SMARTCTL_FLAG_ERROR_LOGGED (1 << 7) /**< The device self-test log contains records of errors. */
     476             : 
     477             : /**
     478             :  * SMART max attribute length.
     479             :  */
     480             : #define SMART_MAX 64
     481             : 
     482             : /**
     483             :  * Value for unassigned SMART attribute.
     484             :  */
     485             : #define SMART_UNASSIGNED 0xFFFFFFFFFFFFFFFFULL
     486             : 
     487             : 
     488             : /**
     489             :  * Power mode
     490             :  */
     491             : #define POWER_STANDBY 0
     492             : #define POWER_ACTIVE 1
     493             : #define POWER_UNKNOWN -1
     494             : 
     495             : /**
     496             :  * Device info entry.
     497             :  */
     498             : struct devinfo_struct {
     499             :         uint64_t device; /**< Device ID. */
     500             :         char name[PATH_MAX]; /**< Name of the disk. */
     501             :         char mount[PATH_MAX]; /**< Mount point or other contained directory. */
     502             :         char smartctl[PATH_MAX]; /**< Options for smartctl. */
     503             :         int smartignore[SMART_IGNORE_MAX]; /**< Attribues to ignore */
     504             :         char file[PATH_MAX]; /**< File device. */
     505             : #ifdef _WIN32
     506             :         char wfile[PATH_MAX]; /**< File device in Windows format. Like \\.\PhysicalDriveX, or \\?\Volume{X}. */
     507             : #endif
     508             :         struct devinfo_struct* parent; /**< Pointer at the parent if any. */
     509             :         uint64_t smart[SMART_COUNT]; /**< SMART raw attributes. */
     510             :         char smart_serial[SMART_MAX]; /**< SMART serial number. */
     511             :         char smart_vendor[SMART_MAX]; /**< SMART vendor. */
     512             :         char smart_model[SMART_MAX]; /**< SMART model. */
     513             :         int power; /**< POWER mode. */
     514             : #if HAVE_THREAD
     515             :         thread_id_t thread;
     516             : #endif
     517             :         tommy_node node;
     518             : };
     519             : typedef struct devinfo_struct devinfo_t;
     520             : 
     521             : #define DEVICE_LIST 0
     522             : #define DEVICE_DOWN 1
     523             : #define DEVICE_UP 2
     524             : #define DEVICE_SMART 3
     525             : #define DEVICE_PROBE 4
     526             : #define DEVICE_DOWNIFUP 5
     527             : 
     528             : /**
     529             :  * Query all the "high" level devices with the specified operation,
     530             :  * and produces a list of "low" level devices to operate on.
     531             :  *
     532             :  * The passed "low" device list must be already initialized.
     533             :  */
     534             : int devquery(tommy_list* high, tommy_list* low, int operation, int others);
     535             : 
     536             : /**
     537             :  * Fill with fake data the device list.
     538             :  */
     539             : int devtest(tommy_list* high, tommy_list* low, int operation);
     540             : 
     541             : /**
     542             :  * Get the ambient temperature in degree
     543             :  *
     544             :  * Return 0 if not available.
     545             :  */
     546             : int ambient_temperature(void);
     547             : 
     548             : /**
     549             :  * Global variable to identify if Ctrl+C is pressed.
     550             :  */
     551             : extern volatile int global_interrupt;
     552             : 
     553             : #endif
     554             : 

Generated by: LCOV version 1.0