delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/08/24/15:24:17

Message-ID: <39A577FD.834F90D1@softhome.net>
Date: Thu, 24 Aug 2000 21:31:09 +0200
From: Laurynas Biveinis <lauras AT softhome DOT net>
X-Mailer: Mozilla 4.74 [en] (Win98; U)
X-Accept-Language: lt,en
MIME-Version: 1.0
To: DJGPP Workers <djgpp-workers AT delorie DOT com>
Subject: Update __solve_dir_symlinks() patch
Reply-To: djgpp-workers AT delorie DOT com

It solves drive letter handling issues pointed out by Eli. Also 
there are related testsuite additions.

If this patch is OK, I commit other patches for remove() etc.

Any comments?

Laurynas

Index: djgpp/src/libc/compat/unistd/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/compat/unistd/makefile,v
retrieving revision 1.7
diff -u -p -r1.7 makefile
--- makefile	2000/08/20 15:46:38	1.7
+++ makefile	2000/08/24 19:20:11
@@ -15,6 +15,7 @@ SRC += lchown.c
 SRC += llseek.c
 SRC += nice.c
 SRC += readlink.c
+SRC += sdirlink.c
 SRC += symlink.c
 SRC += sync.c
 SRC += truncate.c
Index: djgpp/src/libc/compat/unistd/sdirlink.c
===================================================================
RCS file: sdirlink.c
diff -N sdirlink.c
--- /dev/null	Tue May  5 16:32:27 1998
+++ sdirlink.c	Thu Aug 24 15:20:11 2000
@@ -0,0 +1,49 @@
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+
+#include <libc/stubs.h>
+#include <libc/symlink.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int __solve_dir_symlinks(const char * __symlink_path, char * __real_path)
+{
+   char   path_copy[FILENAME_MAX];
+   char * last_part;
+   strcpy(path_copy, __symlink_path);
+   last_part = basename(path_copy);
+   if (*last_part == '\0')
+   {
+      /* If basename() returned pointer to the end of string, cut the last 
+       * dir separator and try again. Exception: for paths like 'C:', just
+       * copy it to the result and return.
+       */ 
+      if (*(last_part - 1) == ':')
+      {
+         strcpy(__real_path, path_copy);
+         return 1;
+      }
+      *(last_part - 1) = '\0'; 
+      last_part = basename(path_copy);
+   }
+   if (last_part == path_copy)
+   {
+      /* The path is made from single part */
+      strcpy(__real_path, path_copy);
+      return 1;
+   }
+   /* If the have path like c:/file or c:file, just copy it to the result
+    * and return.
+    */
+   if (*(last_part - 1) == ':')
+   {
+      strcpy(__real_path, path_copy);
+      return 1;
+   }
+   *(last_part - 1) = '\0';
+   if (!__solve_symlinks(path_copy, __real_path))
+      return 0;
+   strcat(__real_path, "/");
+   strcat(__real_path, last_part);
+   return 1;
+}
+
Index: djgpp/src/libc/compat/unistd/sdirlink.txh
===================================================================
RCS file: sdirlink.txh
diff -N sdirlink.txh
--- /dev/null	Tue May  5 16:32:27 1998
+++ sdirlink.txh	Thu Aug 24 15:20:11 2000
@@ -0,0 +1,37 @@
+@node __solve_dir_symlinks, io
+@subheading Syntax
+
+@example
+#include <libc/symlink.h>
+
+int __solve_dir_symlinks(const char *symlink_path, char *real_path);
+@end example
+
+@subheading Description
+This function resolves given symlink in @var{symlink_path}---all path 
+components @strong{except} the last one and all symlink levels are 
+resolved.  If @var{symlink_path} does not contain symlinks at all, it is 
+simply copied to @var{real_path}.
+
+@subheading Return Value
+
+Zero in case of error (and @code{errno} set to the appropriate
+error code), non-zero in case of success.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+
+  #include <libc/symlink.h>
+  #include <stdio.h>
+
+  __solve_dir_symlinks(fn, file_name);
+  printf("The real path to %s is %s\n", fn, file_name);
+
+
+@end example
+
Index: djgpp/tests/libc/compat/unistd/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/tests/libc/compat/unistd/makefile,v
retrieving revision 1.2
diff -u -p -r1.2 makefile
--- makefile	2000/08/14 08:51:31	1.2
+++ makefile	2000/08/24 19:20:33
@@ -1,6 +1,7 @@
 TOP=../..
 
 SRC += readlink.c
+SRC += sdirlink.c
 SRC += symlink.c
 SRC += xsymlink.c
 
Index: djgpp/tests/libc/compat/unistd/sdirlink.c
===================================================================
RCS file: sdirlink.c
diff -N sdirlink.c
--- /dev/null	Tue May  5 16:32:27 1998
+++ sdirlink.c	Thu Aug 24 15:20:33 2000
@@ -0,0 +1,77 @@
+/* Testsuite for __solve_dir_symlinks()
+ * There are following success tests:
+ *   1. Simple case with symlink in current directory
+ *   2. Symlink with a trailing slash
+ *   3. Symlink in subdirectory
+ *   4. Real file in symlinked directory
+ *   5. Symlink in symlinked directory
+ *   6. Real file in a symlink subdir in a symlink subdir
+ * Any unhandled cases are more than welcome.
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libc/symlink.h>
+#include <sys/stat.h>
+
+static void test_success(int num, const char * slink, const char * expect);
+
+int main(void)
+{
+   if (!__file_exists("test1") || !__file_exists("test4") ||
+       !__file_exists("test5") || !__file_exists("dirtest") ||
+       !__file_exists("fail1") || !__file_exists("fail2") ||
+       !__file_exists("fail3") || !__file_exists("dir1/fail1") ||
+       !__file_exists("dir1/test1") || !__file_exists("dir1/test2") ||
+       !__file_exists("dir1/test3") || !__file_exists("dir1/test4") ||
+       !__file_exists("dir1/test5") || !__file_exists("dir1/test6") ||
+       !__file_exists("dir1/test7") || access("dir1/dir2", D_OK))
+   {
+       fprintf(stderr, "Required data files not found");
+       exit(1);
+   }
+   printf("Running __solve_dir_symlink() testsuite:\n");
+   test_success( 1, "test1", "test1");
+   test_success( 2, "test1/", "test1");
+   test_success( 3, "dir1/test1", "dir1/test1");
+   test_success( 4, "dirtest/file1", "dir1/file1");
+   test_success( 5, "dirtest/test1", "dir1/test1");
+   test_success( 6, "dirtest/test6/file", "dir1/dir2/file");
+   test_success( 7, "c:test1", "c:test1");
+   symlink("c:/file", "c:/linkfile");
+   test_success( 8, "c:/linkfile", "c:/linkfile");
+   remove("c:/linkfile");
+   test_success( 9, "c:/djgpp/tests/libc/compat/unistd/file1", 
+                    "c:/djgpp/tests/libc/compat/unistd/file1");
+   printf("Done.\n");
+   return 0;
+}
+
+static void test_success(int num, const char * slink, const char * expect)
+{
+   char real_name[FILENAME_MAX + 1];
+   char real_fixed[FILENAME_MAX + 1];
+   char expect_fixed[FILENAME_MAX + 1];
+   char err_buf[50];
+   if (!__solve_dir_symlinks(slink, real_name))
+   {
+      sprintf(err_buf, "Test %d failed ", num);
+      perror(err_buf);
+      exit(1);
+   }
+   _fixpath(expect, expect_fixed);
+   _fixpath(real_name, real_fixed);
+   if (strcmp(real_fixed, expect_fixed))
+   {
+      fprintf(stderr,
+            "Test %d failed - __solve_dir_symlinks returns wrong resolved path\n",
+            num);
+      fprintf(stderr, "Expected   %s\n", expect_fixed);
+      fprintf(stderr, "It returns %s\n", real_fixed);
+      exit(1);
+   }
+   printf("Test %d passed\n", num);
+}
+

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019