Paul Eggert wrote:

in my test:
   diff --recursive <rel-dir-1> <rel-dir-2>

does not work.

What are the failure symptoms?

Is this something you can debug? I don't use MS-Windows and won't be of much help on that platform. My guess would be in the fdopendir area; perhaps that guess will help you debug.

Correct.

Now I've made a simple test-program for 'openat()' based
on the examples at:
   https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopendir.html

A simple 'du' clone; attached.

I found 2 issues which I believe is related to this problem
on Windows:
   1) 'open()' + 'fdopendir()' can NOT contain '\\' slashes.
   2) 'openat()' MUST be given a fully qualified pathname.
      A relative dir like ' dp->d_name' does not work.

What does this tell you guys about the 'diff --recursive'
behaviour on Windows?


--
--gv

/*
 * Rewritten from example here:
 *  https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopendir.html
 *
 * A simple 'du' (Disk Usage) clone.
 */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

uint64_t walk_tmp_dir (const char *dir)
{
  struct stat    st;
  struct dirent *dp;
  char           full_name [1000];
  char           dir_name [1000], *p;
  int            dfd;
  DIR           *d;
  uint64_t       sum = 0;

  strncpy (dir_name, dir, sizeof(dir_name)-1);
  for (p = dir_name; *p; p++)
      if (*p == '\\')
         *p = '/';

  dfd = open (dir_name, O_RDONLY);
  d = fdopendir (dfd);

  if (!d)
  {
    fprintf (stderr, "Cannot open '%s' directory\n", dir_name);
    exit (1);
  }

  while ((dp = readdir(d)) != NULL)
  {
    int ffd;

    if (dp->d_name[0] == '.')
       continue;

    snprintf (full_name, sizeof(full_name), "%s/%s", dir_name, dp->d_name);

#if 0
    ffd = openat (dfd, dp->d_name, O_RDONLY);  // does not work
#else
    ffd = openat (dfd, full_name, O_RDONLY);   // does work
#endif

    if (ffd < 0)
    {
      printf ("         %s: %s\n", full_name, strerror(errno));
      continue;
    }

    if (fstat(ffd, &st) == 0)
    {
      if (S_ISDIR(st.st_mode))
      {
        sum += walk_tmp_dir (full_name);
      }
      else
      {
        sum += st.st_size;
        printf ("%5jdK:  %s\n", st.st_size/1024, full_name);
      }
    }
    close (ffd);
  }
  closedir (d);
  return (sum);
}

int main (int argc, char **argv)
{
  uint64_t sum = walk_tmp_dir (argc > 1 ? argv[1] : "c:/temp");

  printf ("total size: %llu kB\n", sum/1024);
  return (0);
}

Reply via email to