This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Add get_current_dir_name(3)


This patchset adds get_current_dir_name(3), a GNU extension:

http://www.gnu.org/software/libc/manual/html_node/Working-Directory.html
http://www.kernel.org/doc/man-pages/online/pages/man3/getcwd.3.html

The test code will show the difference between get_current_dir_name()
and getcwd(NULL, 0) when you cd into a directory via a symlink:

$ gcc -Wall -o test-get_current_dir_name.exe test-get_current_dir_name.c
$ mkdir /tmp/real
$ ln -s real /tmp/symlink
$ cd /tmp/symlink
$ /path/to/test-get_current_dir_name.exe
                  PWD: /tmp/symlink
               getcwd: /tmp/real
 get_current_dir_name: /tmp/symlink

: now try spoofing PWD
$ PWD=$HOME /path/to/test-get_current_dir_name.exe
                  PWD: /home/Yaakov
               getcwd: /tmp/real
 get_current_dir_name: /tmp/real

Patches for newlib, winsup/cygwin, and winsup/doc, plus the STC,
attached.


Yaakov

2011-12-31  Yaakov Selkowitz  <yselkowitz@...>

	* cygwin.din (get_current_dir_name): Export.
	* path.cc (get_current_dir_name): New function.
	* posix.sgml (std-gnu): Add get_current_dir_name.
	* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.

Index: cygwin.din
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/cygwin.din,v
retrieving revision 1.249
diff -u -p -r1.249 cygwin.din
--- cygwin.din	7 Nov 2011 20:05:48 -0000	1.249
+++ cygwin.din	27 Dec 2011 11:28:05 -0000
@@ -672,6 +672,7 @@ _gcvt = gcvt SIGFE
 gcvtf SIGFE
 _gcvtf = gcvtf SIGFE
 get_avphys_pages SIGFE
+get_current_dir_name SIGFE
 get_nprocs SIGFE
 get_nprocs_conf SIGFE
 get_osfhandle SIGFE
Index: path.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.cc,v
retrieving revision 1.644
diff -u -p -r1.644 path.cc
--- path.cc	24 Dec 2011 13:11:34 -0000	1.644
+++ path.cc	27 Dec 2011 11:28:06 -0000
@@ -2855,6 +2855,27 @@ getwd (char *buf)
   return getcwd (buf, PATH_MAX + 1);  /*Per SuSv3!*/
 }
 
+extern "C" char *
+get_current_dir_name (void)
+{
+  char *pwd = getenv ("PWD");
+  char *cwd = getcwd (NULL, 0);
+
+  if (pwd)
+    {
+      struct __stat64 pwdbuf, cwdbuf;
+      stat64 (pwd, &pwdbuf);
+      stat64 (cwd, &cwdbuf);
+      if (pwdbuf.st_ino == cwdbuf.st_ino)
+        {
+          cwd = (char *) malloc (strlen (pwd) + 1);
+          strcpy (cwd, pwd);
+        }
+    }
+
+  return cwd;
+}
+
 /* chdir: POSIX 5.2.1.1 */
 extern "C" int
 chdir (const char *in_dir)
Index: posix.sgml
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/posix.sgml,v
retrieving revision 1.72
diff -u -p -r1.72 posix.sgml
--- posix.sgml	8 Nov 2011 09:24:58 -0000	1.72
+++ posix.sgml	27 Dec 2011 11:28:06 -0000
@@ -1111,6 +1111,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008)
     fremovexattr
     fsetxattr
     get_avphys_pages
+    get_current_dir_name
     get_phys_pages
     get_nprocs
     get_nprocs_conf
Index: include/cygwin/version.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/include/cygwin/version.h,v
retrieving revision 1.357
diff -u -p -r1.357 version.h
--- include/cygwin/version.h	22 Dec 2011 12:25:10 -0000	1.357
+++ include/cygwin/version.h	27 Dec 2011 11:28:06 -0000
@@ -426,12 +426,13 @@ details. */
       255: Export ptsname_r.
       256: Add CW_ALLOC_DRIVE_MAP, CW_MAP_DRIVE_MAP, CW_FREE_DRIVE_MAP.
       257: Export getpt.
+      258: Export get_current_dir_name.
      */
 
      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
 
 #define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 257
+#define CYGWIN_VERSION_API_MINOR 258
 
      /* There is also a compatibity version number associated with the
 	shared memory regions.  It is incremented when incompatible
2011-12-31  Yaakov Selkowitz  <yselkowitz@...>

	* new-features.sgml (ov-new1.7.10): Document get_current_dir_name.

Index: new-features.sgml
===================================================================
RCS file: /cvs/src/src/winsup/doc/new-features.sgml,v
retrieving revision 1.95
diff -u -p -r1.95 new-features.sgml
--- new-features.sgml	30 Dec 2011 20:24:18 -0000	1.95
+++ new-features.sgml	1 Jan 2012 02:27:44 -0000
@@ -101,8 +101,9 @@ dlopen now supports the Glibc-specific R
 </para></listitem>
 
 <listitem><para>
-Other new API: clock_settime, __fpurge, getgrouplist, getpt, ppoll, psiginfo,
-psignal, ptsname_r, sys_siglist, pthread_setschedprio, sysinfo.
+Other new API: clock_settime, __fpurge, getgrouplist, get_current_dir_name,
+getpt, ppoll, psiginfo, psignal, ptsname_r, sys_siglist, pthread_setschedprio,
+sysinfo.
 </para></listitem>
 
 </itemizedlist>
2011-12-31  Yaakov Selkowitz  <yselkowitz@...>

	* libc/include/sys/unistd.h [__CYGWIN__] (get_current_dir_name):
	Declare.

Index: libc/include/sys/unistd.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/sys/unistd.h,v
retrieving revision 1.79
diff -u -p -r1.79 unistd.h
--- libc/include/sys/unistd.h	19 Aug 2011 14:29:34 -0000	1.79
+++ libc/include/sys/unistd.h	27 Dec 2011 11:30:24 -0000
@@ -71,6 +71,9 @@ pid_t   _EXFUN(fork, (void ));
 long    _EXFUN(fpathconf, (int __fd, int __name ));
 int     _EXFUN(fsync, (int __fd));
 int     _EXFUN(fdatasync, (int __fd));
+#if defined(__CYGWIN__)
+char *	_EXFUN(get_current_dir_name, (void));
+#endif
 char *  _EXFUN(getcwd, (char *__buf, size_t __size ));
 #if defined(__CYGWIN__)
 int	_EXFUN(getdomainname ,(char *__name, size_t __len));
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef __CYGWIN__
#include <dlfcn.h>
#include <cygwin/version.h>
#endif

int
main (void)
{
#if defined(__CYGWIN__) && CYGWIN_VERSION_API_MINOR < 258
  char *(*get_current_dir_name) (void);
  get_current_dir_name = dlsym (dlopen ("cygwin1.dll", 0), "get_current_dir_name");
#endif

  char *pwd = getenv ("PWD");
  char *cwd = getcwd (NULL, 0);
  char *gcdn = get_current_dir_name ();

  printf ("                  PWD: %s\n", pwd);
  printf ("               getcwd: %s\n", cwd);
  printf (" get_current_dir_name: %s\n", gcdn);

  free (cwd);
  free (gcdn);

  return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]