public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
* [PATCH] Add get_current_dir_name(3)
@ 2012-01-01  2:45 Yaakov (Cygwin/X)
  2012-01-01  6:46 ` Christopher Faylor
  0 siblings, 1 reply; 6+ messages in thread
From: Yaakov (Cygwin/X) @ 2012-01-01  2:45 UTC (permalink / raw)
  To: cygwin-patches

[-- Attachment #1: Type: text/plain, Size: 883 bytes --]

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


[-- Attachment #2: cygwin-get_current_dir_name.patch --]
[-- Type: text/x-patch, Size: 2936 bytes --]

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

[-- Attachment #3: doc-get_current_dir_name.patch --]
[-- Type: text/x-patch, Size: 878 bytes --]

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>

[-- Attachment #4: newlib-get_current_dir_name.patch --]
[-- Type: text/x-patch, Size: 851 bytes --]

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));

[-- Attachment #5: test-get_current_dir_name.c --]
[-- Type: text/x-csrc, Size: 692 bytes --]

#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;
}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add get_current_dir_name(3)
  2012-01-01  2:45 [PATCH] Add get_current_dir_name(3) Yaakov (Cygwin/X)
@ 2012-01-01  6:46 ` Christopher Faylor
  2012-01-01  7:13   ` Yaakov (Cygwin/X)
  0 siblings, 1 reply; 6+ messages in thread
From: Christopher Faylor @ 2012-01-01  6:46 UTC (permalink / raw)
  To: cygwin-patches

On Sat, Dec 31, 2011 at 08:45:07PM -0600, Yaakov (Cygwin/X) wrote:
>This patchset adds get_current_dir_name(3), a GNU extension:
>[snip]
>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)

You have to check st_dev here too don't you?

cgf

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add get_current_dir_name(3)
  2012-01-01  6:46 ` Christopher Faylor
@ 2012-01-01  7:13   ` Yaakov (Cygwin/X)
  2012-01-01 16:07     ` Christopher Faylor
  2012-01-02 12:56     ` Eric Blake
  0 siblings, 2 replies; 6+ messages in thread
From: Yaakov (Cygwin/X) @ 2012-01-01  7:13 UTC (permalink / raw)
  To: cygwin-patches

[-- Attachment #1: Type: text/plain, Size: 559 bytes --]

On Sun, 2012-01-01 at 01:46 -0500, Christopher Faylor wrote:
> On Sat, Dec 31, 2011 at 08:45:07PM -0600, Yaakov (Cygwin/X) wrote:
> >+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)
> 
> You have to check st_dev here too don't you?

Of course.  Revised patch for winsup/cygwin attached.


Yaakov


[-- Attachment #2: cygwin-get_current_dir_name.patch --]
[-- Type: text/x-patch, Size: 2972 bytes --]

2012-01-01  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.250
diff -u -p -r1.250 cygwin.din
--- cygwin.din	30 Dec 2011 20:22:27 -0000	1.250
+++ cygwin.din	1 Jan 2012 07:11:31 -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	1 Jan 2012 07:11:31 -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_dev == cwdbuf.st_dev) && (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.73
diff -u -p -r1.73 posix.sgml
--- posix.sgml	30 Dec 2011 20:22:27 -0000	1.73
+++ posix.sgml	1 Jan 2012 07:11:32 -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.358
diff -u -p -r1.358 version.h
--- include/cygwin/version.h	30 Dec 2011 20:22:28 -0000	1.358
+++ include/cygwin/version.h	1 Jan 2012 07:11:32 -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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add get_current_dir_name(3)
  2012-01-01  7:13   ` Yaakov (Cygwin/X)
@ 2012-01-01 16:07     ` Christopher Faylor
  2012-01-02 12:56     ` Eric Blake
  1 sibling, 0 replies; 6+ messages in thread
From: Christopher Faylor @ 2012-01-01 16:07 UTC (permalink / raw)
  To: cygwin-patches

On Sun, Jan 01, 2012 at 01:13:25AM -0600, Yaakov (Cygwin/X) wrote:
>On Sun, 2012-01-01 at 01:46 -0500, Christopher Faylor wrote:
>> On Sat, Dec 31, 2011 at 08:45:07PM -0600, Yaakov (Cygwin/X) wrote:
>> >+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)
>> 
>> You have to check st_dev here too don't you?
>
>Of course.  Revised patch for winsup/cygwin attached.

Looks good.  The Cygwin part is approved.

Thanks.

cgf

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add get_current_dir_name(3)
  2012-01-01  7:13   ` Yaakov (Cygwin/X)
  2012-01-01 16:07     ` Christopher Faylor
@ 2012-01-02 12:56     ` Eric Blake
  2012-01-02 17:55       ` Christopher Faylor
  1 sibling, 1 reply; 6+ messages in thread
From: Eric Blake @ 2012-01-02 12:56 UTC (permalink / raw)
  To: cygwin-patches

[-- Attachment #1: Type: text/plain, Size: 844 bytes --]

On 01/01/2012 12:13 AM, Yaakov (Cygwin/X) wrote:
>> > You have to check st_dev here too don't you?
> Of course.  Revised patch for winsup/cygwin attached.
> 

> +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_dev == cwdbuf.st_dev) && (pwdbuf.st_ino == cwdbuf.st_ino))
> +        {
> +          cwd = (char *) malloc (strlen (pwd) + 1);

Memory leak.  You need to free(cwd) before reassigning it.  And why are
you using malloc(strlen())/strcpy(), when you could just use strdup()?

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 620 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add get_current_dir_name(3)
  2012-01-02 12:56     ` Eric Blake
@ 2012-01-02 17:55       ` Christopher Faylor
  0 siblings, 0 replies; 6+ messages in thread
From: Christopher Faylor @ 2012-01-02 17:55 UTC (permalink / raw)
  To: cygwin-patches

On Mon, Jan 02, 2012 at 05:56:26AM -0700, Eric Blake wrote:
>On 01/01/2012 12:13 AM, Yaakov (Cygwin/X) wrote:
>>> > You have to check st_dev here too don't you?
>> Of course.  Revised patch for winsup/cygwin attached.
>> 
>
>> +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_dev == cwdbuf.st_dev) && (pwdbuf.st_ino == cwdbuf.st_ino))
>> +        {
>> +          cwd = (char *) malloc (strlen (pwd) + 1);
>
>Memory leak.  You need to free(cwd) before reassigning it.  And why are
>you using malloc(strlen())/strcpy(), when you could just use strdup()?

Oops.  Eric is right.  Also, there should have been some error checking
for the stat calls since PWD is user-settable and could be bogus.  I'll
make those changes.

cgf

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-01-02 17:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-01  2:45 [PATCH] Add get_current_dir_name(3) Yaakov (Cygwin/X)
2012-01-01  6:46 ` Christopher Faylor
2012-01-01  7:13   ` Yaakov (Cygwin/X)
2012-01-01 16:07     ` Christopher Faylor
2012-01-02 12:56     ` Eric Blake
2012-01-02 17:55       ` Christopher Faylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).