home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gdead.berkeley.edu
/
gdead.berkeley.edu.tar
/
gdead.berkeley.edu
/
pub
/
cad-tools
/
ciftomann.tar
/
sort_dir
/
sort.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-01-28
|
3KB
|
182 lines
#include "sort.h"
#include "sort_thing.h"
#include "fd.h"
#include <signal.h>
#include <stdio.h>
typedef enum { FALSE = 0, TRUE } boolean;
char tmp_dir[101];
extern int num_temps;
int comparer();
int terminate();
char *sbrk();
thing *start_mem,*end_mem;
/*
* This is a re-write of the unix sort command, with
* the character oriented sorting changed to binary
* format using a user supplied comparison function
* The routine reads in a buffer of items,
* sorts thems and outputs them into a file. This is
* continued until all input has been processed. The
* seperate files are merged MAX_FILES at a time into
* larger files until the entire input has been merged
* into one.
*/
main(argc, argv)
int argc;
char **argv;
{
int first_file,last_file;
if (argc > 1) {
strcpy(tmp_dir,argv[1]);
} else {
strcpy(tmp_dir, "/usr/tmp");
}
allocate();
check_tempspace();
catch_signals();
/* make the individual files */
make_runs();
first_file = 1;
last_file = MAX_FILES;
/* merge the files together */
while (last_file < num_temps) {
new_outfile();
merge(first_file,last_file);
close_outfile();
first_file = last_file + 1;
last_file = first_file + MAX_FILES - 1;
}
set_STDOUT();
merge(first_file,num_temps);
exit(0);
}
allocate()
/* Allocate the memory for the sorting of the individual runs.
* Sets the value of start_mem, a pointer to the start of the
* block, and end_mem, a pointer to the end of the block.
*/
{
int size;
int num_things;
size = MAX_MEM;
/* get the largest chunk of memory you can */
while( (start_mem = (thing *)sbrk(size)) == (thing *)(-1) &&
size > 0) {
size -= MEM_INC;
}
if (size < 0) {
panic("No memory at all!");
exit(1);
}
num_things = size / sizeof(thing);
end_mem = &( start_mem[num_things] );
}
make_runs()
/* Input and sort the individual runs, outputing the
* results directly if only one run is necessary
*/
{
thing *current;
int status;
boolean eof = FALSE;
int num_elements;
do {
current = start_mem;
while( current < end_mem && eof == FALSE ) {
status = fread((char *) current, sizeof(thing), 1, stdin);
if (status == 0) {
eof = TRUE;
} else {
current++;
}
}
num_elements = (current - start_mem);
qsort((char *)start_mem,num_elements,sizeof(thing),comparer);
if ( eof && num_temps == 0) {
/* only one run was necessary */
set_STDOUT();
} else {
new_outfile();
}
output_run(start_mem,current);
close_outfile();
} while ( !eof );
}
catch_signals()
{
if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
signal(SIGHUP, terminate);
}
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
signal(SIGINT, terminate);
}
if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
signal(SIGTERM, terminate);
}
}
panic(str)
char *str;
{
extern int errno;
extern char *sys_errlist[];
fprintf(stderr,"Panic in sort : %s (%s)\n",str,sys_errlist[errno]);
terminate();
}
terminate()
{
fprintf(stderr,"\nremoving tempfiles, just a moment...");
clean_up_files();
fprintf(stderr,"done!\n");
exit(1);
}