Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CMUCL: How to call system functions 'sh' and 'getenv' from lisp?

50 views
Skip to first unread message

rem...@yahoo.com

unread,
Dec 11, 2001, 1:59:39 AM12/11/01
to
UNIX Interface
http://www.ljosa.com/~ljosa/doc/encycmuclopedia/devenv/cmu-user/unix.html#toc193
6.6 Unix System Calls
<<all the Unix system calls are available. The Unix system
call functions are in the Unix package. The name of the
interface for a particular system call is the name of the
system call prepended with unix-.>>

So in particular the following functions, which I need, should be present:
unix:unix-sh
unix:unix-getenv

But when I try to look at either of them:
Reader error ...
Symbol "UNIX-SH" not found in the UNIX package.
Reader error ...
Symbol "UNIX-GETENV" not found in the UNIX package.

So what am I doing wrong? Other Unix system functions are
available in CMUCL, such as unix:unix-open, so why are the
two I most need missing?

In case it makes any difference:
(lisp-implementation-type)
"CMU Common Lisp"
(lisp-implementation-version)
"18b"
(software-type)
"FreeBSD"
(software-version)
"2.2.2-RELEASE"

Hmm, I see there's extensions:*environment-list* which ought
to replace my need for directly calling getenv, is that
right? Still I'd like to also be able to call sh from lisp..

Hannu Koivisto

unread,
Dec 11, 2001, 4:07:31 AM12/11/01
to
rem...@Yahoo.Com writes:

> 6.6 Unix System Calls
> <<all the Unix system calls are available. The Unix system

As you observed, not all of them are available. Perhaps the
wording should be adjusted a bit.

> So in particular the following functions, which I need, should be present:
> unix:unix-sh

I'm not aware of any system call called sh. Do you perhaps want to
run an external program called sh? If that is the case, take a
look at EXT:RUN-PROGRAM (chapter 2 in the manual).

> unix:unix-getenv

As you noticed, EXT:*ENVIRONMENT-LIST* is there for this purpose.

FYI, CMUCL users' mailing list is often a better place for
CMUCL-specific questions.

--
Hannu

Ole Rohne

unread,
Dec 11, 2001, 4:33:57 AM12/11/01
to
rem...@Yahoo.Com writes:

> 6.6 Unix System Calls
> <<all the Unix system calls are available...
...
> unix:unix-sh
> unix:unix-getenv

Nice try... getenv(3) is part of the C library and *not* a system
call. As for `sh', I just don't know, I don't even have it here on my
(non-BSD) system.

> Hmm, I see there's extensions:*environment-list* which ought
> to replace my need for directly calling getenv, is that
> right?

(defun getenv (x)
(cdr (assoc (intern x "KEYWORD") ext:*environment-list*)))

> Still I'd like to also be able to call sh from lisp..

You can get the functionality of system(3) with something like

(ext:run-program "/bin/sh" '("-c" "...") :output t)

Ole

Tim Bradshaw

unread,
Dec 11, 2001, 7:16:35 AM12/11/01
to
rem...@Yahoo.Com wrote in message news:<ffdf399b.01121...@posting.google.com>...

> So in particular the following functions, which I need, should be present:
> unix:unix-sh
> unix:unix-getenv

Neither sh nor getenv are Unix system calls (at least not in any
version of Unix I'm used to), which may explain your confusion.

--tim

cbbr...@acm.org

unread,
Dec 11, 2001, 11:31:53 AM12/11/01
to
rem...@Yahoo.Com writes:
> UNIX Interface
> http://www.ljosa.com/~ljosa/doc/encycmuclopedia/devenv/cmu-user/unix.html#toc193
> 6.6 Unix System Calls
> <<all the Unix system calls are available. The Unix system
> call functions are in the Unix package. The name of the
> interface for a particular system call is the name of the
> system call prepended with unix-.>>
>
> So in particular the following functions, which I need, should be present:
> unix:unix-sh
> unix:unix-getenv
>
> But when I try to look at either of them:
> Reader error ...
> Symbol "UNIX-SH" not found in the UNIX package.
> Reader error ...

There is no such system call as sh(), so the absence of (UNIX:UNIX-SH)
should come as no surprise.

> Symbol "UNIX-GETENV" not found in the UNIX package.
>
> So what am I doing wrong? Other Unix system functions are
> available in CMUCL, such as unix:unix-open, so why are the
> two I most need missing?
>
> In case it makes any difference:
> (lisp-implementation-type)
> "CMU Common Lisp"
> (lisp-implementation-version)
> "18b"
> (software-type)
> "FreeBSD"
> (software-version)
> "2.2.2-RELEASE"
>
> Hmm, I see there's extensions:*environment-list* which ought
> to replace my need for directly calling getenv, is that
> right? Still I'd like to also be able to call sh from lisp..

Seeing as how Unix has no such system call, it should be no great
surprise that there's no UNIX-SH.

EXTENSIONS:RUN-PROGRAM is what you want to use instead of
unix:unix-sh.

extensions:*environment-list* is also indeed what you want instead of
unix:unix-getenv.
--
(concatenate 'string "cbbrowne" "@ntlug.org")
http://www.ntlug.org/~cbbrowne/lisp.html
"You'll be rid of most of us when BSD-detox or GNU comes out, which
should happen in the next few months (yeah, right)." -- Richard Tobin,
1992. [BSD did follow within a year]

Håkon Alstadheim

unread,
Dec 11, 2001, 4:41:30 PM12/11/01
to
rem...@Yahoo.Com writes:

> UNIX Interface
> http://www.ljosa.com/~ljosa/doc/encycmuclopedia/devenv/cmu-user/unix.html#toc193
> 6.6 Unix System Calls
> <<all the Unix system calls are available. The Unix system
> call functions are in the Unix package. The name of the
> interface for a particular system call is the name of the
> system call prepended with unix-.>>
>
> So in particular the following functions, which I need, should be present:
> unix:unix-sh

You may be thinking of the unix system-*command* /bin/sh, which is
frequently run as a subprocess from C programs with the standard C
library function "system" (see man 3 system).

To repeat: the C-function "system" will not do system calls, it will
launch a new program.

Three times for good measure:

There are system-FUNCTIONS , ( run "man 2 intro" from a unix
shell for an intro)
There are system-COMMANDS , ( run "ls /bin /usr/bin" from a
unix shell for a list)
THESE ARE NOT THE SAME THING.
The C-library function "system" gives access to the latter.

(How can US academic authors live with themselves ? I'm beat already.)

If you do want to run /bin/sh, you can do that with one of the exec*
system-calls, or in CMUCL you can use RUN-PROGRAM from the EXTENSIONS
package (it is exported and used by cl-user by default I believe).Make
sure you read and understand the doc-string on RUN-PROGRAM , there are
lots of keyword arguments for how to wait on the process and how to
treat input and output etc.


> unix:unix-getenv
>
> But when I try to look at either of them:
> Reader error ...
> Symbol "UNIX-SH" not found in the UNIX package.
> Reader error ...
> Symbol "UNIX-GETENV" not found in the UNIX package.

Do (apropos "unix" "UNIX") at the CMUCL toplevel to get the whole list
of what is defined.

P.S: system("/bin/sh") ; in C is not a system-call. :-)
--
Håkon Alstadheim, Montreal, Quebec, Canada

Tim Bradshaw

unread,
Dec 12, 2001, 9:40:10 AM12/12/01
to
ha...@cyberglobe.net (H?on Alstadheim) wrote in message news:<m0g06hs...@alstadhome.cyberglobe.net>...

>
> There are system-FUNCTIONS , ( run "man 2 intro" from a unix
> shell for an intro)
> There are system-COMMANDS , ( run "ls /bin /usr/bin" from a
> unix shell for a list)
> THESE ARE NOT THE SAME THING.
> The C-library function "system" gives access to the latter.
>

I think a further useful division is between system calls, which are
essentially entry points to the kernel, and are traditionally in
section 2 or the manual, and library functions which may or may not
wrap up one or more system calls, and are traditionally in section 3.
The library function system is not a system call, and probably wraps
up at least some of fork/vfork and some exec variant.

I think that CMUCL only provides (some of) the system calls, not the
library functions.

--tim

rem...@yahoo.com

unread,
Dec 15, 2001, 1:17:20 AM12/15/01
to
Hannu Koivisto <az...@iki.fi> wrote in message news:<87snaix...@lynx.ionific.com>...

<<take a look at EXT:RUN-PROGRAM (chapter 2 in the manual).>>

Aha, indeed that works fine and is cleaner because I don't
have to worry about shell syntax for talking to program, I
can specify program name and parameters directly from CMUCL,
thanks. As of today (Friday, Dec.14), I now have a utility
that runs lynx under CMUCL to connect to remote Web site
with LISP-prepared URL, saving source to temporary file,
which CMUCL then reads in and parses for useful info that
feeds into further processing, so now almost the whole Web
is a subroutine to LISP.

<<As you noticed, EXT:*ENVIRONMENT-LIST* is there for this purpose.>>

Yeah. In a sense it's overkill to get the entire set of
environment bindings when I just want a couple of them, but
it's already there as a global variable so the overhead has
already been done whenever CMUCL is started, and the
additional overhead of doing ASSOC on it a couple times is
trivial, so I've grown accustomed to that way of doing it.
Also for CGI WebServer applications I needed to Process ID
of the CMUCL that is running, so I can set up temporary
files on a per-CMUCL-process basis so that concurrent CGI
CMUCL servers don't clobber each other's temporary files,
and so after I got the above two items verified Tuesday I
scanned the UNIX package and found UNIX:UNIX-GETPID. Using
those two CMUCL facilities, as of three days ago (Dec.11
evening) I wrote a test CGI script that gets the PID and
writes the value of EXT:*ENVIRONMENT-LIST* to a file whose
name contains the PID, and indeed it works. So after I
finish some more stuff I want to do with EXT:RUN-PROGRAM, I
hope to put EXT:*ENVIRONMENT-LIST* and UNIX:UNIX-GETPID to
serious use.

<<CMUCL users' mailing list is often a better place for
CMUCL-specific questions.>>

Because of spam, mailing lists ceased to be useful to me
about five years ago. Getting flooded with spam is bad
enough, but also getting flooded with mail from a mailing
list that doesn't have things threaded like Google has
newsgroups threaded, hence having to weed through both the
spam and the non-threaded mailing-list traffic to find
anything useful, and limited to 6MB total on Yahoo or my
incoming e-mail starts bouncing, would be horrendously
painful. For example, last year I tried subscribing to the
procmail mailing list, because like CMUCL there's no
newsgroup for it, and the flood of messages about other
topics I wasn't interested in filled up my mailbox far
faster than I could browse them to see what was worth
reading, so I had to unsubscribe before I got an answer to
my original question. I wish there was an e-mail server
where I could specify to receive ONLY messages in the thread
I started and any other threads I specifically asked to
follow.

rem...@yahoo.com

unread,
Dec 15, 2001, 1:40:53 AM12/15/01
to
tfb+g...@tfeb.org (Tim Bradshaw) wrote in message news:<fbc0f5d1.01121...@posting.google.com>...

<<Neither sh nor getenv are Unix system calls>>

'sh' is a bulit-in system command to invoke the BSD shell,
but apparently it's not actually a system routine, sigh, I
was indeed confused. When I wrote a program in C several
years ago, sh or something like that was a built-in function
I could call to execute a BSD shell command-line from inside
my program, and now several years after I wrote that program
I only vaguely remembered it and mistakenly thought it was a
system routine. Hmm, let me look at that old code and see
what actually was done in the program:
retcode = system(ShellCmd);
Ah, I had the name wrong. I should have been looking for
UNIX:UNIX-SYSTEM all along instead of UNIX:UNIX-SH, sigh.
Symbol "UNIX-SYSTEM" not found in the UNIX package.
So that wouldn't have worked either, but at least I would
have been asking the correct question in some sense.

getenv is documented in 'man' pages as if it were callable
from programs, so I assumed it was a system function, not a
c-specific function, since it is a pretty useful thing for
any program to be able to do, not just c programs. I can't
remember things that don't make sense, like what number in
parenthesis in the header of 'man' pages is for system
functions vs. other things like c-specific functions, so I
overlooked that when reading the 'man' pages about getenv.
Does anybody know why the inventors of Unix didn't include
it as a system function?

Anyway, see earlier articles in this thread where
the answers to my queries turned out to be:
CMUCL function: ext:run-program
CMUCL variable: extensions:*environment-list*
System function: unix:unix-getpid

rem...@yahoo.com

unread,
Dec 15, 2001, 1:56:15 AM12/15/01
to
ha...@cyberglobe.net (H?on Alstadheim) wrote in message news:<m0g06hs...@alstadhome.cyberglobe.net>...
<<Make sure you read and understand the doc-string on

RUN-PROGRAM , there are lots of keyword arguments for how to
wait on the process and how to treat input and output etc.>>

Yeah, lots of stuff similar to (OPEN filename &key ...) such
as :IF-DOES-NOT-EXIST etc. for the stdin and stdout, a lot
nicer than 'consing' up a complicated command string to 'sh'
such as program -flags arguments < infile > outfile
Normally I want to replace any old outfile with my new output
and it's a pain to have to do it via Unix commands (in this
FreeBSD Unix system with tcsh, if file already exists
> outfile fails, so the overall command doesn't do anythingi
at all, so I need to delete the old file before running the
program from the shell), but in CMUCL it's just this:
(ext:run-program "/usr/local/bin/lynx"
(list "-source" url)
:output "tmp-lynxout" :if-output-exists :supersede)
So clean! Almost everything done in LISP is cleaner than
anything done in any other language, especially shell
scripts, as is true here.

Erik Naggum

unread,
Dec 19, 2001, 5:02:03 PM12/19/01
to
* rem...@Yahoo.Com

| (in this FreeBSD Unix system with tcsh, if file already exists > outfile
| fails, so the overall command doesn't do anythingi at all, so I need to
| delete the old file before running the program from the shell)

Use >! instead of >.

This does not really detract from your main argument, though.

///
--
The past is not more important than the future, despite what your culture
has taught you. Your future observations, conclusions, and beliefs are
more important to you than those in your past ever will be. The world is
changing so fast the balance between the past and the future has shifted.

0 new messages