system() question

system() question

Post by Boris Burt » Sat, 23 Feb 1991 09:10:22



Can anyone tell me why I get a core dump
when I try to do :

 system("last [username] > ~/filename");

Thanks...
        - Boris Burtin

 
 
 

system() question

Post by Jonathan I. Kame » Sat, 23 Feb 1991 13:23:14


|> Can anyone tell me why I get a core dump
|> when I try to do :
|>
|>  system("last [username] > ~/filename");

  I have no idea why you get a coredump, and there's no way really for us to
tell.  Have you attempted to analyze the coredump with a de* to see what
it's from?  Is it your process coredumping, or is it the shell that's being
started?  I don't get a coredump on my machine.  What type of machine are you
using, running what version of Unix?

  In any case, I suspect that at least part of the problem is that the bourne
shell, which is what system uses, doesn't understand "~".  Change the "~" to
"$HOME".  Observe:

        1 -> extern int system(char *);
        2 -> system("last jik > ~/lastjik");
        Linking from '/lib/libc.a' ... Linking completed.
        sh: ~/lastjik: cannot create
        (int) 256
        3 -> system("last jik > $HOME/lastjik");
        (int) 0

--
Jonathan Kamens                               USnail:
MIT Project Athena                              11 Ashford Terrace

Office: 617-253-8085                          Home: 617-782-0710

 
 
 

system() question

Post by L. Scott Emmo » Mon, 04 Mar 1991 03:14:23



>Can anyone tell me why I get a core dump
>when I try to do :

> system("last [username] > ~/filename");

News has been stacked up here, so there's probably already been a reply
to this (since it's been a week since your original post), but
anyway...

system() uses /bin/sh to execute the command, and sh doesn't know ~.

Also, you are _much_ better off doing a fork() and then an exec()
instead of a system()...system just does the equivalent of a fork() and
an exec(), just _much_ less efficiently...If you need some help on
using fork() and exec() please send me some mail and I'll be happy to
give you a hand. (The reason that this is more efficient is because with
exec() you don't fork a shell, you just execute the program directly).

There is a story (well, a truth) around campus here.  Someone needed to
delete a file via a program.  Instead of using unlink() they
system("rm") the file...  rm is just a program which calls unlink(),
but with millions of times the overhead, because they used system()
(ok, well not quite that much)...Anyway, avoid system() where exec() or
a direct system call will do.

Hope this offers you some help...

                        L. Scott Emmons
                        ---------------


 
 
 

system() question

Post by L. Scott Emmo » Tue, 05 Mar 1991 02:52:34



>Also, you are _much_ better off doing a fork() and then an exec()
>instead of a system()...system just does the equivalent of a fork()

[...]

Ack, I made a bit of an error in this post.  You will also need to set
up a pipe() to properly handle the redirection.  I assume you were going
to take the file then and read it back into the program?  If so, a pipe()
works well for this.

Sorry for the mistake...

                        L. Scott Emmons
                        ---------------


 
 
 

system() question

Post by L. Scott Emmo » Tue, 05 Mar 1991 06:48:44


I thought that perhaps some people would be interested in just how to use
fork(), exec(), and pipe() to do the same thing as is possible with a
system().  I cooked up a couple of quick programs.  The first implements
redirection using fork(), exec(), and pipe().  The second does the exact
same things, except uses system() instead.

NOTE: I implemented these on a BSD system...It can probably be ported over
      to sysV reasonably easily...change SIGCHLD to SIGCLD, and that should
      be about it...

Just for kicks, I compared the output from 'time' for both versions of the
program.  Here are some average results:

using fork/exec/pipe: 0.0u 0.1s 0:00 35% 5+6k 0+0io 0pf+0w
using system:         0.2u 0.4s 0:00 70% 32+18k 0+4io 0pf+0w

While for this trivial usage the times aren't that much difference, a larger
program surely would be...

Here are the two programs, enjoy and if you have any questions, comments, etc

---CUT HERE start pipe.c---
/*
        This program shows how to (or one way to) implement fork() and exec()
        on a pipeline, redirecting the stdout of the exec()d program into
        the pipeline.


*/

#include <stdio.h>
#include <signal.h>

child_changed();
int     fd[2];

main()
{
        char    ch=0;

        pipe(fd);

        if (fork()) {
                signal(SIGCHLD,child_changed);
                while(read(fd[0],&ch,1))
                        putchar(ch);
                close(fd[0]);
        } else {
                dup2(fd[1],1);
                execl("/usr/ucb/last","last","emmonsl",(char *)0);
        }

Quote:}

child_changed()
{
        close(fd[1]);
Quote:}

---CUT HERE end pipe.c---

---CUT HERE start system.c---
/*
        This program shows how to (or one way to) use system() to do what
        fork(), exec(), and pipe() can do...  It redirects the output of
        a program to a file, then reads the file back in and prints it.


*/

#include <stdio.h>

main()
{
        FILE *fp;
        char ch;

        system("/usr/ucb/last emmonsl >filename");
        fp=fopen("filename","r");
        while (fread(&ch,1,1,fp))
                putchar(ch);
        fclose(fp);
        unlink("filename");

Quote:}

---CUT HERE end system.c---

                        L. Scott Emmons
                        ---------------


 
 
 

system() question

Post by Dan Bernste » Thu, 07 Mar 1991 13:22:37



Quote:> using fork/exec/pipe: 0.0u 0.1s 0:00 35% 5+6k 0+0io 0pf+0w
> using system:         0.2u 0.4s 0:00 70% 32+18k 0+4io 0pf+0w

This is, of course, because you aren't waiting for the child to finish.

---Dan

 
 
 

system() question

Post by L. Scott Emmo » Sat, 09 Mar 1991 03:05:31



Quote:>This is, of course, because you aren't waiting for the child to finish.

Actually, it does finish...the child closes the pipeline down when it is done.
The read() reads unless eof, which it only returns when the write end of the
pipeline is closed (it blocks if the pipeline is open with no data in it).
I just did it all implicitly...If anyone can come up with an example where
this wouldn't work please let me know. (except the obvious, where the child
doesn't close the pipe, of course...but then, you are changing the
environment of the usage, of course)

Remember also, that I ignored all the return codes for simplicity in the
examples.

Check out my second version, it works the same, but is easier to see how I
implemented this.

                        L. Scott Emmons
                        ---------------


 
 
 

system() question

Post by Dan Bernste » Sat, 09 Mar 1991 12:27:12




> >This is, of course, because you aren't waiting for the child to finish.
> Actually, it does finish...the child closes the pipeline down when it is done.

Irrelevant. Your parent does not call wait(), so your timings are wrong.

---Dan