Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
ZDIR(3) 			   CZMQ Manual				 ZDIR(3)

NAME
     zdir - Class for work with file-system directories

SYNOPSIS
     //  This is a stable class, and may not change except for emergencies. It
     //  is provided in stable builds.
     //  Create a new directory item that loads in the full tree of the specified
     //  path, optionally located under some parent path. If parent is "-", then
     //  loads only the top-level directory, and does not use parent as a path.
     CZMQ_EXPORT zdir_t *
	 zdir_new (const char *path, const char *parent);

     //  Destroy a directory tree and all children it contains.
     CZMQ_EXPORT void
	 zdir_destroy (zdir_t **self_p);

     //  Return directory path
     CZMQ_EXPORT const char *
	 zdir_path (zdir_t *self);

     //  Return last modification time for directory.
     CZMQ_EXPORT time_t
	 zdir_modified (zdir_t *self);

     //  Return total hierarchy size, in bytes of data contained in all files
     //  in the directory tree.
     CZMQ_EXPORT off_t
	 zdir_cursize (zdir_t *self);

     //  Return directory count
     CZMQ_EXPORT size_t
	 zdir_count (zdir_t *self);

     //  Returns a sorted list of zfile objects; Each entry in the list is a pointer
     //  to a zfile_t item already allocated in the zdir tree. Do not destroy the
     //  original zdir tree until you are done with this list.
     //  Caller owns return value and must destroy it when done.
     CZMQ_EXPORT zlist_t *
	 zdir_list (zdir_t *self);

     //  Remove directory, optionally including all files that it contains, at
     //  all levels. If force is false, will only remove the directory if empty.
     //  If force is true, will remove all files and all subdirectories.
     CZMQ_EXPORT void
	 zdir_remove (zdir_t *self, bool force);

     //  Calculate differences between two versions of a directory tree.
     //  Returns a list of zdir_patch_t patches. Either older or newer may
     //  be null, indicating the directory is empty/absent. If alias is set,
     //  generates virtual filename (minus path, plus alias).
     //  Caller owns return value and must destroy it when done.
     CZMQ_EXPORT zlist_t *
	 zdir_diff (zdir_t *older, zdir_t *newer, const char *alias);

     //  Return full contents of directory as a zdir_patch list.
     //  Caller owns return value and must destroy it when done.
     CZMQ_EXPORT zlist_t *
	 zdir_resync (zdir_t *self, const char *alias);

     //  Load directory cache; returns a hash table containing the SHA-1 digests
     //  of every file in the tree. The cache is saved between runs in .cache.
     //  Caller owns return value and must destroy it when done.
     CZMQ_EXPORT zhash_t *
	 zdir_cache (zdir_t *self);

     //  Print contents of directory to open stream
     CZMQ_EXPORT void
	 zdir_fprint (zdir_t *self, FILE *file, int indent);

     //  Print contents of directory to stdout
     CZMQ_EXPORT void
	 zdir_print (zdir_t *self, int indent);

     //  Create a new zdir_watch actor instance:
     //
     //      zactor_t *watch = zactor_new (zdir_watch, NULL);
     //
     //  Destroy zdir_watch instance:
     //
     //      zactor_destroy (&watch);
     //
     //  Enable verbose logging of commands and activity:
     //
     //      zstr_send (watch, "VERBOSE");
     //
     //  Subscribe to changes to a directory path:
     //
     //      zsock_send (watch, "ss", "SUBSCRIBE", "directory_path");
     //
     //  Unsubscribe from changes to a directory path:
     //
     //      zsock_send (watch, "ss", "UNSUBSCRIBE", "directory_path");
     //
     //  Receive directory changes:
     //      zsock_recv (watch, "sp", &path, &patches);
     //
     //      // Delete the received data.
     //      free (path);
     //      zlist_destroy (&patches);
     CZMQ_EXPORT void
	 zdir_watch (zsock_t *pipe, void *unused);

     //  Self test of this class.
     CZMQ_EXPORT void
	 zdir_test (bool verbose);

     Please add '@interface' section in './../src/zdir.c'.

DESCRIPTION
     The zdir class gives access to the file system index. It will load a direc-
     tory  tree  (a  directory plus all child directories) into a zdir structure
     and then let  you	navigate  that	structure.  It	exists	mainly	to  wrap
     non-portable OS functions to do this.

     Please add @discuss section in ./../src/zdir.c.

EXAMPLE
     From zdir_test method.

	 const char *SELFTEST_DIR_RW = "src/selftest-rw";

	 const char *testbasedir  = "zdir-test-dir";
	 const char *testfile1 = "initial_file";
	 const char *testfile2 = "test_abc";
	 char *basedirpath = NULL;   // subdir in a test, under SELFTEST_DIR_RW
	 char *filepath1 = NULL;      // pathname to testfile in a test, in dirpath
	 char *filepath2 = NULL;      // pathname to testfile in a test, in dirpath

	 basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
	 assert (basedirpath);
	 filepath1 = zsys_sprintf ("%s/%s", basedirpath, testfile1);
	 assert (filepath1);
	 filepath2 = zsys_sprintf ("%s/%s", basedirpath, testfile2);
	 assert (filepath2);

	 /*
	 char *relfilepath2 = NULL;	 // pathname to testfile in a test, in dirpath
	 relfilepath2 = zsys_sprintf ("%s/%s", testbasedir, testfile2);
	 assert (relfilepath2);
	 */

	 // Make sure old aborted tests do not hinder us
	 zdir_t *dir = zdir_new (basedirpath, NULL);
	 if (dir) {
	     zdir_remove (dir, true);
	     zdir_destroy (&dir);
	 }
	 zsys_file_delete (filepath1);
	 zsys_file_delete (filepath2);
	 zsys_dir_delete  (basedirpath);

	 dir = zdir_new ("does-not-exist", NULL);
	 if (dir) {
	     zdir_remove (dir, true);
	     zdir_destroy (&dir);
	 }

	 // need to create a file in the test directory we're watching
	 // in order to ensure the directory exists
	 zfile_t *initfile = zfile_new (basedirpath, testfile1);
	 assert (initfile);
	 zfile_output (initfile);
	 fprintf (zfile_handle (initfile), "initial file\n");
	 zfile_close (initfile);
	 zfile_destroy (&initfile);

	 zdir_t *older = zdir_new (basedirpath, NULL);
	 assert (older);
	 if (verbose) {
	     printf ("\n");
	     zdir_dump (older, 0);
	 }
	 zdir_t *newer = zdir_new (SELFTEST_DIR_RW, NULL);
	 assert (newer);
	 zlist_t *patches = zdir_diff (older, newer, "/");
	 assert (patches);
	 while (zlist_size (patches)) {
	     zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches);
	     zdir_patch_destroy (&patch);
	 }
	 zlist_destroy (&patches);
	 zdir_destroy (&older);
	 zdir_destroy (&newer);

	 zdir_t *nosuch = zdir_new ("does-not-exist", NULL);
	 assert (nosuch == NULL);

	 // zdir_watch test:
	 zactor_t *watch = zactor_new (zdir_watch, NULL);
	 assert (watch);

	 int synced;
	 if (verbose) {
	     zsock_send (watch, "s", "VERBOSE");
	     synced = zsock_wait(watch);
	     assert ( synced == 0);
	 }

	 // wait for initial file to become 'stable'
	 #ifdef CZMQ_BUILD_DRAFT_API
	 zclock_sleep ((int)zsys_file_stable_age_msec() + 50);
	 #else
	 zclock_sleep (5050);
	 #endif

	 zsock_send (watch, "si", "TIMEOUT", 100);
	 synced = zsock_wait(watch);
	 assert (synced == 0);

	 zsock_send (watch, "ss", "SUBSCRIBE", basedirpath);
	 synced = zsock_wait(watch);
	 assert(synced == 0);

	 zsock_send (watch, "ss", "UNSUBSCRIBE", basedirpath);
	 synced = zsock_wait(watch);
	 assert(synced == 0);

	 zsock_send (watch, "ss", "SUBSCRIBE", basedirpath);
	 synced = zsock_wait(watch);
	 assert(synced == 0);

	 zfile_t *newfile = zfile_new (basedirpath, testfile2);
	 zfile_output (newfile);
	 fprintf (zfile_handle (newfile), "test file\n");
	 zfile_close (newfile);

	 zpoller_t *watch_poll = zpoller_new (watch, NULL);

	 // poll for a certain timeout before giving up and failing the test
	 void* polled = NULL;
	 #ifdef CZMQ_BUILD_DRAFT_API
	 polled = zpoller_wait(watch_poll, (int)zsys_file_stable_age_msec() + 150);
	 #else
	 polled = zpoller_wait(watch_poll, 5150);
	 #endif
	 assert (polled == watch);

	 // wait for notification of the file being added
	 char *path;
	 int rc = zsock_recv (watch, "sp", &path, &patches);
	 assert (rc == 0);

	 assert (streq (path, basedirpath));
	 freen (path);

	 if (verbose)
	     zsys_debug("zdir_test() : added : zlist_size (patches)=%d",
		 zlist_size (patches) );
	 assert (zlist_size (patches) == 1);

	 zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches);
	 if (verbose)
	     zsys_debug("zdir_test() : added : zdir_patch_path (patch)='%s'",
		 zdir_patch_path (patch) );
	 assert (streq (zdir_patch_path (patch), basedirpath));

	 zfile_t *patch_file = zdir_patch_file (patch);
	 if (verbose)
	     zsys_debug("zdir_test() : added : zfile_filename (patch_file, \"\")='%s'",
		 zfile_filename (patch_file, "") );
	 assert (streq (zfile_filename (patch_file, ""), filepath2));

	 zdir_patch_destroy (&patch);
	 zlist_destroy (&patches);

	 // remove the file
	 zfile_remove (newfile);
	 zfile_destroy (&newfile);

	 // poll for a certain timeout before giving up and failing the test.
	 #ifdef CZMQ_BUILD_DRAFT_API
	 polled = zpoller_wait(watch_poll, (int)zsys_file_stable_age_msec() + 150);
	 #else
	 polled = zpoller_wait(watch_poll, 5150);
	 #endif
	 assert (polled == watch);

	 // wait for notification of the file being removed
	 rc = zsock_recv (watch, "sp", &path, &patches);
	 assert (rc == 0);

	 assert (streq (path, basedirpath));
	 freen (path);

	 if (verbose)
	     zsys_debug("zdir_test() : removed : zlist_size (patches)=%d",
		 zlist_size (patches) );
	 assert (zlist_size (patches) == 1);

	 patch = (zdir_patch_t *) zlist_pop (patches);
	 if (verbose)
	     zsys_debug("zdir_test() : removed : zdir_patch_path (patch)='%s'",
		 zdir_patch_path (patch) );
	 assert (streq (zdir_patch_path (patch), basedirpath));

	 patch_file = zdir_patch_file (patch);
	 if (verbose)
	     zsys_debug("zdir_test() : removed : zfile_filename (patch_file, \"\")='%s'",
		 zfile_filename (patch_file, "") );
	 assert (streq (zfile_filename (patch_file, ""), filepath2));

	 zdir_patch_destroy (&patch);
	 zlist_destroy (&patches);

	 zpoller_destroy (&watch_poll);
	 zactor_destroy (&watch);

	 // clean up by removing the test directory.
	 dir = zdir_new (basedirpath, NULL);
	 assert (dir);
	 zdir_remove (dir, true);
	 zdir_destroy (&dir);

	 zstr_free (&basedirpath);
	 zstr_free (&filepath1);
	 zstr_free (&filepath2);

	 #if defined (__WINDOWS__)
	 zsys_shutdown();
	 #endif

AUTHORS
     The czmq manual was written by the authors in the AUTHORS file.

RESOURCES
     Main web site:

     Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>

COPYRIGHT
     Copyright	(c)  the Contributors as noted in the AUTHORS file. This file is
     part of CZMQ, the high-level C  binding  for  0MQ:  http://czmq.zeromq.org.
     This  Source  Code  Form  is subject to the terms of the Mozilla Public Li-
     cense, v. 2.0. If a copy of the MPL was not distributed with this file, You
     can obtain one at http://mozilla.org/MPL/2.0/. LICENSE  included  with  the
     czmq distribution.

NOTES
      1. zeromq-dev@lists.zeromq.org
	 mailto:zeromq-dev@lists.zeromq.org

CZMQ 4.2.1			   08/27/2026				 ZDIR(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=zdir&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help