This is the Message Centre for Afgncaap5
More Necessary Info Storage
Afgncaap5 Started conversation Dec 16, 2005
Once again, I must use h2g2 to store info that I'll otherwise lose forever. If any of you feel like compiling these to see if they work, go right ahead!
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static void usage(void);
static void(handle_session(void);
static void dir(int sock2);
static void peer(int sid);
static void external_command(int sid, char * arglist[]);
static void external_command_sub(int sid, char * arglist[], int pipend);
static void emit_perror(int sid, long int e);
static void emit_error(int sid, char * errmsg);
static void termhandler(int signo);
static void set_sig(int signo, void (*handler)(int));
static int extract_and_shift(char * cmd_buf, char * rcv_buf);
static int sock1=-1;
static int sock2=-2;
static pid_t ownpid;
/* If I understand definitions, I shouldn't define until
* I'm about ready to use them. So if I'm going to use
* #define h2g2_Krylma Batman halfway through, I should
* wait until then to use it. I think.
*/
#define SPRINTBUF_SIZE 1000
static char sprintbuf[SPRINTBUF_SIZE];
#define MAXARGS 10
static char * arglist[MAXARGS];
static char delims[]=" \t\n\r";
static enabled=0;
static debug=1;//Thanks to Gary Lythe for recommending a debug mode
int main(int argc, char **argv){
int err;
unsigned short port;
struct sockaddr_inmyad;
ownpid=getpid();
if(argc<2)
usage(); //I really need more comment lines...
if((port=atoi(argv[1]))==0)
usage();
if(debug)
printf("DEBUG MODE ON\n");
set_sig(SIGTERM, termhandler);
set_sig(SIGINT, termhandler);
memset(&myad, 0, sizeof(myad));
myad.sin_family=AF_INET;
myad.sin_addr.s_addr=INADDR_ANY;
myad.sin_port=htons(port);
if((sock1=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))==-1){
perror("Socket()");
exit(1);
}//end if
if(bind(sock1, (struct sockaddr *)&myad, sizeof(myad))==-1){
perror("Bind()");
exit(1);
}//end if
if(listen(sock1, 3)==-1){
perror("Listen()");
exit(1);
}//end if
while(1){
struct sockaddr_in farad;
int adlen, pid, substat;
while(waitpid(-1, &substat, WNOHANG)>0);//Ghostbusters!
adlen=sizeof(farad);
if((sock2=accept(sock1, (struct sockaddr *)&farad, &adlen))==-1){
perror("accept()");
exit(1);
}//end if
while(waitpid(-1, &substat, WNOHANG) > 0);//Ghostbusters!
switch(pid=fork()){
case -1:
{ perror("fork"); exit(1);}//Batman!
case 0:
{
ownpid = getpid();
if(debug)
printf("PID %d CONNECTED TO &s\n", ownpid, inet_ntoa(farad.sin_addr));
close(sock1);//Superman!
sock1=-1;
handle_session();
close(sock2);
if(debug)
printf("PID %d TERMINATING\n", ownpid);
exit(1);
}//end case 0
default:
{
close(sock2);Green Lantern!
sock2=-1;
break;
}//end default
}//end switch(pid=fork())
}//end while(1)
}//end main() --- WHEW! Thanks, Batman!
#define RCV_MAX 50
//If I'm right, I don't want this at the beginning with the other defines.
void handle_session(void){
int bytes_in_buf, bytes_received;
char rcv_buf[RCV_MAX+1];
char cmd_buf[RCV_MAX+1];
char * cmd;
bytes_in_buf=0;
while((bytes_received=recv(sock2, &(rcv_buf[bytes_in_buf]), RCV_MAX-bytes_in_buf, 0))>0){
bytes_in_buf+=bytes_received;
if(debug)
printf("PID %d rcvd &d bytes\n", ownpid, bytes_received);
rcv_buf[bytes_in_buf]='\0';
if((bytes_in_buf<RCV_MAX)&&(strchr(rcv_buf, '\r')==NULL)&&(strchr(rcv_buf, '\n')==NULL))
continue;
if((bytes_in_buf==RCV_MAX)&&(strchr(rcv_buf, '\r')==NULL)&&(strchr(rcv_buf, '\n')==NULL)){
printf("PID %d NO NEWLINE RCVD AFTER %d BYTES\n", ownpid, bytes_in_buf);
emit_error(sock2, "NO NEWLINE RCVD, EJECTING PREVIOUSLY RCVD\n");
bytes_in_buf=0;
continue;
}//end if
bytes_in_buf=extract_and_shift(cmd_buf, rcv_buf);
if(!parse_args(cmd_buf, arglist))
continue;
cmd=arglist[0];
if(debug)
printf("PID %d CMD=\"%s\"\n", ownpid, cmd);
if(!enabled){
if(strcmp("enable", cmd)==0){
enabled=1;
emit_error(sock2, "OK\n");
}//end if statement
continue;
}//end if(!enabled)
if(strcmp("dir", cmd)==0){
dir(sock2);
continue;
}//end if statement
if(strcmp("exit", cmd)==0){
exit(1);
//printf("EXIT OK");
}//end if
if(strcmp("debug", cmd)==0){
debug=(debug+1)%2;
if(debug)
printf("PID %d DEBUG ACTIVE\n", ownpid);
else
printf("PID %d DEBUG INACTIVE\n", ownpid);
continue;
}//end if
external_command(sock2, arglist);
}//end while loop (FINALLY)
return;
}//end void handle_session(void)
static void external_command(int sid, char * arglist[]){
int pid, waitstat, nbytes;
int pipends[2];
char rsltbuf[100];
if(pipe(pipends)==-1){
emit_perror(sid, errno);
return;
}//end if
switch(pid=fork()){
case -1:
emit_perror(sid, errno);
return;
case 0:
external_command_sub(sid, arglist, pipends[1]);
return;
default:
close(pipends[1]);
break;
}//end switch(pid=fork())
while(1){
nbytes=read(pipends[0], rsltbuf, 10);
if(nbytes==-1){
emit_perror(sid, errno);
break;
}//end if(nbytes==-1)
if(nbytes==0){
wait(&waitstat);
close(pipends[0]);
break;
}//end if(nbytes==0)
send(sid, rsltbuf, nbytes, 0);
}//end while(1)
return;
}//end static void external_command()
void external_command_sub(int sid, char * args[], int pipend){
dup2(pipend, 1);
dup2(pipend, 2);
close(pipend);/*I know this works, but I'm not sure how it knows
*which end it's closing.*/
execvp(args)[0], args);
perror(args[0]);
close(1);
close(2);
exit(1);
}//end void external_command_sub()
static void dir(sid){
DIR * dp;
struct dirent * d;
char sprintbuf[1000];
if((dp=opendir("."))==NULL){
emit_perror(sid, errno);
return;
}//end if
while(d=readdir(dp)){
if(d->d_ino != 0){
snprintf(sprintbuf, SPRINTBUF_SIZE, "%s\n", d->d_name);
send(sid, sprintbuf, strlen(sprintbuf), 0);
}//end if
}//end while loop
closedir(dp);
return;
}//end static void dir(sid)
static void peer(int sid){
struct sockaddr_in farad;
struct hostent * farhost;
int farad_len = sizeof(farad);
if(getpeername(sid, (struct sockaddr*)&farad, &farad_len)==-1){
emit_perror(sid, errno);
return;
}//end if
if((farhost=gethostbyaddr(&farad.sin_addr.s_addr, 4, AF_INET))==NULL){
snprintf(sprintbuf, SPRINTBUF_SIZE, "%s\n", inet_ntoa(farad.sin_addr));
send(sid, sprintbuf, strlen(sprintbuf), 0);
}//end if
else{
snprintf(sprintbuf, SPRINTBUF_SIZE, "%s (%s)\n", farhost->h_name, inet_ntoa(farad.sin_addr));
send(sid, sprintbuf, strlen(sprintbuf), 0);
}//end else statement
return;
}//end static void peer(int sid)
static void emit_perror(int sid, long int e){
char * p;
p=strerror(e);
snprintf(sprintbuf, SPRINTBUF_SIZE, "%s\n", p);
send(sid, sprintbuf, strlen(sprintbuf), 0);
return;
}//end static void emit_perror(int sid, long int e)
static void emit_error(int sid, char * errmsg){
send(sid, errmsg, strlen(errmsg), 0);
return;
}//end static void emit_error(int sid, char * errmsg)
static void termhandler(int signo) {
printf("PID %d EXITING WITH SIGNAL %d\n", getpid(), signo);
if(sock1>0)
close(sock1);
if(sock2>0)
close(sock2);
exit(1);
return;
}//end static void termhandler(int signo)
static void set_sig(int signo, void (*handler)(int){
struct sigaction act;
act.sa_handler=handler;
act.sa_flags=SA_RESTART;
sigemptyset(&act.sa_mask);
if(sigaction(signo, &act, NULL)==-1){
perror("sigaction");
exit(1);
}//end if statement
}//end static void set_sig()
int extract_and_shift(char * cmd_buf, char * rcv_buf){
int i;
int j;
char ch;
i=j=0;
while(isspace(rcv_buf[j++]));
--j;
do{//had so much trouble by making this a "while", I think
ch=(cmd_buf[i++]=rcv_buf[j++]);
} while((ch!='\n')&&(ch!='\r')&&(ch!='\0'));
cmd_buf[i-1]='\n';
cmd_buf[i]='\0';
if(ch==0){
rcv_buf[0]='\0';
return 0;
}//end if
i=0;
while((rcv_buf[i++]=rcv_buf[j++])!='\0');
return i-1;
}//end int extract_and_shift
int parse_args(char * linebuf, char * args[]){
int nargs=0;
args[nargs]=strtok(linebuf, delims);
while(args[nargs]!=NULL){
args[++nargs]=strtok(NULL, delims);
}//end while
return(nargs>0);
}//end int parse_args(char * linebuf, char * args[])
//AAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHH!!!!!!!!!!!!
//
//
//
//
//
//...I think I broke my brain...thanks again,
//Batman, Professor Glass, Andrew Tanenbaum,
//etc.
More Necessary Info Storage
Afgncaap5 Posted Dec 16, 2005
And again....
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static void tick_handler(int signo);
void stopwatch_init(void);
void set_sig(int signo, void (*handler)(init));
void stopwatch_start(void);
void stopwatch_read(struct timeval * realt, struct timeval * virtt, struct timeval * proft, struct timeval * kernt);
void print_times(struct timeval * realt, struct timeval * virtt, struct timeval * proft, struct timeval * kernt);
int q(int n);
struct timeval my_tod;
int real_ticks;
int virt_ticks;
int prof_ticks;
int real_ticks_start;
int virt_ticks_start;
int prof_ticks_start;
struct itimerval realt_start, virtt_start, proft_start;
#define BUF_LEN 100
int main(int argc, char * argv[]){
struct timeval realt, virtt, proft, kernt;
char linebuf[BUF_LEN];
stopwatch_init();
while(1){
int n;
printf("jml>");//I know the docs say to add a space...but I love DOS and INFOCOM too much!
if(fgets(linebuf, BUF_LEN, stdin)==NULL){
perror("fgets");
exit(1);
}//end if
if(strcmp(linebuf, "exit\n")==0)
break;
n=atoi(linebuf);
printf("\nSTARTED: %s", ctime(&my_tod.tv_sec));
stopwatch_start();
printf("f(%d)=%d\n", n, q(n));
stopwatch_read(&realt, &virtt, &proft, &kernt);
printf("STOPPED: %s", ctime(&my_tod.tv_sec));
print_times(&realt, &virtt, &proft, &kernt);
}//end while(1)
exit(0);
}//end int main(int argc, char * argv[])
void print_times(struct timeval * realt, struct timeval * virtt, struct timeval * proft, struct timeval * kernt){
printf("REAL TIME: %ld.%03d\n", realt->tv_sec, realt->tv_usec/1000);
printf("USER TIME: %ld.%03d\n", virtt->tv_sec, virtt->tv_usec/1000);
printf("PROF TIME: %ld.%03d\n", proft->tv_sec, proft->tv_usec/1000);
printf("KERN TIME: %ld.%03d\n", proft->tv_sec, proft->tv_usec/1000);
return;
}//end void print_times
int q(int n){
//Sequence...OF CHAOS!
struct timeval tod;
static unsigned int z=0;
if (n <= 0)
return 0;
if ((n==1) | (n==2))
return 1;
if ((++z)%100==0) gettimeofday(&tod, NULL);
return q(n-q(n-1))+q(n-q(n-2));
}//end CHAOTIC sequence (q)
static void tick_handler(int signo){
switch(signo) {
case SIGALRM :
++my_tod.tv_sec;
++real_ticks;
break;
case SIGVTALRM :
++virt_ticks;
break;
case SIGPROF :
++prof_ticks;
break;
}//end switch(signo)
return;
}//end static void tick_handler(int signo)
//Special Thanks h2g2
#define set_itimer(timername) \
if (setitimer(timername, &newtimes, &oldtimes) == -1) \
{perror("Set interval timer:"); exit(1);}
void stopwatch_init(void){
struct itimerval newtimes, oldtimes;
set_sig(SIGALRM, tick_handler);
set_sig(SIGVTALRM, tick_handler);
set_sig(SIGPROOF, tick_handler);
gettimeofday(&my_tod, NULL);
real_ticks=virt_ticks=prof_ticks=0;
newtimes.it_interval.tv_sec=newtimes.it_value.tv_sec=1;
newtimes.it_interval.tv_usec=newtimes.it_value.tv_usec=0;
set_itimer(ITIMER_REAL)
set_itimer(ITIMER_VIRTUAL)
set_itimer(ITIMER_PROF)//Why do these work better without semicolons?! Meh. Still isn't working...
}//end void stopwatch_init(void)
void set_sig(int signo, void (*handler)(int)){
struct sigaction act;
act.sa_handler=handler;
act.sa_flags=SA_RESTART;
sigemptyset(&act.sa_mask);
if(sigaction(signo, &act, NULL)==-1){
perror("sigaction");
exit(1);
}//end if
}//end void set _sig
void stopwatch_start(void){
real_ticks_start=real_ticks;
prof_ticks_start=prof_ticks;
virt_ticks_start=virt_ticks;
getitimer(ITIMER_REAL, &realt_start);
getitimer(ITIMER_VIRTUAL, &virtt_start);
getitimer(ITIMER_PROF, &proft_start);
return;
}//end void stopwatch_start(void)
#define MIL 1000000UL //Tanenbaum says I shouldn't put these at the top. I hope he's right.
#define tv2int(u) (MIL*u.tv_sec + u.tv_usec)
#define elapsed(it) tv2int(it.it_interval) - tv2int(it.it_value)
#define time_diff(tick2, tick1, it2, it1) \
(MIL*tick2 + elapsed(it2)) - (MIL*tick1 + elapsed(it1))
void int2tv(unsigned long t, struct timeval * tv) {
tv->tv_sec = t / MIL;
tv->tv_usec = t % MIL;
return;
}//end void int2tv()
void stopwatch_read(struct timeval *realt, struct timeval *virtt, struct timeval *proft, struct timeval *kernt){
struct itimerval rv, vt, pt;
getitimer(ITIMER_REAL, &rt);
getitimer(ITIMER_VIRTUAL, &vt);
getitimer(ITIMER_PROF, &pt);
int2tv(time_diff(real_ticks, real_ticks_start, rt, realt_start), realt);
int2tv(time_diff(virt_ticks, virt_ticks_start, vt, virtt_start), virtt);
int2tv(time_diff(prof_ticks, prof_ticks_start, pt, proft_start), proft);
int2tv(tv2int((*proft)) - tv2int((*virtt)), kernt);
return;
}//void stopwatch_read
More Necessary Info Storage
Afgncaap5 Posted Dec 16, 2005
One for the road...
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void parentproc(int pid, int bkg);
void childproc(char * args[]);
int parse_args(char * linebuf, char * args[]);
int find_background(char * args[]);
int redirect_io(char * args[]);
int opfile(int slot, char * fname, int flags, int mode);
void check_exit_status(void);
void print_exit_status(void);
int find_pipe(char * args[], char *** args2p);
void run_piped_children(char * args[], char * argss2[], int bkg);
extern char ** environ;
#define MAXARGS 64
#define BUFLEN 81
char delims[]="\t\n ";
//Read commands, parse, fork children, wait for finish, repeat
int main(int argc, char * argv[]) {
int pid, i, bkg;
char *(args[MAXARGS+1]);
char **args2;
char linebuf[BUFLEN+1];
while(1){
check_exit_status();//update from stub
printf("jml>");/*All examples give a space...but
I like DOS too much, I'm afraid. */
if(fgets(linebuf, BUFLEN, stdin)==NULL) break;
if(!(parse_args(linebuf, args)) continue;
if (internal_command(args)) continue;
bkg=find_background(args);
if(find_pipe(args, &args2)) {//The line that caused trouble
run_piped_children(args, args2, bkg);
} else{
if ((pid=fork())==-1)
perror(NULL);
else if (pid==0)
childproc(args);
else
parentproc(pid, bkg);
}//end if Actually, end else
}//end while(1)
exit(0);
}//end main
void check_exit_status(void){
int stat, pid;
while((pid=waitpid(-1, &stat, WNOHANG))>0){
if(pid==-1){
perror(NULL);
return;
}//end if
print_exit_status(pid, stat);
}//end while loop
return;
}//end check_exit_status
void parentproc(int pid, int bkg){
int stat;
int resultpid;
if(bkg)
return;
while((resultpid=wait(&stat))!=pid){
if(resultpid==-1){
perror(NULL);
return;
}//end if
print_exit_status(pid, stat);
}//end while loop
if(WEXITSTATUS(stat)!=0)//Halleluja, found WEXITSTATUS Dec. 3rd!
printf("EXIT STATUS = %d\n", WEXITSTATUS(stat));
return;
}//end void parentproc(int pid, intbkg)
//1 if internal_command works, no return if it doesn't
int internal_command(char *args[]){
int j;
if(strcmp("exit", args[0])==0)
exit(0);
if(strcmp("environ", args[0])==0){
for(i=0; environ[1]!=NULL; i++)
printf("%s\n", environ[i]);
return 1;
}//end if
if(strcmp("path", args[0])==0){
printf("%s\n", getenv("PATH"));
return 1;
}//end if
return 0;
}//end int internal_command(char *args[])
void print_exit_status(int pid, int stat){
if(WIFEXITED(stat))
if(WEXITSTATUS(stat)!=0)
printf("PID %d EXITED AS %d\n", pid, WEXITSTATUS(stat));
else if(WIFSIGNALED(stat))
printf("PID %d ENDED WITH %d\n", pid, WTERMSIG(stat));
else
printf("PID %d ENDED AS %08x\n", pid, stat);
return;
}//end void print_exit_status(int pid, int stat)
void childproc(char *args[]) {
if(!redirect_io(args))
exit(1);
if(execvp(args[0], args)==-1)
perror(args[0]);
exit(1)
}//end void childproc(char *args[])
int parse_args(char * linebuf, char * args[]){
int nargs=0;
args[nargs]=strtok(linebuf, delims);
while(args[nargs]!=NULL){
args[++nargs]=strtok(NULL, delims);
}//end while
return(nargs>//Should be 1 if it works, I think
}//end int parse_args
//ip= input process, op=output process, p=process I'm lookin' at.
int redirect_io(char * args[]){
int ip=1;
int op=1;
char c;
char * p;
while((p=args[ip++])!=NULL){
c=*p;
if(!((c=='>') || (c=='<'))){ //Is this line right?
args[op++]=p;
continue;
}//end if statement
if(strlen(p)==1)
p=args[ip++];
else
p++;
switch(c){
case '<' :
if(|opfile(0, p, O_RDONLY, 0))
return 0;
break;
case '>' :
if(!opfile(1, p, O_CREAT|O_EXCL|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR))//I KNOW I made a mistake here.
return 0;
break;
}//end switch(c)
}//end while((p=args[ip++])!=NULL)
args[op++]=NULL;
return 1;
}//end int redirect_io
int find_background(char * args[]){
int arglen;
char *p;
int x=0;
while((p=args[x++])!=NULL); //Thank you, h2g2!
--x;//Or should it be x--? Or does it matter? Hmmm...
p=args[--x];//Ditto.
arglen=strlen(p);
if(p[arglen-1]=='&'){
if(arglen==1)
args[x]=NULL;
else
p[arglen-1]='\0';
return 1;
}//end if statement
return 0;//Only hits this if not backgrounded
}//int find_background(char * args[])
int opfile(int slot, char * fname, int flags, int mode){
int fid;//file ID
if((fid=open(fname, flags, mode))==-1){
perror(fname);
return 0;
}//end if
dup2(fid, slot);
close(fid);
return 1;//gets here if succesfully moves the file to the FID slot
}//end int opfile(int slot, char * fname, int flags, int mode)
void run_piped_children(char * args[], char * args2[], int bkg){
int pipends[2];
int pid;//process ID
if(pipe(pipends)==-1){
perror(NULL);
return;
}//end if
if((pid=fork())==-1){
perror(NULL);//I can't figure out why this works....but it DOES! WIIGII!
return;
}//end another if statement
if(pid==0){
dup2(pipends[1], 1);
close(pipends[1]);//I think the problem was here. I didn't close this end soon enough.
childproc(args);
}//end if
close(pipends[1]));//WHERE DOES THIS GO?!
if((pid=fork())==-1){
perror(NULL);
return;
}//end if
if(pid==0){
dup2(pipends[0], 0);
close(pipends[0]);
childproc(args2);
}//end if(pid==0)
close(pipends[0]);
parentproc(pid, bkg);
return;
}//end void run_piped_children(char * args[], char * args2[], int bkg)
int find_pipe(char * args[], char ***args2p){//Help me, Batman! Asterisks confuse me!
int x=0;
char * p;
while((p=args[x++])!=NULL){
if(strcmp(p, "|")==0){
args[x-1]=NULL;
if(args[x]==NULL)
return 0;
*args2p = &args[x];
return 1;
}//end if(strcmp(p, "|")==0)
}//end while loop
return 0;
}//end int find_pipe(char * args[], char ***args2p)
More Necessary Info Storage
Garius Lupus Posted Dec 16, 2005
Here's an example of a well formatted and commented program. I think it does something similar to your last one - spawns child processes (and times them). Note the use of indenting to make the structure clear. I got an A for this one.
/* *******************************************************************
forking - program to determine the time for creating processes in AIX.
Author: Gary Lythe
Revision Number: 1.00
Revision History:
Oct. 17, 1996 : Certified.
Oct. 17, 1996 : Final modifications and testing.
Oct. 9, 1996 : Original insertion of code.
************************************************************************ */
#include
#include
#include
#include
#include
#include
#define NITER 4 /* number of process sizes to loop for */
#define MAXFORKS 10000 /* maximum number of forks to do */
void write_err(); /* routine to write error messages */
main(int argc, char *argv[])
{
int num_forks; /* number of forks to do to get average time per fork */
char *dummy = NULL; /* dummy array for setting size of process */
int dum_size = 100 ; /* no. of elements in dummy array */
clock_t fstart, fend; /* starting and ending time for forking */
double ftime; /* elapsed time for forking */
int child_pid; /* pid of child process */
int isize, ifork, i; /* loop counters */
int ierr; /* return value from a function */
/* check if optional argument on command line - i.e. get no. of
forks to do and check if in bounds */
if( argc == 2 )
{
num_forks = (int) strtol( argv[1], (char **) NULL, 10 );
if( num_forks <= 0 || num_forks > MAXFORKS )
{
write_err(1); /* write out of bounds error message */
write_err(0); /* write command line syntax */
exit(0);
}
}
else
num_forks = 1000; /* default value */
/* start outer loop for various process sizes */
for ( isize = 1; isize <= NITER; isize++ )
{
dum_size *= 10; /* increase size of process by factor of 10 */
/* realocate space for the larger dummy array */
dummy = (char *) realloc( (char *)dummy, dum_size * sizeof(char) );
if ( dummy == NULL )
{
write_err(2); /* write out of memory error message */
exit(0);
}
/* Now time the forking */
fstart = clock(); /* get starting time */
for ( ifork = 1; ifork <= num_forks; ifork++ ) /* loop many times to
get reliable average */
{
child_pid = fork(); /* this is the fork */
if ( child_pid == -1 )
{
write_err(3); /* write error message */
exit(0);
}
if ( child_pid )
{
/* this is the parent process, so kill child */
ierr = kill( child_pid, SIGKILL ) ;
if ( ierr != 0 )
{
write_err(4); /* write error message */
exit(0);
}
wait ( child_pid ); /* needed to ensure child is dead (if this
is not here, child doesn't die until
parent exits) */
}
else
{
/* this is the child process, so just exit */
exit(1);
}
}
fend = clock(); /* get ending time */
/* calculate average time for a fork */
ftime = ( (double) (fend - fstart) / CLOCKS_PER_SEC / num_forks );
/* report the time to the user */
printf( "\nTime for forking with an array of %d characters ", dum_size );
printf( "\n(average time from %d trials):\n", num_forks );
printf( "%e seconds\n", ftime );
}
}
/* *******************************************************************
write_err - routine to write error messages
Author: Gary Lythe 4291878
Address: 119 Tecumseh Ave. E.
London, Ontario, Canada
N6A 1S1
Phone: (519) 438-9792
Revision Number: 1.00
Revision History:
October 14, 1996 : Original insertion of code
************************************************************************ */
void write_err( int err_num )
{
/* note: illegal error number message should always be the last
in the list */
char *errmsg[] =
{
"\nSyntax: forking [no._fork_iterations]\n",
"\nNumber of forks must be between 1 and 10000.\n",
"\nOut of memory.\n",
"\nForking Error.\n",
"\nError killing child.\n",
"\nIllegal error number in call to write_err routine.\n"
};
int max_err_num = 4;
if ( err_num < 0 || err_num > max_err_num )
printf( "%s\n", errmsg[max_err_num] );
else
printf( "%s\n", errmsg[err_num] );
}
More Necessary Info Storage
Garius Lupus Posted Dec 16, 2005
rofl - of course, there IS no indenting here.
*smacks forehead*
And I can't believe I broke a 9 or 10 month silence to post that.
*rolls around his office laughing*
More Necessary Info Storage
Witty Moniker Posted Dec 16, 2005
Well, now that you broke your fast, so to speak, you might as well dip your toes into a few other fora, eh?
Missed you, GL.
I'm not ignoring you Affy, I just have nothing to contribute on the programing thingy.
More Necessary Info Storage
Afgncaap5 Posted Dec 16, 2005
GL, nice to see you!
Yes, the indentation here stinks. I'll look over your coding, see if it works...
Don't suppose you've run mine through a thing to see if it works or not, didja? If it works, then I don't have to drive forty miles through the snow and ice.
Anyway, thanks GL. And no problem, Witty.
Key: Complain about this post
More Necessary Info Storage
More Conversations for Afgncaap5
Write an Entry
"The Hitchhiker's Guide to the Galaxy is a wholly remarkable book. It has been compiled and recompiled many times and under many different editorships. It contains contributions from countless numbers of travellers and researchers."