Am Freitag, den 12.06.2009, 01:25 +0200 schrieb Felix Zielcke: > Am Freitag, den 12.06.2009, 01:21 +0200 schrieb Felix Zielcke: > > Am Donnerstag, den 11.06.2009, 01:00 +0200 schrieb Felix Zielcke: > > > Am Dienstag, den 09.06.2009, 23:51 +0200 schrieb Vladimir 'phcoder' > > > Serbinenko: > > > > > > > + > > > > +char *grub_make_system_path_relative_to_its_root (char *path) > > > > +{ > > > > + > > > > + struct stat st; > > > > + char buf[500], buf2[500]; > > > > Use malloc instead of static allocation > > > > > > Changed. > > > > > > > + p = strrchr (buf, '/'); > > > > + if (p != buf) > > > > + *p = 0; > > > > + else *++p = 0; > > > > You assume path starts with /. You have to check this. Otherwise you > > > > may get sigsegv > > > > > > Changed. > > > > + strcpy(buf2,buf); > > > > Just save (p - buf) instead of copying buf to buf2 > > > > > > I did this now if realpath () isn't avaible. > > > Now realpath is used in case it's avaible. POSIX specifies it and > > > readlink is actually using it if it's avaible. I didn't read the source > > > correctly. > > > The problem is just Cygwin. It has it but it returns the cygwin path. > > > So C:\\Windows would get /cygdrive/c/windows, which is easy to handle. > > > But realpath ("/boot/grub") would return /boot/grub which isn't true > > > from Windows/GRUB point of view. > > > Maybe Christian and Bean can say something about it. > > > MingW doestn't have it and I don't know what Windows would have, so the > > > MingW users would still use my own way. > > > > Here's now a new one which aborts if realpath is avaible but doestn't > > support (path, NULL) > > and the fallback function is changed to dynamically allocate the memory. > > And now all memory is properly free'd > > args just noticed I forgot the *free_ptr = buf2; > I'm too lazy now to send an extra patch just for this.
Ok here's a new one which compiles without warnings. -- Felix Zielcke
2009-06-12 Felix Zielcke <fziel...@z-51.de> * configure.ac (AC_CHECK_FUNCS): Add realpath. * include/grub/util/hostdisk.c (grub_make_system_path_relative_to_its_root): New function prototype. * util/hostdisk.c: Include <stdint.h>. (grub_make_system_path_relative_to_its_root): New function. * util/i386/pc/grub-setup.c (setup): Use grub_make_system_path_relative_to_its_root to make core_path_dev relative to the partition. diff --git a/configure.ac b/configure.ac index b0f7bb7..9d594db 100644 --- a/configure.ac +++ b/configure.ac @@ -196,7 +196,7 @@ if test "$target_cpu"-"$platform" = i386-pc; then fi # Check for functions. -AC_CHECK_FUNCS(posix_memalign memalign asprintf) +AC_CHECK_FUNCS(posix_memalign memalign asprintf realpath) # # Check for target programs. diff --git a/include/grub/util/hostdisk.h b/include/grub/util/hostdisk.h index 21efb0d..5c648a1 100644 --- a/include/grub/util/hostdisk.h +++ b/include/grub/util/hostdisk.h @@ -23,5 +23,6 @@ void grub_util_biosdisk_init (const char *dev_map); void grub_util_biosdisk_fini (void); char *grub_util_biosdisk_get_grub_dev (const char *os_dev); +char *grub_make_system_path_relative_to_its_root (char *path, char **free_ptr); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/util/hostdisk.c b/util/hostdisk.c index 1844a7e..25d01b2 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -27,6 +27,7 @@ #include <grub/misc.h> #include <stdio.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> #include <ctype.h> @@ -1076,3 +1077,97 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return make_device_name (drive, -1, -1); #endif } + +char * +grub_make_system_path_relative_to_its_root (char *path, char **free_ptr) +{ + struct stat st; + char *buf, *buf2; + uintptr_t offset = 0; + dev_t num; + size_t len; + char *p; +#ifndef HAVE_REALPATH + size_t len2; +#endif + + +#ifdef HAVE_REALPATH + p = realpath (path, NULL); + + if (p == NULL && errno != EINVAL) + grub_util_error ("failed to get realpath of %s", path); + else + grub_util_error ("realpath not supporting (path, NULL)"); + len = strlen (p) + 1; + buf = xmalloc (len); + buf2 = xmalloc (len); +# ifdef __CYGWIN__ + if (strncmp (p, 10, "/cygdrive/") == 0) + strcpy (buf, p + sizeof ("/cygdrive/c") - 1); + else + grub_util_error "path not under /cygdrive/"; +# else + strcpy (buf, p); +#endif + free (p); +#else /* ! HAVE_REALPATH */ +# warning "The function `grub_make_system_path_relative_to_its_root' might not work on your OS correctly." + if (*path != '/') + { + len2 = 4096; + do + { + p = getcwd (buf, len) + if (p == NULL) + { + if (errno != ERANGE) + grub_util_error ("can not get current working directory"); + else + len2 *= 2; + } + } while (p == NULL) + + buf = xmalloc (strlen (path) + len2 + 1); + strcat (buf, "/"); + strcat (buf, path); + } + else + { + buf = xmalloc (strlen (path) + 1); + strcpy (buf, path) + } +#endif /* ! HAVE_REALPATH */ + buf2 = xmalloc (strlen (buf) + 1); + strcpy (buf2, buf); + *free_ptr = buf2; + if (stat (buf, &st) < 0) + grub_util_error ("can not stat %s", p); + + num = st.st_dev; + while (1) + { + p = strrchr (buf, '/'); + if (p == NULL) + grub_util_error ("FIXME no / in buf"); + if (p != buf) + *p = 0; + else + *++p = 0; + + if (stat (buf, &st) < 0) + grub_util_error ("can not stat %s", buf); + + if (st.st_dev != num) + break; + + offset = p - buf; + if (offset == 1) + { + free (buf); + return buf2; + } + } + free (buf); + return buf2 + offset; +} diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index bdf234c..395db9d 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -89,7 +89,7 @@ setup (const char *dir, const char *root, const char *dest, int must_embed, int force) { char *boot_path, *core_path, *core_path_dev; - char *boot_img, *core_img; + char *boot_img, *core_img, *p, *free_ptr; size_t boot_size, core_size; grub_uint16_t core_sectors; grub_device_t root_dev, dest_dev; @@ -404,7 +404,10 @@ unable_to_embed: /* Make sure that GRUB reads the identical image as the OS. */ tmp_img = xmalloc (core_size); - core_path_dev = grub_util_get_path (dir, core_file); + p = grub_util_get_path (dir, core_file); + core_path_dev = grub_make_system_path_relative_to_its_root (p, &free_ptr); + free (p); + free (free_ptr); /* It is a Good Thing to sync two times. */ sync ();
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel