Blame test/driver/realpath.c

Packit dd8086
/* -*- C -*-
Packit dd8086
  Copyright (C) 2010-2012, 2015, 2017 Rocky Bernstein <rocky@gnu.org>
Packit dd8086
Packit dd8086
  This program is free software: you can redistribute it and/or modify
Packit dd8086
  it under the terms of the GNU General Public License as published by
Packit dd8086
  the Free Software Foundation, either version 3 of the License, or
Packit dd8086
  (at your option) any later version.
Packit dd8086
Packit dd8086
  This program is distributed in the hope that it will be useful,
Packit dd8086
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit dd8086
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit dd8086
  GNU General Public License for more details.
Packit dd8086
Packit dd8086
  You should have received a copy of the GNU General Public License
Packit dd8086
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit dd8086
*/
Packit dd8086
Packit dd8086
/*
Packit dd8086
   Unit test for lib/driver/realpath.c
Packit dd8086
*/
Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
#include "config.h"
Packit dd8086
#define __CDIO_CONFIG_H__ 1
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#ifdef HAVE_STDIO_H
Packit dd8086
#include <stdio.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_STRING_H
Packit dd8086
#include <string.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_LIMITS_H
Packit dd8086
#include <limits.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_STDLIB_H
Packit dd8086
#include <stdlib.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_SYS_STAT_H
Packit dd8086
#include <sys/stat.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_SYS_TYPES_H
Packit dd8086
#include <sys/types.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_UNISTD_H
Packit dd8086
#include <unistd.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_ERRNO_H
Packit dd8086
#include <errno.h>
Packit dd8086
#endif
Packit dd8086
#if defined(_WIN32) && !defined(__CYGWIN__)
Packit dd8086
#include <windows.h>
Packit dd8086
#include <direct.h> /* _mkdir */
Packit dd8086
/* MinGW, MSVC do not have symlink */
Packit dd8086
#define symlink(oldpath, newpath) CopyFileA(oldpath, newpath, FALSE)
Packit dd8086
#else
Packit dd8086
#define _mkdir(a) mkdir(a, S_IRWXU)
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <cdio/util.h>
Packit dd8086
Packit dd8086
#ifdef MINGW32
Packit dd8086
#define MY_DIR_SEPARATOR '\\'
Packit dd8086
#else
Packit dd8086
#define MY_DIR_SEPARATOR '/'
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#ifndef PATH_MAX
Packit dd8086
#define PATH_MAX 4096
Packit dd8086
#endif
Packit dd8086
Packit dd8086
static char *
Packit dd8086
get_temporary_name(const char *dirname, const char *errmsg)
Packit dd8086
{
Packit dd8086
    char *new_filename = tempnam(NULL, "syml");
Packit dd8086
    if (NULL == new_filename) {
Packit dd8086
        printf("Could not generate %s name\n", errmsg);
Packit dd8086
    }
Packit dd8086
    return new_filename;
Packit dd8086
}
Packit dd8086
Packit dd8086
static int check_rc(int rc, const char *psz_operation,
Packit dd8086
    const char *psz_filename)
Packit dd8086
{
Packit dd8086
    if (-1 == rc) {
Packit dd8086
        printf("%s %s failed with error: %s\n",
Packit dd8086
               psz_operation, psz_filename, strerror(errno));
Packit dd8086
    } else if (0 != rc) {
Packit dd8086
        printf("%s %s gives weird return %d\n",
Packit dd8086
               psz_operation, psz_filename, rc);
Packit dd8086
    }
Packit dd8086
    return rc;
Packit dd8086
}
Packit dd8086
Packit dd8086
Packit dd8086
Packit dd8086
int
Packit dd8086
main(int argc, const char *argv[])
Packit dd8086
{
Packit dd8086
    char *psz_tmp_subdir;
Packit dd8086
    char *psz_orig_file;
Packit dd8086
    char tmp_dir[PATH_MAX+1] = {0};
Packit dd8086
    char tmp_subdir[PATH_MAX+1] = {0};
Packit dd8086
    char psz_file_check[PATH_MAX+1];
Packit dd8086
    char *psz_last_slash;
Packit dd8086
    int i_last_slash;
Packit dd8086
    char *psz_symlink_file = NULL;
Packit dd8086
    int rc = 0;
Packit dd8086
Packit dd8086
    psz_tmp_subdir = get_temporary_name(NULL, "temporary directory");
Packit dd8086
    if (NULL == psz_tmp_subdir) {
Packit dd8086
      rc = 77;
Packit dd8086
      goto err_exit1;
Packit dd8086
    }
Packit dd8086
    if (-1 == check_rc(_mkdir(psz_tmp_subdir),
Packit dd8086
                       "mkdir", psz_tmp_subdir)) {
Packit dd8086
      rc = 77;
Packit dd8086
      goto err_exit1;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    cdio_realpath(psz_tmp_subdir, tmp_subdir);
Packit dd8086
Packit dd8086
    if (0 == strlen(tmp_subdir)) {
Packit dd8086
      fprintf(stderr, "cdio_realpath on temp directory %s failed\n",
Packit dd8086
              psz_tmp_subdir);
Packit dd8086
      rc = 1;
Packit dd8086
      goto err_exit1;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    psz_last_slash = strrchr(tmp_subdir, MY_DIR_SEPARATOR);
Packit dd8086
    if (psz_last_slash == NULL) {
Packit dd8086
      printf("Can't find %c in %s\n", MY_DIR_SEPARATOR, tmp_subdir);
Packit dd8086
      rc = 2;
Packit dd8086
      goto err_exit1;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    i_last_slash = psz_last_slash - tmp_subdir + 1;
Packit dd8086
    memcpy(tmp_dir, tmp_subdir, i_last_slash);
Packit dd8086
    tmp_dir[i_last_slash] = '\0';
Packit dd8086
    printf("-- Temp directory is %s\n", tmp_dir);
Packit dd8086
Packit dd8086
    psz_orig_file = get_temporary_name(NULL, "file");
Packit dd8086
    if (NULL != psz_orig_file) {
Packit dd8086
        FILE *fp = fopen(psz_orig_file, "w");
Packit dd8086
        char orig_file[PATH_MAX+1] = {0};
Packit dd8086
        char symlink_file[PATH_MAX+1] = {0};
Packit dd8086
Packit dd8086
        fprintf(fp, "testing\n");
Packit dd8086
        fclose(fp);
Packit dd8086
        cdio_realpath(psz_orig_file, orig_file);
Packit dd8086
        if (0 == strlen(orig_file)) {
Packit dd8086
          fprintf(stderr, "cdio_realpath on temp file %s failed\n",
Packit dd8086
                  psz_orig_file);
Packit dd8086
	  rc = 3;
Packit dd8086
	  goto err_exit;
Packit dd8086
        }
Packit dd8086
Packit dd8086
        psz_symlink_file = get_temporary_name(NULL, "symlink file");
Packit dd8086
        rc = check_rc(symlink(psz_orig_file, psz_symlink_file),
Packit dd8086
                      "symlink", psz_symlink_file);
Packit dd8086
        if (0 == rc) {
Packit dd8086
            /* Just when you thought we'd forgotten, here is our first
Packit dd8086
               test! */
Packit dd8086
            cdio_realpath(psz_symlink_file, psz_file_check);
Packit dd8086
            if (0 != strncmp(psz_file_check, orig_file, PATH_MAX)) {
Packit dd8086
                fprintf(stderr, "simple cdio_realpath failed: %s vs %s\n",
Packit dd8086
                        psz_file_check, orig_file);
Packit dd8086
		rc = 4;
Packit dd8086
		goto err_exit;
Packit dd8086
            }
Packit dd8086
            check_rc(unlink(psz_symlink_file), "unlink", psz_symlink_file);
Packit dd8086
        }
Packit dd8086
Packit dd8086
        /* Make sure we handle a cyclic symbolic name, e.g. xx -> xx */
Packit dd8086
        cdio_realpath(psz_symlink_file, symlink_file);
Packit dd8086
        rc = check_rc(symlink(psz_symlink_file, psz_symlink_file),
Packit dd8086
                      "symlink", psz_symlink_file);
Packit dd8086
        if (0 == rc) {
Packit dd8086
            cdio_realpath(psz_symlink_file, psz_file_check);
Packit dd8086
            if (0 != strncmp(psz_file_check, symlink_file, PATH_MAX)) {
Packit dd8086
                fprintf(stderr, "direct cdio_realpath cycle test failed. %s vs %s\n",
Packit dd8086
                        psz_file_check, symlink_file);
Packit dd8086
		rc = 5;
Packit dd8086
		goto err_exit;
Packit dd8086
            }
Packit dd8086
            check_rc(unlink(psz_symlink_file), "unlink", psz_symlink_file);
Packit dd8086
        }
Packit dd8086
Packit dd8086
    }
Packit dd8086
Packit dd8086
    check_rc(unlink(psz_orig_file), "unlink", psz_orig_file);
Packit dd8086
    check_rc(rmdir(psz_tmp_subdir), "rmdir", psz_tmp_subdir);
Packit dd8086
		free(psz_symlink_file);
Packit dd8086
 err_exit:
Packit dd8086
    free(psz_orig_file);
Packit dd8086
 err_exit1:
Packit dd8086
    free(psz_tmp_subdir);
Packit dd8086
Packit dd8086
    return rc;
Packit dd8086
}