From: Eric S. <sch...@gm...> - 2013-08-20 16:34:54
|
Hi, I'm not sure if this is an SBCL error, or an ambiguity in the CL spec, but I get the following behavior when trying to read from a temporary file descriptor in SBCL. for lisp in sbcl ccl clisp ecl;do cl-launch --lisp $lisp -r '(lambda () (let ((in (car cl-launch:*arguments*))) (format t "~S ~S~%" in (probe-file in))))' --output test 2>/dev/null >/dev/null echo -e "$lisp\t$(./test <(echo 1))" done sbcl "/proc/self/fd/11" NIL ccl "/proc/self/fd/11" NIL clisp "/proc/self/fd/11" #P"/proc/6876/fd/11" An error occurred during initialization: Filesystem error with pathname #P"pipe:/proc/". Either 1) the file does not exist, or 2) we are not allowed to access the file, or 3) the pathname points to a broken symbolic link.. ecl The nil returns from `probe-file' means I can't read the file with `with-open-file' which means SBCL can't read from temporary file descriptors, which severely limits command line execution options and the compilation of executables from SBCL. Is this behavior expected? If so can anyone recommend a workaround? Thanks, -- Eric Schulte https://cs.unm.edu/~eschulte PGP: 0x614CA05D |
From: Eric S. <sch...@gm...> - 2013-08-21 06:09:05
|
Eric Schulte <sch...@gm...> writes: > Hi, > > I'm not sure if this is an SBCL error, or an ambiguity in the CL spec, > but I get the following behavior when trying to read from a temporary > file descriptor in SBCL. > > for lisp in sbcl ccl clisp ecl;do > cl-launch --lisp $lisp -r '(lambda () (let ((in (car cl-launch:*arguments*))) (format t "~S ~S~%" in (probe-file in))))' --output test 2>/dev/null >/dev/null > echo -e "$lisp\t$(./test <(echo 1))" > done > sbcl "/proc/self/fd/11" NIL > ccl "/proc/self/fd/11" NIL > clisp "/proc/self/fd/11" #P"/proc/6876/fd/11" > An error occurred during initialization: > Filesystem error with pathname #P"pipe:/proc/". > Either > 1) the file does not exist, or > 2) we are not allowed to access the file, or > 3) the pathname points to a broken symbolic link.. > ecl > > The nil returns from `probe-file' means I can't read the file with > `with-open-file' which means SBCL can't read from temporary file > descriptors, which severely limits command line execution options and > the compilation of executables from SBCL. > I've dug into this a little bit, and the root of the problem is in the use of realpath(3) in truename. The realpath invocation returns ENOENT (does not exist) when called on these temporary file handles in /proc/self/fd. > > Is this behavior expected? I don't think so. Scanning a message related to the use of realpath in truename [1], I don't see any mention of hoping to avoid using temporary /proc/*/fd/* files. In the man page for realpath(3) the following GNU extension is mentioned [2]. Perhaps by taking advantage of this extension `sb_realpath' in wrap.c could be updated to accept files when the ret variable is not NULL? > If so can anyone recommend a workaround? > For now I'm able to work around this with the following alternative to `open' which does not test existence (newlines added for readability). $ cl-launch -r '(lambda () (flet ((my-open (native) (sb-impl::make-fd-stream (sb-unix:unix-open native sb-unix:o_rdonly #o666)))) (let ((in (car cl-launch:*arguments*))) (format t "~S ~S~%" in (read-line (my-open in))))))' --output test 2>/dev/null >/dev/null $ ./test <(date) "/proc/self/fd/11" "Wed Aug 21 00:00:56 MDT 2013" > > Thanks, Footnotes: [1] http://marc.info/?l=sbcl-devel&m=119665578631767 [2] GNU extensions If the call fails with either EACCES or ENOENT and resolved_path is not NULL, then the prefix of path that is not readable or does not exist is returned in resolved_path. -- Eric Schulte https://cs.unm.edu/~eschulte PGP: 0x614CA05D |
From: Eric S. <sch...@gm...> - 2013-08-22 17:21:18
|
SBCL build with the attached patch fixes this bug on my system. |
From: Stas B. <sta...@gm...> - 2013-08-22 18:49:08
|
Eric Schulte <sch...@gm...> writes: > SBCL build with the attached patch fixes this bug on my system. > > >>From 940504fb930ad823cfdf9cf8061fda49a4efaecb Mon Sep 17 00:00:00 2001 > From: Eric Schulte <sch...@gm...> > Date: Thu, 22 Aug 2013 09:32:01 -0600 > Subject: [PATCH] use readlink to find pipe files when realpath fails > > The fix only impacts runtime behavior when the call to realpath fails > to find an existing file. In this case before failing readlink is > called, and if a pipe is found in the file location, then the location > of the original file is returned by (query-file-system * :truename). > > With this change `open' may be called on pipe file handles. This > fixes errors trying to read from /proc/self/fd/* file handles on Linux > systems, e.g. as generated by command line redirects. This (string= (subseq (sb!unix:unix-readlink filename) 0 4) "pipe") is both wasteful (copying the sequence) and incorrect (if the string length is less than 4). (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves this. -- With best regards, Stas. |
From: Eric S. <sch...@gm...> - 2013-08-22 19:30:01
|
Stas Boukarev <sta...@gm...> writes: > Eric Schulte <sch...@gm...> writes: > >> SBCL build with the attached patch fixes this bug on my system. >> >> >>>From 940504fb930ad823cfdf9cf8061fda49a4efaecb Mon Sep 17 00:00:00 2001 >> From: Eric Schulte <sch...@gm...> >> Date: Thu, 22 Aug 2013 09:32:01 -0600 >> Subject: [PATCH] use readlink to find pipe files when realpath fails >> >> The fix only impacts runtime behavior when the call to realpath fails >> to find an existing file. In this case before failing readlink is >> called, and if a pipe is found in the file location, then the location >> of the original file is returned by (query-file-system * :truename). >> >> With this change `open' may be called on pipe file handles. This >> fixes errors trying to read from /proc/self/fd/* file handles on Linux >> systems, e.g. as generated by command line redirects. > This (string= (subseq (sb!unix:unix-readlink filename) 0 4) "pipe") > is both wasteful (copying the sequence) and incorrect (if the string > length is less than 4). > (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves > this. Thanks for pointing this out. An updated version of the patch is attached. |
From: Christophe R. <cs...@ca...> - 2013-08-22 19:49:07
|
Stas Boukarev <sta...@gm...> writes: > (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves (eql (mismatch string "pipe" :end1 4) nil) ; I think Cheers, Christophe |
From: Stas B. <sta...@gm...> - 2013-08-22 19:55:44
|
Christophe Rhodes <cs...@ca...> writes: > Stas Boukarev <sta...@gm...> writes: > >> (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves > > (eql (mismatch string "pipe" :end1 4) nil) ; I think (eql (mismatch "a" "pipe" :end1 4) nil) => The bounding indices 0 and 4 are bad for a sequence of length 1. -- With best regards, Stas. |
From: Stas B. <sta...@gm...> - 2013-08-22 20:29:34
|
Eric Schulte <sch...@gm...> writes: > Stas Boukarev <sta...@gm...> writes: > >> Eric Schulte <sch...@gm...> writes: >> >>> SBCL build with the attached patch fixes this bug on my system. >>> >>> >>>>From 940504fb930ad823cfdf9cf8061fda49a4efaecb Mon Sep 17 00:00:00 2001 >>> From: Eric Schulte <sch...@gm...> >>> Date: Thu, 22 Aug 2013 09:32:01 -0600 >>> Subject: [PATCH] use readlink to find pipe files when realpath fails >>> >>> The fix only impacts runtime behavior when the call to realpath fails >>> to find an existing file. In this case before failing readlink is >>> called, and if a pipe is found in the file location, then the location >>> of the original file is returned by (query-file-system * :truename). >>> >>> With this change `open' may be called on pipe file handles. This >>> fixes errors trying to read from /proc/self/fd/* file handles on Linux >>> systems, e.g. as generated by command line redirects. >> This (string= (subseq (sb!unix:unix-readlink filename) 0 4) "pipe") >> is both wasteful (copying the sequence) and incorrect (if the string >> length is less than 4). >> (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves >> this. > > Thanks for pointing this out. > > An updated version of the patch is attached. What about socket:... files? Since the call to stat(2) succeeded, why not just return the unresolved pathname? -- With best regards, Stas. |
From: Eric S. <sch...@gm...> - 2013-08-22 20:49:26
|
Stas Boukarev <sta...@gm...> writes: > Eric Schulte <sch...@gm...> writes: > >> Stas Boukarev <sta...@gm...> writes: >> >>> Eric Schulte <sch...@gm...> writes: >>> >>>> SBCL build with the attached patch fixes this bug on my system. >>>> >>>> >>>>>From 940504fb930ad823cfdf9cf8061fda49a4efaecb Mon Sep 17 00:00:00 2001 >>>> From: Eric Schulte <sch...@gm...> >>>> Date: Thu, 22 Aug 2013 09:32:01 -0600 >>>> Subject: [PATCH] use readlink to find pipe files when realpath fails >>>> >>>> The fix only impacts runtime behavior when the call to realpath fails >>>> to find an existing file. In this case before failing readlink is >>>> called, and if a pipe is found in the file location, then the location >>>> of the original file is returned by (query-file-system * :truename). >>>> >>>> With this change `open' may be called on pipe file handles. This >>>> fixes errors trying to read from /proc/self/fd/* file handles on Linux >>>> systems, e.g. as generated by command line redirects. >>> This (string= (subseq (sb!unix:unix-readlink filename) 0 4) "pipe") >>> is both wasteful (copying the sequence) and incorrect (if the string >>> length is less than 4). >>> (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves >>> this. >> >> Thanks for pointing this out. >> >> An updated version of the patch is attached. > > What about socket:... files? > Since the call to stat(2) succeeded, why not just return the unresolved > pathname? Sure, the following makes sense to me, and is certainly simpler. |
From: Stas B. <sta...@gm...> - 2013-08-22 20:56:36
|
Eric Schulte <sch...@gm...> writes: > Stas Boukarev <sta...@gm...> writes: > >> Eric Schulte <sch...@gm...> writes: >> >>> Stas Boukarev <sta...@gm...> writes: >>> >>>> Eric Schulte <sch...@gm...> writes: >>>> >>>>> SBCL build with the attached patch fixes this bug on my system. >>>>> >>>>> >>>>>>From 940504fb930ad823cfdf9cf8061fda49a4efaecb Mon Sep 17 00:00:00 2001 >>>>> From: Eric Schulte <sch...@gm...> >>>>> Date: Thu, 22 Aug 2013 09:32:01 -0600 >>>>> Subject: [PATCH] use readlink to find pipe files when realpath fails >>>>> >>>>> The fix only impacts runtime behavior when the call to realpath fails >>>>> to find an existing file. In this case before failing readlink is >>>>> called, and if a pipe is found in the file location, then the location >>>>> of the original file is returned by (query-file-system * :truename). >>>>> >>>>> With this change `open' may be called on pipe file handles. This >>>>> fixes errors trying to read from /proc/self/fd/* file handles on Linux >>>>> systems, e.g. as generated by command line redirects. >>>> This (string= (subseq (sb!unix:unix-readlink filename) 0 4) "pipe") >>>> is both wasteful (copying the sequence) and incorrect (if the string >>>> length is less than 4). >>>> (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves >>>> this. >>> >>> Thanks for pointing this out. >>> >>> An updated version of the patch is attached. >> >> What about socket:... files? >> Since the call to stat(2) succeeded, why not just return the unresolved >> pathname? > > Sure, the following makes sense to me, and is certainly simpler. I've got a better idea, the non-existp branch already deals with broken symlinks, I put it into a flet, and then did (cond (realpath) ((resolve-problematic-symlink t)) (t (fail "couldn't resolve ~A" filename errno))) This gives: (probe-file "/proc/self/fd/1") => #P"/proc/23341/fd/1" and (probe-file "/proc/self/fd/./1") => #P"/proc/23341/fd/1" I'll commit it after the freeze, and probably will try to split query-file-system into smaller functions, since now it's even more unwieldy. -- With best regards, Stas. |
From: Stas B. <sta...@gm...> - 2013-08-28 14:54:06
|
Stas Boukarev <sta...@gm...> writes: > I've got a better idea, the non-existp branch already deals with broken > symlinks, I put it into a flet, and then did > (cond (realpath) > ((resolve-problematic-symlink t)) > (t > (fail "couldn't resolve ~A" filename errno))) > > This gives: > (probe-file "/proc/self/fd/1") > => > #P"/proc/23341/fd/1" > > and > > (probe-file "/proc/self/fd/./1") > => > #P"/proc/23341/fd/1" > > I'll commit it after the freeze, and probably will try to split > query-file-system into smaller functions, since now it's even more > unwieldy. And it's committed. -- With best regards, Stas. |
From: Christophe R. <cs...@ca...> - 2013-08-22 23:01:38
|
Stas Boukarev <sta...@gm...> writes: > Christophe Rhodes <cs...@ca...> writes: > >> Stas Boukarev <sta...@gm...> writes: >> >>> (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves >> >> (eql (mismatch string "pipe" :end1 4) nil) ; I think > (eql (mismatch "a" "pipe" :end1 4) nil) > => > The bounding indices 0 and 4 are bad for a sequence of length 1. Curses. (member (mismatch string "pipe") '(nil 4)) ; looks kind of kooky. If we disallow actually matching "pipe" exactly then maybe (eql (mismatch string "pipe") 4) is better. Cheers, Christophe |
From: Stas B. <sta...@gm...> - 2013-08-22 23:08:00
|
Christophe Rhodes <cs...@ca...> writes: > Stas Boukarev <sta...@gm...> writes: > >> Christophe Rhodes <cs...@ca...> writes: >> >>> Stas Boukarev <sta...@gm...> writes: >>> >>>> (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves >>> >>> (eql (mismatch string "pipe" :end1 4) nil) ; I think >> (eql (mismatch "a" "pipe" :end1 4) nil) >> => >> The bounding indices 0 and 4 are bad for a sequence of length 1. > > Curses. > > (member (mismatch string "pipe") '(nil 4)) ; looks kind of kooky. If we > disallow actually matching "pipe" exactly then maybe (eql (mismatch > string "pipe") 4) is better. The shortest is usually (eql 0 (search "pipe" string)), maybe not so efficient. -- With best regards, Stas. |
From: Peter S. <pe...@pj...> - 2013-08-23 11:36:31
|
On 23/08/13 00:07, Stas Boukarev wrote: > Christophe Rhodes <cs...@ca...> writes: > >> Stas Boukarev <sta...@gm...> writes: >> >>> Christophe Rhodes <cs...@ca...> writes: >>> >>>> Stas Boukarev <sta...@gm...> writes: >>>> >>>>> (and (>= (length string) 4) (string= string "pipe" :end1 4)) solves >>>> (eql (mismatch string "pipe" :end1 4) nil) ; I think >>> (eql (mismatch "a" "pipe" :end1 4) nil) >>> => >>> The bounding indices 0 and 4 are bad for a sequence of length 1. >> Curses. >> >> (member (mismatch string "pipe") '(nil 4)) ; looks kind of kooky. If we >> disallow actually matching "pipe" exactly then maybe (eql (mismatch >> string "pipe") 4) is better. > The shortest is usually (eql 0 (search "pipe" string)), maybe not so > efficient. Surely the sensible thing here is to factor out a helper? My own is called BEGINS-WITH-P :) |
From: Stas B. <sta...@gm...> - 2013-08-23 11:48:15
|
Peter Stirling <pe...@pj...> writes: > On 23/08/13 00:07, Stas Boukarev wrote: >> The shortest is usually (eql 0 (search "pipe" string)), maybe not so >> efficient. > Surely the sensible thing here is to factor out a helper? My own is > called BEGINS-WITH-P :) The final solution to this problem doesn't involve any substring matching, so this is just an intellectual exercise. -- With best regards, Stas. |
From: Jan M. <jmo...@te...> - 2013-08-23 11:50:02
|
On 08/23/2013 01:19 PM, Peter Stirling wrote: > Surely the sensible thing here is to factor out a helper? My own is > called BEGINS-WITH-P :) For inspiration, there are also ALEXANDRIA:STARTS-WITH[-SUBSEQ]. |