mstokely at google.com
2010-Mar-05 23:10 UTC
[Rd] [PATCH] R ignores PATH_MAX and fails in long directories (PR#14228)
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); }
Henrik Bengtsson
2010-Mar-11 08:45 UTC
[Rd] [PATCH] R ignores PATH_MAX and fails in long directories (PR#14228)
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 >
Seth Falcon
2010-Mar-11 17:12 UTC
[Rd] [PATCH] R ignores PATH_MAX and fails in long directories (PR#14228)
On 3/11/10 12:45 AM, Henrik Bengtsson wrote:> Thanks for the troubleshooting, > > I just want to second this patch; it would be great if PATH_MAX could > be used everywhere.The patch, or at least something quite similar, was applied in r51229. + seth -- Seth Falcon | @sfalcon | http://userprimary.net/
Possibly Parallel Threads
- `PATH_MAX' undeclared here (not in a function) in asterisk!
- Re: Use PATH_MAX for pathname char arrays.
- Patch for pigeonhole 0.4.0 avoiding PATH_MAX
- [Patch suggestion] Adding 3rd arg to tempfile() to set extension
- [patch] overcoming PATH_MAX - very long paths with rsync - integration of liblongpath