This is the Message Centre for Afgncaap5

More Necessary Info Storage

Post 1

Afgncaap5

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

Post 2

Afgncaap5

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

Post 3

Afgncaap5

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&gtsmiley - winkeye;//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

Post 4

Garius Lupus

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. smiley - biggrin 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

Post 5

Garius Lupus

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

Post 6

Witty Moniker

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. smiley - winkeye


More Necessary Info Storage

Post 7

Afgncaap5

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.smiley - winkeye

Anyway, thanks GL. And no problem, Witty.


Key: Complain about this post

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."

Write an entry
Read more