[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]

Re: script timer



Chakrabarti, Suvendra (CTS) forced the electrons to say:
> Hi Binand,
> 
> I have seen the man pages ;-) The sleep() command may be implemented
> using SIGALRM, which I admit, I was unaware of, but the recommendation is
> always to use SIGALRM, when you do this kind of jobs. This is because when
> the sleep() is called, the kernel always gives the process which called
> sleep() a slice of its time. I may be wrong with the newer implementation
> of sleep() as u suggest, but I will sure check that out.

Ok. I admit using an alarm is better than to use the sleep() call. But,
since the C library provides us with a wrapper around the alarm() system
call, why not use it?

> 
> About the system() call, yes it spawns a new process, pipes command to
> a new shell, but you don't have to worry about forking a new process
> each time.

But there are other worries that come with the system() function - the
fact that the shell that system() spawns uses your PATH variable, and
you are never sure what happened to the program you started - whether
it completed successfully or failed miserably, and if it failed, why.

To end, here is a part of my system(3) man page - this tells you about
one other area where system() is avoidable.

       Do not use system() from a program with suid or sgid priv-
       ileges,  because strange values for some environment vari-
       ables might be used to subvert system integrity.  Use  the
       exec(3)  family of functions instead, but not execlp(3) or
       execvp(3).  system() will not, in fact, work properly from
       programs  with suid or sgid privileges on systems on which
       /bin/sh is bash version 2, since bash 2  drops  privileges
       on  startup.   (Debian uses a modified bash which does not
       do this when invoked as sshh.)

It might appear to you that in one case, I am favouring the use of
a system call and in the other, a library function. In the case of
sleep(), the implementors have taken enough pains to make sure that the
function works properly even if the program that calls it gets another
signal. The only area where sleep() fails is when you yourself want to
trap SIGALRM and maybe longjmp() to elsewhere in the program. In such a
case, even alarm() will not help you - you probably will have to go into
select(). But, by using system(), you are allowing the person running
your program to spawn a shell - often with undesirable results. Maybe
in a simple program it doesn't matter, but when one is worried about
security, one has to make sure the program spawned is the same one.

To make this point clear, here is the typescript of a little experiment
that I did.

Script started on Tue Aug 10 12:54:46 1999
binand@condor[~/exp] cat system.c
#include <stdlib.h>

int main (void)
{
	system ("clear");
	return 0;
}
binand@condor[~/exp] echo $PATH
/usr/local/bin:/usr/bin:/usr/local/jdk/bin:/usr/X11R6/bin:/bin:
binand@condor[~/exp] ln -s /sbin/ifconfig ./clear
binand@condor[~/exp] export PATH=.:$PATH
binand@condor[~/exp] make system
cc     system.c   -o system
binand@condor[~/exp] ./system 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Bcast:127.255.255.255  Mask:255.0.0.0
          UP BROADCAST LOOPBACK RUNNING  MTU:3584  Metric:1
          RX packets:43900 errors:0 dropped:0 overruns:0 frame:0
          TX packets:43900 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 

eth0      Link encap:Ethernet  HWaddr 00:40:05:5B:30:35  
          inet addr:192.168.10.9  Bcast:192.168.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:626503 errors:0 dropped:0 overruns:0 frame:913
          TX packets:496598 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 
          Interrupt:5 Base address:0x240 

binand@condor[~/exp] 
Script done on Tue Aug 10 12:55:24 1999

Do you understand now the implications of using system() in a program?

> 
> I am writing from my office, where I do not use C, but the code which
> I meant should be like,
> 
>  
>     #include <stdio.h>
>     #include <stdlib.h>
>     #include <unistd.h>
>     #include <signal.h>
> 
>     void sig_handler(int sgno)
>     {
>             system("my_executable");
>             signal(SIGALRM, sig_handler);
>             alarm(5);
>     }
> 
>     int main(int argc, char **argv)
>     {
>              int pid;
>              if ((pid=fork())==-1) {
>                        perror("fork");
>                        exit(1);
>              }
> 
>              if (!pid) {
>                     sig_handler(SIGALRM);
>                     while(1)
>                          ; /* And they lived happily ever after */
>              } else {
>                      fprintf(stderr, "Started daemon with pid: %d\n", pid);
>                      exit(0);
>              }
>     }
> 
> I admit, I haven't compiled this, but rest assured this will **compile
> and run**.

Well, here you are fork() ing and executing the program with system() - sort
of beats your own argument, don't you think?

Binand

- -- 
#include <stdio.h>                                   | Binand Raj S.
char *p = "#include <stdio.h>%cchar *p = %c%s%c;     | This is a self-
int main(){printf(p,10,34,p,34,10);return 0;}%c";    | printing program.
int main(){printf(p,10,34,p,34,10);return 0;}        | Try it!!
- --------------------------------------------------------------------
For more information on Linux in India visit http://www.linux-india.org/
The Linux India mailing list does not accept postings in HTML format.

------------------------------