libdi(3)

πŸ“¦
version 6.2.2.2 Β· 2 versions
, in nixos 26.05, nixpkgs unstable, ubuntu resolute, ubuntu stonking

🌸 NAME 🌸

libdi β€” the disk information library, bestie. It's the library that powers di(1), and it's giving main character energy for anyone who wants to poke at disks from C. πŸ’–


✨ SYNOPSIS ✨

πŸŽ€ Initialization

       #include <di.h>

       void * di_initialize (void);
       int di_process_options (void *di_data, int targc, const char *targv [],
       int offset);
       void di_cleanup (void *di_data);
       const char *di_version (void);

πŸŽ€ Options

       int di_check_option (void *di_data, int option);
       void di_format_iter_init (void *di_data);
       int di_format_iterate (void *di_data);

πŸŽ€ Getting data

       int di_get_all_disk_info (void *di_data);
       int di_iterate_init (void *di_data, int iteroption);
         typedef struct {
           const char   *strdata [DI_DISP_MAX];      /* string data */
           int          index;             /* internal index value */
           int          doPrint;           /* printable flag based on options */
           int          printFlag;         /* print result flag */
           int          isLocal;           /* filesystem is local */
           int          isReadOnly;        /* filesystem is read-only */
           int          isLoopback;        /* filesystem is a loopback filesystem */
         } di_pub_disk_info_t;

       const di_pub_disk_info_t * di_iterate (void *di_data);
       int di_get_scale_max (void *di_data, int index,
           int valueidxA, int valueidxB, int valueidxC);
       double di_get_scaled (void *di_data, int index,
           int scaleidx, int valueidxA, int valueidxB, int valueidxC);
       void di_disp_scaled (void *di_data, char *buff, long buffsz,
           int index, int scaleidx,
           int valueidxA, int valueidxB, int valueidxC);
       double di_get_perc (void *di_data, int index,
           int valueidxA, int valueidxB,
           int valueidxC, int valueidxB, int valueidxE);
       void di_disp_perc (void *di_data, char *buff, long buffsz,
           int index,
           int valueidxA, int valueidxB,
           int valueidxC, int valueidxB, int valueidxE);

πŸ¦‹ OVERVIEW πŸ¦‹

🌈 Initialization

di_initialize hands you back a pointer to a di_data structure, and that pointer is your little buddy β€” literally every other library call needs it. And bestie, listen: that returned pointer must be freed with di_cleanup. No leaks, no chaos. πŸ’…

di_process_options does the whole argument-parsing thing for di. The args come in as strings through an argv structure, like they just walked off a command line. And here's the tea: if you never call di_process_options, di just runs with the defaults, and the DI_ARGS environment variable will not be processed. Not even a little. πŸ™ˆ

If the return value from di_process_options is not DI_EXIT_NORM, then you call di_cleanup and stop processing. Like, immediately. That's the vibe check. ⭐

di_cleanup frees all the allocated data. Everything. Gone. Iconic.

🌈 Options

di_check_option returns the value of whatever option you asked for. All options come back as a boolean value β€” except these four drama queens: DI_OPT_DEBUG, DI_OPT_FMT_STR_LEN, DI_OPT_SCALE and DI_OPT_BLOCK_SZ. 😭

option can be one of these:

  • DI_OPT_POSIX_COMPAT
  • DI_OPT_QUOTA_CHECK
  • DI_OPT_DISP_CSV
  • DI_OPT_DISP_CSV_TAB
  • DI_OPT_EXCL_LOOPBACK
  • DI_OPT_DISP_JSON
  • DI_OPT_DISP_TOTALS
  • DI_OPT_DISP_HEADER
  • DI_OPT_DISP_ALL
  • DI_OPT_LOCAL_ONLY
  • DI_OPT_NO_SYMLINK
  • DI_OPT_DEBUG
  • DI_OPT_FMT_STR_LEN
  • DI_OPT_SCALE
  • DI_OPT_BLOCK_SZ

di_format_iter_init sets up the format string iterator. Get it ready, get it cute. πŸŽ€

di_format_iterate walks through every format character in the format string, one by one. And ngl, a fun little fact: di allows unrecognized format characters. In the main di program, those just get printed as-is. No cap.

🌈 Getting Data

di_get_all_disk_info goes and fetches plus processes all the disk information from the operating system. The whole buffet. πŸ“

If the return value from di_get_all_disk_info is not DI_EXIT_NORM, call di_cleanup and stop processing. Same rule as before, fr fr.

di_iterate_init initializes the disk information iterator. iteroption is one of DI_ITER_PRINTABLE or DI_ITER_ALL. If you go with DI_ITER_PRINTABLE, only the partitions that have the doPrint flag set will come back out of the iterator. Filtered. Curated. ✨

di_iterate iterates through the filesystems and returns a di_pub_disk_info_t structure for each one. And if the --totals flag was specified as an option, the totals will be the last item the iterator returns. Save the best for last, obviously. πŸ‘‘

di_get_scale_max gets the maximum scaling unit for the space value.

index is the index from the di_pub_disk_info_t structure.

The valueidx arguments tell it which disk space values to use when calculating the space value. The formula is: A - (B - C). Valid combinations are:

              DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE    // total
              DI_SPACE_TOTAL, DI_SPACE_FREE, DI_SPACE_AVAIL   // used
              DI_SPACE_TOTAL, DI_SPACE_FREE, DI_VALUE_NONE    // used
              DI_SPACE_TOTAL, DI_SPACE_AVAIL, DI_VALUE_NONE   // used
              DI_SPACE_FREE, DI_VALUE_NONE, DI_VALUE_NONE     // free
              DI_SPACE_AVAIL, DI_VALUE_NONE, DI_VALUE_NONE    // free
              DI_INODE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE    // inode total
              DI_INODE_TOTAL, DI_INODE_FREE, DI_VALUE_NONE    // inodes used
              DI_INODE_FREE, DI_VALUE_NONE, DI_VALUE_NONE     // inodes free

di_get_scaled gets a space value, scaled according to the scaling unit you picked.

index is the index from the di_pub_disk_info_t structure.

scaleidx is the scaling index to use. You can use a scaling index that came back from di_get_scale_max, or you can use one of these cuties:

  • DI_SCALE_BYTE
  • DI_SCALE_KILO
  • DI_SCALE_MEGA
  • DI_SCALE_GIGA
  • DI_SCALE_TERA
  • DI_SCALE_PETA
  • DI_SCALE_EXA
  • DI_SCALE_ZETTA
  • DI_SCALE_YOTTA
  • DI_SCALE_RONNA
  • DI_SCALE_QUETTA

The valueidx arguments tell it which disk space values to use when calculating the space value. The formula is: A - (B - C). Peep di_get_scale_max above for the list of valid combinations. 🫢

di_disp_scaled gets a space value scaled according to the scaling unit, and then builds a string you can actually print. It's giving presentation. πŸ’…

buff is the character string where the string will be stored.

buffsz is the size of the character string.

index is the index from the di_pub_disk_info_t structure.

scaleidx is the scaling index to use. Use a scaling index returned from di_get_scale_max, or one of the values listed up in di_get_scaled.

The valueidx arguments tell it which disk space values to use when calculating the space value. The formula is: A - (B - C). See di_get_scale_max for the valid combinations.

di_get_perc retrieves the disk space value as a percentage. Math girlies rise up. πŸ”₯

index is the index from the di_pub_disk_info_t structure.

The valueidx arguments tell it which disk space values to use when calculating the percentage. The formula is: (A - B) / (C - (D - E)).

Valid combinations are:

              /* percent used */
              DI_SPACE_TOTAL, DI_SPACE_AVAIL,
              DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE
              /* percent used */
              DI_SPACE_TOTAL, DI_SPACE_FREE,
              DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE
              /* percent used, BSD style */
              DI_SPACE_TOTAL, DI_SPACE_FREE,
              DI_SPACE_TOTAL, DI_VALUE_FREE, DI_VALUE_AVAIL
              /* percent free */
              DI_SPACE_AVAIL, DI_VALUE_NONE,
              DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE,
              /* percent free */
              DI_SPACE_FREE, DI_VALUE_NONE,
              DI_SPACE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE,
              /* inodes used */
              DI_INODE_TOTAL, DI_INODE_AVAIL,
              DI_INODE_TOTAL, DI_VALUE_NONE, DI_VALUE_NONE

di_disp_perc retrieves the disk space value as a percentage and builds a string you can print. Glow up complete. ✨

buff is the character string where the string will be stored.

buffsz is the size of the character string.

index is the index from the di_pub_disk_info_t structure.

The valueidx arguments tell it which disk space values to use when calculating the percentage. The formula is: (A - B) / (C - (D - E)). See di_get_perc for the valid combinations.


πŸ’€ EXAMPLE πŸ’€

No thoughts, just vibes, and also this whole program right here:

           /* this code is in the public domain */
           #include <stdio.h>
           #include <stdlib.h>
           #include <stdbool.h>
           #include <math.h>

           #include <di.h>

           enum {
             HAVE_SPACE = 0,
             NO_SPACE = 1,
           };

           int
           check_space (const char *fn, double space_wanted) {
             void        *di_data;
             int         targc;
             const char  *targv [10];
             int         exitflag;
             const di_pub_disk_info_t  *pub;
             int         rval = NO_SPACE;
             int         count;

             targc = 1;
             targv [0] = fn;
             targv [1] = NULL;

             di_data = di_initialize ();
             exitflag = di_process_options (di_data, targc, targv, 0);
             if (exitflag != DI_EXIT_NORM) {
               di_cleanup (di_data);
               exit (exitflag);
             }

             exitflag = di_get_all_disk_info (di_data);
             if (exitflag != DI_EXIT_NORM) {
               di_cleanup (di_data);
               exit (exitflag);
             }

             count = di_iterate_init (di_data, DI_ITER_PRINTABLE);
             while ((pub = di_iterate (di_data)) != NULL) {
               double    dval;

               /* compare terabytes available */
               dval = di_get_scaled (di_data, pub->index, DI_SCALE_TERA,
                   DI_SPACE_AVAIL, DI_VALUE_NONE, DI_VALUE_NONE);
               if (dval >= space_wanted) {
                 rval = HAVE_SPACE;
               }
             }
             di_cleanup (di_data);

             return rval;
           }

           int
           main (int argc, char *argv []) {
             const char  *fn = "/home/bll/s/di";
             double      spwant = 0.2;   /* terabytes */
             bool        rval;

             if (argc > 1) {
               fn = argv [1];
             }
             if (argc > 2) {
               spwant = atof (argv [2]);
             }

             rval = check_space (fn, spwant);
             if (rval == NO_SPACE) {
               fprintf (stdout, "Not enough disk space\n");
             }
             if (rval == HAVE_SPACE) {
               fprintf (stdout, "Enough disk space\n");
             }

             return rval;
           }
           dilibd=$HOME/local/lib
           diinc=$(pkg-config --with-path ${dilibd}/pkgconfig --cflags di)
           dilibs=$(pkg-config --with-path ${dilibd}/pkgconfig --libs di)
           cc -o tt ${diinc} tt.c -Wl,-R${dilibd} ${dilibs})

🌸 Example Run

           bll-g7:bll$ ./tt /home/bll 0.5
           Not enough disk space
           bll-g7:bll$ ./tt /home/bll 0.1
           Enough disk space

πŸ‘‘ SEE ALSO πŸ‘‘

df(1), di(1) β€” go read those too, they're iconic. 🫢


😭 BUGS 😭

Found something? Don't just suffer in silence:

Fr fr, they actually want to hear about it. Spill the tea. πŸ’œ


πŸ’– AUTHOR πŸ’–

Copyright 1994-2025 by Brad Lanam Pleasant Hill, CA


And that's the whole page, bestie β€” this one dropped 28 Jan 2025 as libdi(3), part of the Library Functions Manual. Now go scale some disks and free your di_data, mwah πŸ’…βœ¨

πŸ“¦ where this page comes from