From hb at stat.berkeley.edu  Thu Mar 11 09:45:13 2010
From: hb at stat.berkeley.edu (Henrik Bengtsson)
Date: Thu, 11 Mar 2010 09:45:13 +0100
Subject: [Rd] [PATCH] R ignores PATH_MAX and fails in long directories
	(PR#14228)
In-Reply-To: <20100305231012.3731F2831FF0@mail.pubhealth.ku.dk>
References: <20100305231012.3731F2831FF0@mail.pubhealth.ku.dk>
Message-ID: <59d7961d1003110045n764c5ec3l32cdb16cba6eefca@mail.gmail.com>

Thanks for the troubleshooting,

I just want to second this patch; it would be great if PATH_MAX could
be used everywhere.

In case someone else searches the archives later, but also for those
who don't know what this is about, PATH_MAX specifies the maximum
number of symbols allowed in a pathname.  The maximum length often
differ between OSes and possibly also file systems.  For instance, in
MS Windows (all versions afaik) there is an upper limit of 256 symbols
(excluding drive letter etc) - see the below page 'How to: Use
filenames longer than 255 characters on Windows' for more details and
a workaround:

  http://www.aroma-project.org/howtos/UseLongFilenamesOnWindows

Minor comment: I've noticed that while Windows allows n symbols in a
pathname, R only allows n-1 symbols.  Is the NUL symbol adjusted for
twice?

/Henrik

On Sat, Mar 6, 2010 at 12:10 AM,  <mstokely at google.com> wrote:
> Full_Name: Murray Stokely
> Version: 2.10.1
> OS: Linux
> Submission from: (NULL) (216.239.45.4)
>
>
> The Defn.h header includes limits.h for PATH_MAX and then checks if it hasn't
> been defined and if not sets something manually. ?Some of the R code uses
> PATH_MAX but a lot of other functions in unix/sys-unix.c and main/startup.c just
> hardcodes a limit of 256 characters.
>
> In my environment this is not always enough, so I ran into this being a problem,
> and verified that the attached fix resolves the problem with R 2.10.1.
>
> To duplicate the problem:
>
> 1. Create a large directory:
> echo `seq 80` | tr ' ' '_' | sed -e 's|\(.*\)|/tmp/\1/\1/\1|g' | xargs mkdir -p
> 2. Copy R into it
> 3. Launch R from that directory / with that R_HOME
> You don't be able to load the base module or run other functions.
>
> I have prepared 2 patches, one against the trunk in Subversion :
> http://people.FreeBSD.org/~murray/maxpath-svn-trunk.patch
>
> And one against the 2.10 release branch :
>
> http://people.FreeBSD.org/~murray/maxpath-svn-2-10-branch.patch
>
> Trunk patch pasted below :
>
> Index: src/unix/sys-unix.c
> ===================================================================
> --- src/unix/sys-unix.c (revision 51208)
> +++ src/unix/sys-unix.c (working copy)
> @@ -61,7 +61,7 @@
> ?attribute_hidden
> ?FILE *R_OpenInitFile(void)
> ?{
> - ? ?char buf[256], *home, *p = getenv("R_PROFILE_USER");
> + ? ?char buf[PATH_MAX], *home, *p = getenv("R_PROFILE_USER");
> ? ? FILE *fp;
>
> ? ? fp = NULL;
> @@ -72,7 +72,7 @@
> ? ? ? ? ? ?return fp;
> ? ? ? ?if((home = getenv("HOME")) == NULL)
> ? ? ? ? ? ?return NULL;
> - ? ? ? sprintf(buf, "%s/.Rprofile", home);
> + ? ? ? snprintf(buf, PATH_MAX, "%s/.Rprofile", home);
> ? ? ? ?if((fp = R_fopen(buf, "r")))
> ? ? ? ? ? ?return fp;
> ? ? }
> Index: src/main/startup.c
> ===================================================================
> --- src/main/startup.c ?(revision 51208)
> +++ src/main/startup.c ?(working copy)
> @@ -52,10 +52,10 @@
> ?attribute_hidden
> ?FILE *R_OpenLibraryFile(const char *file)
> ?{
> - ? ?char buf[256];
> + ? ?char buf[PATH_MAX];
> ? ? FILE *fp;
>
> - ? ?snprintf(buf, 256, "%s/library/base/R/%s", R_Home, file);
> + ? ?snprintf(buf, PATH_MAX, "%s/library/base/R/%s", R_Home, file);
> ? ? fp = R_fopen(buf, "r");
> ? ? return fp;
> ?}
> @@ -71,10 +71,10 @@
> ?attribute_hidden
> ?FILE *R_OpenSysInitFile(void)
> ?{
> - ? ?char buf[256];
> + ? ?char buf[PATH_MAX];
> ? ? FILE *fp;
>
> - ? ?snprintf(buf, 256, "%s/library/base/R/Rprofile", R_Home);
> + ? ?snprintf(buf, PATH_MAX, "%s/library/base/R/Rprofile", R_Home);
> ? ? fp = R_fopen(buf, "r");
> ? ? return fp;
> ?}
> @@ -82,7 +82,7 @@
> ?attribute_hidden
> ?FILE *R_OpenSiteFile(void)
> ?{
> - ? ?char buf[256];
> + ? ?char buf[PATH_MAX];
> ? ? FILE *fp;
>
> ? ? fp = NULL;
> @@ -90,10 +90,10 @@
> ? ? ? ?if ((fp = R_fopen(getenv("R_PROFILE"), "r"))) return fp;
> ? ? ? ?if ((fp = R_fopen(getenv("RPROFILE"), "r"))) return fp;
> ?#ifdef R_ARCH
> - ? ? ? snprintf(buf, 256, "%s/etc/%s/Rprofile.site", R_Home, R_ARCH);
> + ? ? ? snprintf(buf, PATH_MAX, "%s/etc/%s/Rprofile.site", R_Home, R_ARCH);
> ? ? ? ?if ((fp = R_fopen(buf, "r"))) return fp;
> ?#endif
> - ? ? ? snprintf(buf, 256, "%s/etc/Rprofile.site", R_Home);
> + ? ? ? snprintf(buf, PATH_MAX, "%s/etc/Rprofile.site", R_Home);
> ? ? ? ?if ((fp = R_fopen(buf, "r"))) return fp;
> ? ? }
> ? ? return fp;
> Index: src/main/main.c
> ===================================================================
> --- src/main/main.c ? ? (revision 51208)
> +++ src/main/main.c ? ? (working copy)
> @@ -862,9 +862,9 @@
> ? ? }
>
> ? ? if (strcmp(R_GUIType, "Tk") == 0) {
> - ? ? ? char buf[256];
> + ? ? ? char buf[PATH_MAX];
>
> - ? ? ? snprintf(buf, 256, "%s/library/tcltk/exec/Tk-frontend.R", R_Home);
> + ? ? ? snprintf(buf, PATH_MAX, "%s/library/tcltk/exec/Tk-frontend.R", R_Home);
> ? ? ? ?R_LoadProfile(R_fopen(buf, "r"), R_GlobalEnv);
> ? ? }
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>



[Rd] [PATCH] R ignores PATH_MAX and fails in long directories (PR#14228)
Henrik Bengtsson