From 355eb381900a42f6dcabeb21579db9aa686906a3 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 28 Jul 2003 19:49:47 +0000 Subject: [PATCH] New function g_read_link(). (#72545) * glib/gfileutils.h: * glib/gfileutils.c: New function g_read_link(). (#72545) --- ChangeLog | 8 ++++ ChangeLog.pre-2-10 | 8 ++++ ChangeLog.pre-2-12 | 8 ++++ ChangeLog.pre-2-4 | 8 ++++ ChangeLog.pre-2-6 | 8 ++++ ChangeLog.pre-2-8 | 8 ++++ docs/reference/ChangeLog | 2 +- docs/reference/glib/glib-sections.txt | 1 + glib/gfileutils.c | 59 +++++++++++++++++++++++++++ glib/gfileutils.h | 3 +- tests/file-test.c | 51 ++++++++++++++++++++++- 11 files changed, 161 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index b4fc25dfd..1e32938bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2003-07-28 Matthias Clasen + * glib/gfileutils.h: + * glib/gfileutils.c: New function g_read_link(). (#72545) + + * configure.in: Check for setenv, unsetenv, readlink and symlink. + + * tests/file-test.c (test_readlink): Test for g_read_link() (only on systems supporting + symbolic links). + * tests/env-test.c: New test for g_{get,set,unset}env(). * tests/Makefile.am (test_programs): Add env-test. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index b4fc25dfd..1e32938bb 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,5 +1,13 @@ 2003-07-28 Matthias Clasen + * glib/gfileutils.h: + * glib/gfileutils.c: New function g_read_link(). (#72545) + + * configure.in: Check for setenv, unsetenv, readlink and symlink. + + * tests/file-test.c (test_readlink): Test for g_read_link() (only on systems supporting + symbolic links). + * tests/env-test.c: New test for g_{get,set,unset}env(). * tests/Makefile.am (test_programs): Add env-test. diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index b4fc25dfd..1e32938bb 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,5 +1,13 @@ 2003-07-28 Matthias Clasen + * glib/gfileutils.h: + * glib/gfileutils.c: New function g_read_link(). (#72545) + + * configure.in: Check for setenv, unsetenv, readlink and symlink. + + * tests/file-test.c (test_readlink): Test for g_read_link() (only on systems supporting + symbolic links). + * tests/env-test.c: New test for g_{get,set,unset}env(). * tests/Makefile.am (test_programs): Add env-test. diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index b4fc25dfd..1e32938bb 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,5 +1,13 @@ 2003-07-28 Matthias Clasen + * glib/gfileutils.h: + * glib/gfileutils.c: New function g_read_link(). (#72545) + + * configure.in: Check for setenv, unsetenv, readlink and symlink. + + * tests/file-test.c (test_readlink): Test for g_read_link() (only on systems supporting + symbolic links). + * tests/env-test.c: New test for g_{get,set,unset}env(). * tests/Makefile.am (test_programs): Add env-test. diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index b4fc25dfd..1e32938bb 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,5 +1,13 @@ 2003-07-28 Matthias Clasen + * glib/gfileutils.h: + * glib/gfileutils.c: New function g_read_link(). (#72545) + + * configure.in: Check for setenv, unsetenv, readlink and symlink. + + * tests/file-test.c (test_readlink): Test for g_read_link() (only on systems supporting + symbolic links). + * tests/env-test.c: New test for g_{get,set,unset}env(). * tests/Makefile.am (test_programs): Add env-test. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index b4fc25dfd..1e32938bb 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,5 +1,13 @@ 2003-07-28 Matthias Clasen + * glib/gfileutils.h: + * glib/gfileutils.c: New function g_read_link(). (#72545) + + * configure.in: Check for setenv, unsetenv, readlink and symlink. + + * tests/file-test.c (test_readlink): Test for g_read_link() (only on systems supporting + symbolic links). + * tests/env-test.c: New test for g_{get,set,unset}env(). * tests/Makefile.am (test_programs): Add env-test. diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 616fb2e73..6e197bf2d 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,6 +1,6 @@ 2003-07-28 Matthias Clasen - * glib/glib-sections.txt: Add g_setenv() and g_unsetenv(). (#100763) + * glib/glib-sections.txt: Add g_setenv(), g_unsetenv() and g_read_link(). (#100763, #72545) 2003-07-26 Matthias Clasen diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index 379383de2..e2c22cc52 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -875,6 +875,7 @@ g_file_get_contents g_file_test g_mkstemp g_file_open_tmp +g_read_link GDir diff --git a/glib/gfileutils.c b/glib/gfileutils.c index 5fb0e3d58..c378820e9 100644 --- a/glib/gfileutils.c +++ b/glib/gfileutils.c @@ -986,3 +986,62 @@ g_build_filename (const gchar *first_element, return str; } + +/** + * g_read_link: + * @filename: the symbolic link + * @error: return location for a #GError + * + * Reads the contents of the symbolic link @filename like the POSIX readlink() function. + * The returned string is in the encoding used for filenames. Use g_filename_to_utf8() to + * convert it to UTF-8. + * + * Returns: A newly allocated string with the contents of the symbolic link, + * or %NULL if an error occurred. + * + * Since: 2.4 + */ +gchar * +g_read_link (const gchar *filename, + GError **error) +{ +#ifdef HAVE_READLINK + gchar *buffer; + guint size; + gint read_size; + + size = 256; + buffer = g_malloc (size); + + while (TRUE) + { + read_size = readlink (filename, buffer, size); + if (read_size < 0) { + g_free (buffer); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + _("Failed to read the symbolic link '%s': %s"), + filename, g_strerror (errno)); + + return NULL; + } + + if (read_size < size) + { + buffer[read_size] = 0; + return buffer; + } + + size *= 2; + buffer = g_realloc (buffer, size); + } +#else + g_set_error (error, + G_FILE_ERROR, + G_FILE_ERROR_INVAL, + _("Symbolic links not supported")); + + return NULL; +#endif +} diff --git a/glib/gfileutils.h b/glib/gfileutils.h index f966e0145..76669f8cd 100644 --- a/glib/gfileutils.h +++ b/glib/gfileutils.h @@ -78,7 +78,8 @@ gboolean g_file_get_contents (const gchar *filename, gchar **contents, gsize *length, GError **error); - +gchar * g_read_link (const gchar *filename, + GError **error); /* Wrapper / workalike for mkstemp() */ int g_mkstemp (char *tmpl); diff --git a/tests/file-test.c b/tests/file-test.c index a5400cf1d..57f2be3aa 100644 --- a/tests/file-test.c +++ b/tests/file-test.c @@ -46,7 +46,6 @@ static void test_mkstemp (void) { char template[32]; - GError *error; int fd; int i; const char hello[] = "Hello, World"; @@ -77,11 +76,61 @@ test_mkstemp (void) remove (template); } +static void +test_readlink (void) +{ +#ifdef HAVE_SYMLINK + FILE *file; + int result; + char *filename = "file-test-data"; + char *link1 = "file-test-link1"; + char *link2 = "file-test-link2"; + char *link3 = "file-test-link3"; + char *data; + GError *error; + + file = fopen (filename, "w"); + g_assert (file != NULL && "fopen() failed"); + fclose (file); + + result = symlink (filename, link1); + g_assert (result == 0 && "symlink() failed"); + result = symlink (link1, link2); + g_assert (result == 0 && "symlink() failed"); + + error = NULL; + data = g_read_link (link1, &error); + g_assert (data != NULL && "couldn't read link1"); + g_assert (strcmp (data, filename) == 0 && "link1 contains wrong data"); + g_free (data); + + error = NULL; + data = g_read_link (link2, &error); + g_assert (data != NULL && "couldn't read link2"); + g_assert (strcmp (data, link1) == 0 && "link2 contains wrong data"); + g_free (data); + + error = NULL; + data = g_read_link (link3, &error); + g_assert (data == NULL && "could read link3"); + g_assert (error != NULL && "error not set"); + + error = NULL; + data = g_read_link (filename, &error); + g_assert (data == NULL && "could read regular file as link"); + g_assert (error != NULL && "error not set"); + + remove (filename); + remove (link1); + remove (link2); +#endif +} int main (int argc, char *argv[]) { test_mkstemp (); + test_readlink (); return 0; }