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

FreeBSD Manual Pages

  
 
  

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
       directory 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 License, 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			  11/01/2025			       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.0>

home | help