bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Cvs-dev] Re: [bug-gnulib] AC_HEADER_DIRENT


From: Derek R. Price
Subject: Re: [Cvs-dev] Re: [bug-gnulib] AC_HEADER_DIRENT
Date: Tue, 11 Jul 2006 13:42:10 -0400
User-agent: Thunderbird 1.5.0.4 (Windows/20060516)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Paul Eggert wrote:
>> I'd be happy to declare my changes to those files also public domain, if
>> it makes things any easier.  If this is needed, we might need Jim to
>> declare his tweaks public domain too under the many tiny changes rule,
> 
> I'd rather not use this escape hatch for GNU projects, as there are
> sound legal reasons for preferring signing papers to the "let's
> declare it public domain" route.  You (Derek) shouldn't need to go the
> public-domain route anyway, since you've signed the papers.  If the
> bottleneck is Jim Hyslop, we can wait for his papers to go through.

Well, there's still the issue that the files started in the public
domain.  The POSIX.1 portion of <dirent.h> is pretty straightforward,
but someone will probably have to rewrite the struct underlying the DIR*
and most all of "dirent.c" from the POSIX API if we want to distribute
it under the GPL or LGPL.

Unless I'm misunderstanding.  Is it okay to just take some code that was
declared to be in the public domain and redistribute it under the GPL?

I've attached my current revisions of the files for inspection.

Thanks,

Derek
- --
Derek R. Price
CVS Solutions Architect
Get CVS support at Ximbiot <http://ximbiot.com>!
v: +1 248.835.1260
f: +1 248.835.1263
<mailto:address@hidden>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEs+LyLD1OTBfyMaQRAu3EAKDik5Mv5NAjvpGO7OViXha0UpWEaACg/WiM
e1dfIQOj+jw4tkXvfSFzEgo=
=HSMk
-----END PGP SIGNATURE-----
/*  dirent.h - portable directory routines
 *
 * This file is in the public domain.
 *
 * Everything non trivial in this code came originally from: @(#)msd_dir.c 1.4
 * 87/11/06, a public domain implementation of BSD directory routines for
 * MS-DOS, written by Michael Rendell ({uunet,address@hidden),
 * August 1987.
 *
 * Converted to CVS's "windows-NT/ndir.c" in 1990 by Thorsten Ohl
 * <address@hidden>.
 *
 * Minor adaptations made in 2006 by Derek R. Price <address@hidden>, with
 * Windows API oversight by Jim Hyslop <address@hidden>, to meet the
 * POSIX.1 <dirent.h> API with some GNU extensions (as opposed to its
 * intermediate incarnation as CVS's "windows-NT/ndir.h").
 */

#ifndef WINDOWSNT_DIRENT_H_INCLUDED
#define WINDOWSNT_DIRENT_H_INCLUDED

#define rewinddir(dirp) seekdir (dirp, 0L)

/* 255 is said to be big enough for Windows NT.  The more elegant
 * solution would be declaring d_name as one byte long and allocating
 * it to the actual size needed.
 */
#ifndef NAME_MAX
# define NAME_MAX 255
#endif
struct dirent
{
  size_t d_namlen;              /* GNU extension.  */
  char d_name[NAME_MAX + 1];    /* guarantee null termination */
};

struct _dircontents
{
  size_t _d_length;
  char *_d_entry;
  struct _dircontents *_d_next;
};

typedef struct _dirdesc
{
  int dd_id;                    /* uniquely identify each open directory */
  long dd_loc;                  /* where we are in directory entry is this */
  struct _dircontents *dd_contents;     /* pointer to contents of dir */
  struct _dircontents *dd_cp;   /* pointer to current position */
} DIR;

int closedir (DIR *);
DIR *opendir (const char *);
struct dirent *readdir (DIR *);
int readdir_r (DIR *, struct dirent *restrict, struct dirent **restrict);
void seekdir (DIR *, long);
long telldir (DIR *);

/* GNU extension.  */
#define _D_EXACT_NAMLEN(dp) (dp)->d_namlen

#endif /* WINDOWSNT_DIRENT_H_INCLUDED */
/*  dirent.c - portable directory routines
 *
 * This file is in the public domain.
 *
 * Everything non trivial in this code came originally from: @(#)msd_dir.c 1.4
 * 87/11/06, a public domain implementation of BSD directory routines for
 * MS-DOS, written by Michael Rendell ({uunet,address@hidden),
 * August 1987.
 *
 * Converted to CVS's "windows-NT/ndir.c" in 1990 by Thorsten Ohl
 * <address@hidden>.
 *
 * Minor adaptations made in 2006 by Derek R. Price <address@hidden>, with
 * Windows API oversight by Jim Hyslop <address@hidden>, to meet the
 * POSIX.1 <dirent.h> API with some GNU extensions (as opposed to its
 * intermediate incarnation as CVS's "windows-NT/ndir.c").
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

/* Validate API.  */
#include <sys/types.h>
#include <dirent.h>

/* System (WOE32) Includes.  */
#include <dos.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

/* GNULIB Includes.  */
#include "xalloc.h"



DIR *
opendir (const char *name)
{
  struct _finddata_t find_buf;
  DIR *dirp;
  struct _dircontents *dp;
  char name_buf[_MAX_PATH + 1];
  char *slash = "";
  long hFile;

  if (!name)
    name = "";
  else if (*name)
    {
      const char *s;
      int l = strlen (name);

      s = name + l - 1;
      if ( !(l == 2 && *s == ':') && *s != '\\' && *s != '/')
        slash = "/";    /* save to insert slash between path and "*.*" */
    }

  sprintf (name_buf, "%s%s%s", name, slash, "*.*");

  dirp = xmalloc (sizeof DIR);
  dirp->dd_loc = 0;
  dirp->dd_contents = dirp->dd_cp = NULL;

  if ((hFile = _findfirst (name_buf, &find_buf)) < 0)
    {
      free (dirp);
      return NULL;
    }

  do
    {
      dp = xmalloc (sizeof struct _dircontents);
      dp->_d_length = strlen (find_buf.name);
      dp->_d_entry = xmalloc (dp->_d_length + 1);
      memcpy (dp->_d_entry, find_buf.name, dp->_d_length + 1);

      if (dirp->dd_contents)
        dirp->dd_cp = dirp->dd_cp->_d_next = dp;
      else
        dirp->dd_contents = dirp->dd_cp = dp;

      dp->_d_next = NULL;

    } while (!_findnext (hFile, &find_buf));

  dirp->dd_cp = dirp->dd_contents;

  _findclose(hFile);

  return dirp;
}



/* Garbage collection */
static void
free_dircontents (struct _dircontents *dp)
{
  struct _dircontents *odp;

  while (dp)
    {
      if (dp->_d_entry)
        free (dp->_d_entry);
      dp = (odp = dp)->_d_next;
      free (odp);
    }
}



int
closedir (DIR *dirp)
{
  free_dircontents (dirp->dd_contents);
  free (dirp);
  return 0;
}



int
readdir_r (DIR *dirp, struct dirent * restrict dp,
           struct dirent ** restrict result)
{
  if (!dirp->dd_cp)
    *result = NULL;
  else
    {
      dp->d_namlen = dirp->dd_cp->_d_length;
      memcpy (dp->d_name, dirp->dd_cp->_d_entry, dp->d_namlen + 1);

      dirp->dd_cp = dirp->dd_cp->_d_next;
      dirp->dd_loc++;
      *result = dp;
    }

  return 0;
}



struct dirent *
readdir (DIR *dirp)
{
  static struct dirent dp;
  static struct dirent *retval;
  int err = readdir_r (dirp, &dp, &retval);
  if (err)
    {
      errno = err;
      retval = NULL;
    }
  return retval;
}



void
seekdir (DIR *dirp, long off)
{
  long i = off;
  struct _dircontents *dp;

  if (off < 0)
    return;
  for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next)
    ;
  dirp->dd_loc = off - (i + 1);
  dirp->dd_cp = dp;
}



long
telldir (DIR *dirp)
{
  return dirp->dd_loc;
}



#ifdef TEST
void
main (int argc, char *argv[])
{
  static DIR *directory;
  struct dirent *entry = NULL;

  char *name = "";

  if (argc > 1)
    name = argv[1];

  directory = opendir (name);

  if (!directory)
    {
      fprintf (stderr, "can't open directory `%s'.\n", name);
      exit (2);
    }

  while (entry = readdir (directory))
    printf ("> %s\n", entry->d_name);

  printf ("done.\n");
}
#endif /* TEST */

reply via email to

[Prev in Thread] Current Thread [Next in Thread]