Exemple #1
0
int
zconfig_save (zconfig_t *self, const char *filename)
{
    assert (self);

    int rc = 0;
    if (streq (filename, "-"))
        //  "-" means write to stdout
        rc = zconfig_execute (self, s_config_save, stdout);
    else {
        FILE *file;
        file = fopen (filename, "w");
        if (file) {
            rc = zconfig_execute (self, s_config_save, file);
            fflush (file);
            fclose (file);

            //  If we saved back to original file, restat it so that
            //  the file does not appear as "changed"
            if (self->file && streq (filename, zconfig_filename (self)))
                zfile_restat (self->file);
        }
        else
            rc = -1;          //  File not writeable
    }
    return rc;
}
Exemple #2
0
zfile_t *
zfile_new (const char *path, const char *name)
{
    zfile_t *self = (zfile_t *) zmalloc (sizeof (zfile_t));

    //  Format full path to file
    if (path) {
        self->fullname = (char *) zmalloc (strlen (path) + strlen (name) + 2);
        sprintf (self->fullname, "%s/%s", path, name);
    }
    else
        self->fullname = strdup (name);

    //  Resolve symbolic link if possible
    if (strlen (self->fullname) > 3
    &&  streq (self->fullname + strlen (self->fullname) - 3, ".ln")) {
        FILE *handle = fopen (self->fullname, "r");
        if (handle) {
            char buffer [256];
            if (fgets (buffer, 256, handle)) {
                //  We have the contents of the symbolic link
                if (buffer [strlen (buffer) - 1] == '\n')
                    buffer [strlen (buffer) - 1] = 0;
                self->link = strdup (buffer);
                //  Chop ".ln" off name for external use
                self->fullname [strlen (self->fullname) - 3] = 0;
            }
            fclose (handle);
        }
    }
    zfile_restat (self);
    return self;
}
Exemple #3
0
void
zfile_close (zfile_t *self)
{
    assert (self);
    if (self->handle) {
        fclose (self->handle);
        zfile_restat (self);
    }
    self->handle = 0;
}
Exemple #4
0
zfile_t *
zfile_tmp (void)
{
    zfile_t *self = NULL;

#if defined (__WINDOWS__)
    // adapted from MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363875(v=vs.85).aspx
    DWORD dwRetVal = 0;
    UINT uRetVal   = 0;
    TCHAR lpTempPathBuffer[MAX_PATH];
    TCHAR szTempFileName[MAX_PATH];

    //  Gets the temp path env string (no guarantee it's a valid path).
    dwRetVal = GetTempPath(MAX_PATH,          // length of the buffer
                           lpTempPathBuffer); // buffer for path
    if (dwRetVal > MAX_PATH || (dwRetVal == 0))
        return NULL;

    uRetVal = GetTempFileName(lpTempPathBuffer,   // directory for tmp files
                              TEXT("CZMQ_ZFILE"), // temp file name prefix
                              0,                  // create unique name
                              szTempFileName);    // buffer for name
    if (uRetVal == 0)
        return NULL;

    self = (zfile_t *) zmalloc (sizeof (zfile_t));
    assert (self);
    self->fullname = strdup ((char*)szTempFileName);
    self->handle = fopen (self->fullname, "w");
#else
    char buffer [PATH_MAX];
    strcpy (buffer, "/tmp/czmq_zfile.XXXXXX");
    int fd = mkstemp (buffer);
    if (fd == -1)
        return NULL;

    self = (zfile_t *) zmalloc (sizeof (zfile_t));
    assert (self);
    self->fd = fd;
    self->close_fd = true;
    self->fullname = strdup (buffer);
    self->handle = fdopen (self->fd, "w");
#endif

    if (!self->handle) {
        if (self->close_fd)
            close (self->fd);
        zstr_free (&self->fullname);
        free (self);
        return NULL;
    }
    self->remove_on_destroy = true;
    zfile_restat (self);
    return self;
}
Exemple #5
0
void
zfile_close (zfile_t *self)
{
    assert (self);
    if (self->handle) {
        fclose (self->handle);
        zfile_restat (self);
        self->handle = 0;
        self->eof = false;
    }
}
Exemple #6
0
static bool config_file_has_changed()
{
    bool changed = false;
    if (config_file_exists) {
        zfile_restat(config_file);
        if (config_file_last_modified != zfile_modified(config_file)) {
            const char *new_digest = zfile_digest(config_file);
            // printf("[D] old digest: %s\n[D] new digest: %s\n", config_file_digest, new_digest);
            changed = strcmp(config_file_digest, new_digest) != 0;
        }
    }
    return changed;
}
JNIEXPORT void JNICALL
Java_org_zeromq_czmq_Zfile__1_1restat (JNIEnv *env, jclass c, jlong self)
{
    zfile_restat ((zfile_t *) (intptr_t) self);
}
Exemple #8
0
void
zfile_test (bool verbose)
{
    printf (" * zfile: ");

    //  @selftest
    zfile_t *file = zfile_new (NULL, "bilbo");
    assert (streq (zfile_filename (file, "."), "bilbo"));
    assert (zfile_is_readable (file) == false);
    zfile_destroy (&file);

    //  Create a test file in some random subdirectory
    file = zfile_new ("./this/is/a/test", "bilbo");
    int rc = zfile_output (file);
    assert (rc == 0);
    zchunk_t *chunk = zchunk_new (NULL, 100);
    zchunk_fill (chunk, 0, 100);
    
    //  Write 100 bytes at position 1,000,000 in the file
    rc = zfile_write (file, chunk, 1000000);
    assert (rc == 0);
    zchunk_destroy (&chunk);
    zfile_close (file);
    assert (zfile_is_readable (file));
    assert (zfile_cursize (file) == 1000100);
    assert (!zfile_is_stable (file));
    
    //  Now append one byte to file from outside
    int handle = open ("./this/is/a/test/bilbo", O_WRONLY | O_TRUNC | O_BINARY, 0);
    assert (handle >= 0);
    rc = write (handle, "Hello, World\n", 13);
    assert (rc == 13);
    close (handle);
    assert (zfile_has_changed (file));
    zclock_sleep (1001);
    assert (zfile_has_changed (file));
    
    assert (!zfile_is_stable (file));
    zfile_restat (file);
    assert (zfile_is_stable (file));
    assert (streq (zfile_digest (file), "4AB299C8AD6ED14F31923DD94F8B5F5CB89DFB54"));
    
    //  Check we can read from file
    rc = zfile_input (file);
    assert (rc == 0);
    chunk = zfile_read (file, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_close (file);

    //  Try some fun with symbolic links
    zfile_t *link = zfile_new ("./this/is/a/test", "bilbo.ln");
    rc = zfile_output (link);
    assert (rc == 0);
    fprintf (zfile_handle (link), "./this/is/a/test/bilbo\n");
    zfile_destroy (&link);

    link = zfile_new ("./this/is/a/test", "bilbo.ln");
    rc = zfile_input (link);
    assert (rc == 0);
    chunk = zfile_read (link, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_destroy (&link);

    //  Remove file and directory
    zdir_t *dir = zdir_new ("./this", NULL);
    assert (zdir_cursize (dir) == 26);
    zdir_remove (dir, true);
    assert (zdir_cursize (dir) == 0);
    zdir_destroy (&dir);

    //  Check we can no longer read from file
    assert (zfile_is_readable (file));
    zfile_restat (file);
    assert (!zfile_is_readable (file));
    rc = zfile_input (file);
    assert (rc == -1);
    zfile_destroy (&file);
    //  @end

    printf ("OK\n");
}
Exemple #9
0
///
//  Refresh file properties from disk; this is not done automatically   
//  on access methods, otherwise it is not possible to compare directory
//  snapshots.                                                          
void QZfile::restat ()
{
    zfile_restat (self);
    
}
Exemple #10
0
void
zfile_test (bool verbose)
{
    printf (" * zfile: ");

    //  @selftest

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

    const char *testbasedir  = "this";
    const char *testsubdir  = "is/a/test";
    const char *testfile = "bilbo";
    const char *testlink = "bilbo.ln";
    char *basedirpath = NULL;   // subdir in a test, under SELFTEST_DIR_RW
    char *dirpath = NULL;       // subdir in a test, under basedirpath
    char *filepath = NULL;      // pathname to testfile in a test, in dirpath
    char *linkpath = NULL;      // pathname to testlink in a test, in dirpath

    basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
    assert (basedirpath);
    dirpath = zsys_sprintf ("%s/%s", basedirpath, testsubdir);
    assert (dirpath);
    filepath = zsys_sprintf ("%s/%s", dirpath, testfile);
    assert (filepath);
    linkpath = zsys_sprintf ("%s/%s", dirpath, testlink);
    assert (linkpath);

    // This subtest is specifically for NULL as current directory, so
    // no SELFTEST_DIR_RW here; testfile should have no slashes inside.
    // Normally tests clean up in zfile_destroy(), but if a selftest run
    // dies e.g. on assert(), workspace remains dirty. Better clean it up.
    if (zfile_exists (testfile) ) {
        if (verbose)
            zsys_debug ("zfile_test() has to remove ./%s that should not have been here", testfile);
        zfile_delete (testfile);
    }
    zfile_t *file = zfile_new (NULL, testfile);
    assert (file);
    assert (streq (zfile_filename (file, "."), testfile));
    assert (zfile_is_readable (file) == false);
    zfile_destroy (&file);

    //  Create a test file in some random subdirectory
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Creating new zfile %s",
            zclock_time(), filepath );

    if (zfile_exists (filepath) ) {
        if (verbose)
            zsys_debug ("zfile_test() has to remove %s that should not have been here", filepath);
        zfile_delete (filepath);
    }

    file = zfile_new (dirpath, testfile);
    assert (file);
    int rc = zfile_output (file);
    assert (rc == 0);
    zchunk_t *chunk = zchunk_new (NULL, 100);
    assert (chunk);
    zchunk_fill (chunk, 0, 100);

    //  Write 100 bytes at position 1,000,000 in the file
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Writing 100 bytes at position 1,000,000 in the file",
            zclock_time() );
    rc = zfile_write (file, chunk, 1000000);
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Wrote 100 bytes at position 1,000,000 in the file, result code %d",
            zclock_time(), rc );
    assert (rc == 0);
    zchunk_destroy (&chunk);
    zfile_close (file);
    assert (zfile_is_readable (file));
    assert (zfile_cursize (file) == 1000100);
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Testing if file is NOT stable (is younger than 1 sec)",
            zclock_time() );
    assert (!zfile_is_stable (file));
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Passed the lag-dependent tests",
            zclock_time() );
    assert (zfile_digest (file));

    //  Now truncate file from outside
    int handle = open (filepath, O_WRONLY | O_TRUNC | O_BINARY, 0);
    assert (handle >= 0);
    rc = write (handle, "Hello, World\n", 13);
    assert (rc == 13);
    close (handle);
    assert (zfile_has_changed (file));
#ifdef CZMQ_BUILD_DRAFT_API
    zclock_sleep ((int)zsys_file_stable_age_msec() + 50);
#else
    zclock_sleep (5050);
#endif
    assert (zfile_has_changed (file));

    assert (!zfile_is_stable (file));
    zfile_restat (file);
    assert (zfile_is_stable (file));
    assert (streq (zfile_digest (file), "4AB299C8AD6ED14F31923DD94F8B5F5CB89DFB54"));

    //  Check we can read from file
    rc = zfile_input (file);
    assert (rc == 0);
    chunk = zfile_read (file, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_close (file);

    //  Check we can read lines from file
    rc = zfile_input (file);
    assert (rc == 0);
    const char *line = zfile_readln (file);
    assert (streq (line, "Hello, World"));
    line = zfile_readln (file);
    assert (line == NULL);
    zfile_close (file);

    //  Try some fun with symbolic links
    zfile_t *link = zfile_new (dirpath, testlink);
    assert (link);
    rc = zfile_output (link);
    assert (rc == 0);
    fprintf (zfile_handle (link), "%s\n", filepath);
    zfile_destroy (&link);

    link = zfile_new (dirpath, testlink);
    assert (link);
    rc = zfile_input (link);
    assert (rc == 0);
    chunk = zfile_read (link, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_destroy (&link);

    //  Remove file and directory
    zdir_t *dir = zdir_new (basedirpath, NULL);
    assert (dir);
    assert (zdir_cursize (dir) == 26);
    zdir_remove (dir, true);
    assert (zdir_cursize (dir) == 0);
    zdir_destroy (&dir);

    //  Check we can no longer read from file
    assert (zfile_is_readable (file));
    zfile_restat (file);
    assert (!zfile_is_readable (file));
    rc = zfile_input (file);
    assert (rc == -1);
    zfile_destroy (&file);

    // This set of tests is done, free the strings for reuse
    zstr_free (&basedirpath);
    zstr_free (&dirpath);
    zstr_free (&filepath);
    zstr_free (&linkpath);

    const char *eof_checkfile = "eof_checkfile";
    filepath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, eof_checkfile);
    assert (filepath);

    if (zfile_exists (filepath) ) {
        if (verbose)
            zsys_debug ("zfile_test() has to remove %s that should not have been here", filepath);
        zfile_delete (filepath);
    }
    zstr_free (&filepath);

    file = zfile_new (SELFTEST_DIR_RW, eof_checkfile);
    assert (file);

    //  1. Write something first
    rc = zfile_output (file);
    assert (rc == 0);
    chunk = zchunk_new ("123456789", 9);
    assert (chunk);

    rc = zfile_write (file, chunk, 0);
    assert (rc == 0);
    zchunk_destroy (&chunk);
    zfile_close (file);
    assert (zfile_cursize (file) == 9);

    // 2. Read the written something
    rc = zfile_input (file);
    assert (rc != -1);
    // try to read more bytes than there is in the file
    chunk = zfile_read (file, 1000, 0);
    assert (zfile_eof(file));
    assert (zchunk_streq (chunk, "123456789"));
    zchunk_destroy (&chunk);

    // reading is ok
    chunk = zfile_read (file, 5, 0);
    assert (!zfile_eof(file));
    assert (zchunk_streq (chunk, "12345"));
    zchunk_destroy (&chunk);

    // read from non zero offset until the end
    chunk = zfile_read (file, 5, 5);
    assert (zfile_eof(file));
    assert (zchunk_streq (chunk, "6789"));
    zchunk_destroy (&chunk);
    zfile_remove (file);
    zfile_close (file);
    zfile_destroy (&file);

#ifdef CZMQ_BUILD_DRAFT_API
    zfile_t *tempfile = zfile_tmp ();
    assert (tempfile);
    assert (zfile_filename (tempfile, NULL));
    assert (zsys_file_exists (zfile_filename (tempfile, NULL)));
    zchunk_t *tchunk = zchunk_new ("HELLO", 6);
    assert (zfile_write (tempfile, tchunk, 0) == 0);
    zchunk_destroy (&tchunk);

    char *filename = strdup (zfile_filename (tempfile, NULL));
    zfile_destroy (&tempfile);
    assert (!zsys_file_exists (filename));
    zstr_free (&filename);
#endif // CZMQ_BUILD_DRAFT_API

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

    //  @end

    printf ("OK\n");
}