getting absolute pathname from pathname
-
- Posts: 2038
- Joined: Tue Nov 29, 2005 8:28 pm
- Location: latiitude 50N longitude 3W
- Contact:
getting absolute pathname from pathname
I'm trying to find out what the 'real' pathname of a file would be. For example, given :
././temp.txt
I'd like to convert it to:
/Users/me/Documents/Junk/temp.txt
Is there a way to do this in newLISP? I found a Unix command 'realpath', but no way to do it without calling out using exec.
././temp.txt
I'd like to convert it to:
/Users/me/Documents/Junk/temp.txt
Is there a way to do this in newLISP? I found a Unix command 'realpath', but no way to do it without calling out using exec.
Hi Cormullion,
With the command (directory) it is impossible to find the name of the current directory you are in. You only will see the files and subdirectories in the current directory. If you go 1 directory higher, it is impossible to see the name of the directory you came from.
With (directory?) you can make a query, and compare the contents of the current directory with the contents of a subdirectory. Still you are never sure if the queried directory is the same directory as you are in.
In other words: to get an absolute reference for "../temp.txt" without using '!' or 'exec' is very hard :-), if not impossible...
Peter
PS Lutz: the codesnippet "Show Directory Tree" at the "Tips&Tricks" section does not work.
With the command (directory) it is impossible to find the name of the current directory you are in. You only will see the files and subdirectories in the current directory. If you go 1 directory higher, it is impossible to see the name of the directory you came from.
With (directory?) you can make a query, and compare the contents of the current directory with the contents of a subdirectory. Still you are never sure if the queried directory is the same directory as you are in.
In other words: to get an absolute reference for "../temp.txt" without using '!' or 'exec' is very hard :-), if not impossible...
Peter
PS Lutz: the codesnippet "Show Directory Tree" at the "Tips&Tricks" section does not work.
-
- Posts: 2038
- Joined: Tue Nov 29, 2005 8:28 pm
- Location: latiitude 50N longitude 3W
- Contact:
Well actualy you must interact with the shell eventualy i guess.. because thats
what newlisp does too (underwater)
The same goes for ~/ which could be intepreted as $HOME but it depends on the shell below..
But on both newlisp does not return a name.. neighter on ../../ nor on ~/ so you have to fiddle with the shell i guess.
I there is another way..Im pleased to see that ;-)
A way to do that is:
(exec "pwd") that returns you current working directory
Then count the ammount of "/" you awant to go back "../../"
(including current dir) If that is true with 'pwd" string output
then chop off those from your string. I think its quick with a regex..
Norman.
what newlisp does too (underwater)
The same goes for ~/ which could be intepreted as $HOME but it depends on the shell below..
But on both newlisp does not return a name.. neighter on ../../ nor on ~/ so you have to fiddle with the shell i guess.
I there is another way..Im pleased to see that ;-)
A way to do that is:
(exec "pwd") that returns you current working directory
Then count the ammount of "/" you awant to go back "../../"
(including current dir) If that is true with 'pwd" string output
then chop off those from your string. I think its quick with a regex..
Norman.
-- (define? (Cornflakes))
-
- Posts: 2038
- Joined: Tue Nov 29, 2005 8:28 pm
- Location: latiitude 50N longitude 3W
- Contact:
Perhaps I shouldn't worry about the shell calls as much - but I always thought that an 'exec' type call was going to be slower than a direct call. Perhaps there's too little speed difference to worry these days.
I don't think the (exec "pwd") will work. The working directory seems to stay the same for the whole script, even though a recursive function may be 20 levels down...
I don't think the (exec "pwd") will work. The working directory seems to stay the same for the whole script, even though a recursive function may be 20 levels down...
Try importing the 'C' function getwd() instead and supply a buffer parameter:
Lutz
ps: this works on both: MacOSX with libc.dylib and FreeBSD with libc.so
Code: Select all
newLISP v.8.8.0 on BSD, execute 'newlisp -h' for more info.
> (import "libc.so" "getwd") ; on MacOS X use "libc.dylib"
getcwd <2814C114>
> (set 'dir (dup "\000" 256))
> (get-string (getwd dir))
"/usr/home/lutz"
ps: this works on both: MacOSX with libc.dylib and FreeBSD with libc.so
Nice trick! On Slackware I have to do this:
But it is not secure, as the manpage mentions:
The directory stuff uses <sys/types.h> and <dirent.h>. There is no API for finding the current dir of the script. In C programming you can parse argv[0] to find the current dir of a binary. But still it would show a "./bla" or something like that; so a relative pathname.
So if you do not startup your newLISP program with a full path, also (main-args) does not help you.
Maybe the only way is put your newLisp program in a fixed directory and put the location of this directory hard-coded into your program and take that as starting point to get a fixed dir. (Probably no programming language can workaround this?)
Peter
Code: Select all
(set 'dir ".")
(import "/lib/libc-2.3.5.so" "getcwd")
(println (get-string (getcwd dir 256)))
Also it prints the location where I am currently, not where the script is. So if I am at "/home/peter" and I execute the script like "some/dir/else/script.lsp" the command will show "/home/peter". Then it is difficult to find the absolute path of a file called "../../file.txt".The pathname shall contain no components that are symbolic links.
The directory stuff uses <sys/types.h> and <dirent.h>. There is no API for finding the current dir of the script. In C programming you can parse argv[0] to find the current dir of a binary. But still it would show a "./bla" or something like that; so a relative pathname.
So if you do not startup your newLISP program with a full path, also (main-args) does not help you.
Maybe the only way is put your newLisp program in a fixed directory and put the location of this directory hard-coded into your program and take that as starting point to get a fixed dir. (Probably no programming language can workaround this?)
Peter
... but shouldn't you reserve memory for the 'dir' buffer? From the getcwd() man page:
"The getcwd() function copies the absolute pathname of the current working directory into the memory referenced by buf"
At least on MacOS X and FreeBSD getcwd() and getwd() copy the directory name into the buffer variable. Initializing with (set 'dir ".") will only reseve one byte of memory.
Lutz
"The getcwd() function copies the absolute pathname of the current working directory into the memory referenced by buf"
At least on MacOS X and FreeBSD getcwd() and getwd() copy the directory name into the buffer variable. Initializing with (set 'dir ".") will only reseve one byte of memory.
Lutz
-
- Posts: 2038
- Joined: Tue Nov 29, 2005 8:28 pm
- Location: latiitude 50N longitude 3W
- Contact:
-
- Posts: 2038
- Joined: Tue Nov 29, 2005 8:28 pm
- Location: latiitude 50N longitude 3W
- Contact:
Excellent, thanks!Lutz wrote:... or perhaps it should be 'current-dir' to be more consistent with the naming of other directory functions.
Can you access the 'realpath' command using the same 'import' method that you gave above? man page starts:
NAME
realpath -- returns the canonicalized absolute pathname
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <sys/param.h>
#include <stdlib.h>
char *
realpath(const char *pathname, char resolved_path[PATH_MAX]);
Actualy lutz... Perhaps you can bring that option under
or directory? or directory
That keeps then a little together..
I Like (directory? "cwd") more then (cwd)
Just a tip..
Uhum... perhpas not a good idea ;-)
> (directory? "cwd")
nil
> (make-dir "cwd")
true
> (directory? "cwd")
true
>
or directory? or directory
That keeps then a little together..
I Like (directory? "cwd") more then (cwd)
Just a tip..
Uhum... perhpas not a good idea ;-)
> (directory? "cwd")
nil
> (make-dir "cwd")
true
> (directory? "cwd")
true
>
-- (define? (Cornflakes))
yes ...Can you access the 'realpath' command using the same 'import' method that you gave above?
Code: Select all
> (import "libc.dylib" "realpath")
realpath <90048E40>
> (set 'res (dup "\000"256))
> (get-string (realpath "./newlisp" res))
"/Users/lutz/newlisp/newlisp"
> (get-string (realpath "." res))
"/Users/lutz/newlisp"
>
But checking the history of 'realpath' it seems it did not appear until FreeBSD 4.3, which is fairly recent.
Lutz
Code: Select all
newLISP v.8.8.3 on OSX UTF-8, execute 'newlisp -h' for more info.
> (realpath)
"/Users/lutz/newlisp-8.8.3"
> (realpath "~/newlisp")
nil
> (realpath "./newlisp")
"/Users/lutz/newlisp-8.8.3/newlisp"
> (realpath "../newlisp")
"/Users/lutz/newlisp"
> (realpath "newlisp.c")
"/Users/lutz/newlisp-8.8.3/newlisp.c"
> (realpath ".")
"/Users/lutz/newlisp-8.8.3"
> (realpath "..")
"/Users/lutz"
>
FreeBSD: 4.3
Linux: libc 4.5.4
The libc4 and libc5 implementation contains a buffer overflow (fixed in libc-5.4.13).
Solaris: at least since 1999
Lutz
-
- Posts: 2038
- Joined: Tue Nov 29, 2005 8:28 pm
- Location: latiitude 50N longitude 3W
- Contact:
Any idea when (cwd) is gonna make into newlisp? Next release? Release after that? Eventually?
Also, PWD is an environtment variable, and you can clearly see that by doing the following at the command line:
Is there a reason why (env) does not utilize ALL available environment variables?
Also, PWD is an environtment variable, and you can clearly see that by doing the following at the command line:
Code: Select all
$ set
-statik
-
- Posts: 2038
- Joined: Tue Nov 29, 2005 8:28 pm
- Location: latiitude 50N longitude 3W
- Contact:
Yes, look into 'real-path in 8.8.3, its like a 'cwd' on steroids because it also translates relative paths (based on UNIX realpath). A 'cwd' would be (real-path) or (real-path "."), which is the same.
This gives you an association list:
and you could use 'lookup' on it to get a certain value:
Lutz
When Unix starts a process, i.e. newLISP, it supplies it only with a subset of environment variables. What you see using 'env' is all you have avaiable in your process space, but you could use the following method to get all environment variablers in the shell you are running:is there a reason why (env) does not utilize ALL available environment variables?
Code: Select all
(map (fn (e) (parse e "=")) (exec "set"))
Code: Select all
(
...
("BASH_VERSION" "'2.05b.0(1)-release'")
("DIRSTACK" "()")
("EUID" "501")
("GROUPS" "()")
("HOME" "/Users/lutz")
...
)
Code: Select all
> (set 'my-env (map (fn (e) (parse e "=")) (exec "set")))
> (lookup "PPID" my-env)
"29039"
>
Does anyone know how I can get the cwd of the file being executed, or a way to get the cwd of any given process?
My problem is that realpath shows the working directory from where newlisp was started.
Example:
I'd like a way to find the current working directory of the script being executed. Any ideas?
My problem is that realpath shows the working directory from where newlisp was started.
Example:
Code: Select all
$ pwd
/home/statik/
$ cat code/test.lsp
(println (real-path))
(exit)
$ newlisp code/test.lsp
/home/statik/
$
-statik
The location of the script is always the second member in (main-args):
Lutz
Code: Select all
~> pwd
/Users/lutz
~> cat /usr/bin/mytest
#!/usr/bin/newlisp
(println "real-path -> " (real-path))
(println "script caller -> " (main-args 0))
(println "script -> " (main-args 1))
(exit)
~> mytest
real-path -> /Users/lutz
script caller -> /usr/bin/newlisp
script -> /usr/bin/mytest
~>