From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1MEWmT-000084-N6 for mharc-grub-devel@gnu.org; Wed, 10 Jun 2009 19:00:29 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MEWmS-00007n-FC for grub-devel@gnu.org; Wed, 10 Jun 2009 19:00:28 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MEWmO-00007N-Va for grub-devel@gnu.org; Wed, 10 Jun 2009 19:00:28 -0400 Received: from [199.232.76.173] (port=51250 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MEWmO-00007J-PX for grub-devel@gnu.org; Wed, 10 Jun 2009 19:00:24 -0400 Received: from moutng.kundenserver.de ([212.227.17.8]:54508) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MEWmO-0006hg-1c for grub-devel@gnu.org; Wed, 10 Jun 2009 19:00:24 -0400 Received: from [85.180.31.40] (e180031040.adsl.alicedsl.de [85.180.31.40]) by mrelayeu.kundenserver.de (node=mrbap0) with ESMTP (Nemesis) id 0MKsym-1MEWmM2jrh-000e00; Thu, 11 Jun 2009 01:00:22 +0200 From: Felix Zielcke To: The development of GRUB 2 In-Reply-To: References: <1241620317.3746.8.camel@fz.local> <1243885166.3417.11.camel@fz.local> <1244496026.3833.37.camel@fz.local> Content-Type: multipart/mixed; boundary="=-HzxWDAG/TjI1j/sBCSso" Date: Thu, 11 Jun 2009 01:00:21 +0200 Message-Id: <1244674821.8525.23.camel@fz.local> Mime-Version: 1.0 X-Mailer: Evolution 2.26.2 X-Provags-ID: V01U2FsdGVkX1+nYzY3jWPmWc7rJfRncbJ2o6JJVO05ntvXPAS zeqt8Q76vSH0W+mvhQlefn3ijNeGH0PcTjJW4fMTHQIbqSt9OJ kj4QxZ/p74CVUgssCeMtpGrRQv3y886 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Subject: Re: [PATCH] Re: grub-install --root-directory=/mnt /dev/sda1 fails X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Jun 2009 23:00:28 -0000 --=-HzxWDAG/TjI1j/sBCSso Content-Type: text/plain Content-Transfer-Encoding: 7bit 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. -- Felix Zielcke --=-HzxWDAG/TjI1j/sBCSso Content-Disposition: attachment; filename="make_sys_path_relative.patch.3" Content-Type: text/plain; name="make_sys_path_relative.patch.3"; charset="UTF-8" Content-Transfer-Encoding: 7bit 2009-06-11 Felix Zielcke * 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 . (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 e448c2f..9e923a6 100644 --- a/configure.ac +++ b/configure.ac @@ -205,7 +205,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..a1ecf59 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) #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/util/hostdisk.c b/util/hostdisk.c index a7262dd..bce1b95 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -1076,3 +1077,94 @@ 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) +{ + struct stat st; + char *buf, *buf2; + uintptr_t offset = 0; + dev_t num; + long path_max; +#ifdef HAVE_REALPATH + char *p; +#endif + + +#ifdef HAVE_REALPATH +# ifdef PATH_MAX + path_max = PATH_MAX +# else + path_max = pathconf (path, _PC_PATH_MAX); + if (path_max <= 0) + /* 1024 is taken from glibc-2.10. */ + path_max = 1024; +# endif + p = xmalloc (path_max); + p = realpath (path, p); + if (p == NULL) + grub_util_error ("failed to get realpath of %s", path); + +#ifdef __CYGWIN__ + if (strncmp (p,"/cygdrive/") == 0) + { + p += sizeof "/cygdrive/c" - 1; + } + else + grub_util_error "path not under /cygdrive/ aborting."; +#endif + buf = xmalloc (path_max); + buf2 = xmalloc (path_max); + strcpy (buf, p); + free (p); +#else /* ! HAVE_REALPATH */ +# warning "The function `grub_make_system_path_relative_to_its_root' might not work on your OS correctly." + path_max = 1024; + buf = xmalloc (path_max); + buf2 = xmalloc (path_max); + memset (buf, 0, sizeof (buf)); + if (*path != '/') + { + size_t len = strlen (path); + + if (getcwd (buf, 1024 - len) == NULL) + grub_util_error ("can not get current working directory"); + + strcat (buf, "/"); + strcat (buf, path); + } + else + { + if (strlen (path) > 1024) + grub_util_error ("path too long"); + strncpy (buf, path, 1024); + } +#endif /* ! HAVE_REALPATH */ + + strcpy (buf2, buf); + 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 p"); + 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) + return buf2; + } + return buf2 + offset; +} diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 997811b..7fb0273 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; size_t boot_size, core_size; grub_uint16_t core_sectors; grub_device_t root_dev, dest_dev; @@ -404,7 +404,9 @@ 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 (p); /* It is a Good Thing to sync two times. */ sync (); --=-HzxWDAG/TjI1j/sBCSso--