📄 diskwrit.c
字号:
- 'var_id' corresponds to an undefined variable - all values of this variable have been saved since last end_block - saved less than the specified number of values*/save_variable ( var_id, values, num )register char *values;int var_id, num;{ register char *bufp, *endp; int values_left, error; strcpy(ervar.routine, "save_variable"); strcpy(ervar.name, "UNKNOWN"); /* the first 2 errors have no f or v name *//* * do the easy error checking: */ if (var_id < 0 || var_id >= MAX_FILES * MAX_VARS_PER_BLK) /* out of range */ { ervar.param = var_id; if (auto_er) error_exit(-19); return(-19); } if (vd[var_id].bytes == 0) /* undefined variable */ { ervar.param = var_id; if (auto_er) error_exit(-20); return(-20); } strcpy(ervar.name, fd[var_id/MAX_VARS_PER_BLK].vnames[var_id%MAX_VARS_PER_BLK]); if (num < 1) /* saving less than one value */ { if (auto_er) error_exit(-18); return(-18); }/* * find out if the requested amount of values can be saved: */ values_left = vd[var_id].number - vd[var_id].num_saved; if (values_left == 0) /* all values already saved */ { if (auto_er) error_exit(-21); return(-21); } error = 0; if (num > values_left) /* not enough space to save all values */ { num = values_left; /* truncate number saved to number left */ error = -22; /* and report this error */ } vd[var_id].num_saved += num; /* account for the number of values saved *//* * move the new values to the data buffer: */ bufp = vd[var_id].bufp; /* fetch buffer pointer, for register use */ endp = vd[var_id].bufp + num * vd[var_id].bytes; /* end of transfer */ while (bufp < endp) *bufp++ = *values++; /* move values & inc pointers */ vd[var_id].bufp = bufp; /* restore the advanced buffer pointer */ if (error<0 && auto_er) error_exit(error); return(error);}/* ------------------------- END BLOCK ROUTINE ------------------------- *//* DESCRIPTION: status = end_block ( file_id ) This routine terminates the saving of variables for a block. The valuesin the block are written to the data file. This is the ONLY routine whichwrites values to the data file. The first call to this routine terminates thevariable definition process, i.e. def_var can no longer be called for thisfile_id.Returned value: The returned value indicates whether or not the routine encountered anerror. If no error occurs, the returned value is 0. If an error occurs, thereturned value is < 0.The following errors are detected: - 'file_id' is out of range - 'file_id' corresponds to an unopened file - current variable definition differs from that of appended file - error when writing format file - error when writing data buffer to disk - no variables have been defined*/end_block ( file_id )int file_id;{ register int i; int var_id, bytes, tempfd, vnum; short format[2 + 2*MAX_VARS_PER_BLK]; char fname[MAX_FILENAME_LENG + sizeof(FFE)]; strcpy(ervar.routine, "end_block"); strcpy(ervar.name, "UNKNOWN"); /* the first 2 errors have no f or v name *//* * do the easy error checking: */ if (file_id < 0 || file_id >= MAX_FILES) /* bogus file_id */ { ervar.param = file_id; if (auto_er) error_exit(-11); return(-11); } if (fd[file_id].open_type == 0) /* file not open */ { ervar.param = file_id; if (auto_er) error_exit(-12); return(-12); } strcpy(ervar.name, fd[file_id].filename);/* * for all variables in this file, put default values into unused locations: */ for (vnum=1; vnum<=fd[file_id].var_count; vnum++) { var_id = var_id_gen(file_id, vnum); while (vd[var_id].num_saved++ < vd[var_id].number) { for (i=0; i<vd[var_id].bytes; i++) *vd[var_id].bufp++ = vd[var_id].def_val[i]; } }/* * If this is the first time end_block is called for this file_id: * if appending, compare format of old file with current definition; * if writing a new file, write the format information. */ if (fd[file_id].defined == 0) /* first call for this file_id */ { if (fd[file_id].var_count == 0) /* no variables defined */ { if (auto_er) error_exit(-28); return(-28); } fd[file_id].format[0] = 1; /* disk-resident data */ fd[file_id].format[1] = fd[file_id].var_count; fd[file_id].defined = 1; /* indicate that the block has been defined *//* * make the format file name: */ strcpy(fname, fd[file_id].filename); strcat(fname, FFE); if (fd[file_id].open_type == 2) /* appending to current file */ { tempfd = open(fname, O_RDONLY); read(tempfd, format, 4); /* read the first 2 format values */ if (format[1] != fd[file_id].format[1]) /* # of vars different */ { close(tempfd); /* close the format file */ if (auto_er) error_exit(-25); return(-25); } read(tempfd, &format[2], 4*format[1]); /* read var definitions */ for (i=2; i < 2 + 2*format[1]; i++) { if (format[i] != fd[file_id].format[i]) /* type or # different */ { close(tempfd); /* close the format file */ if (auto_er) error_exit(-25); return(-25); } } close(tempfd); } else /* new file; write format info */ { tempfd = open(fname, O_WRONLY);/* * write the format array: */ bytes = 4 + 4 * fd[file_id].var_count; if (bytes != write(tempfd, fd[file_id].format, bytes) ) { close(tempfd); /* close the format file */ if (bytes == -1) perror("The system call error in disk write is"); if (auto_er) error_exit(-26); return(-26); }/* * write the variable names: */ bytes = fd[file_id].var_count * MAX_VARNAME_LENG; if (bytes != write(tempfd, fd[file_id].vnames, bytes) ) { close(tempfd); /* close the format file */ if (bytes == -1) perror("The system call error in disk write is"); if (auto_er) error_exit(-26); return(-26); } close(tempfd); /* close the format file */ } }/* * reset bufp & num_saved in preparation to save the next block: */ for (vnum=1; vnum<=fd[file_id].var_count; vnum++) { var_id = var_id_gen(file_id, vnum); vd[var_id].bufp = vd[var_id].base_addr; vd[var_id].num_saved = 0; }/* * write the block buffer: */ bytes = fd[file_id].bytes_p_blk; if (bytes != write(fd[file_id].fd, vd[var_id_gen(file_id, 1)].base_addr, bytes) ) { if (bytes == -1) perror("The system call error in disk write is"); if (auto_er) error_exit(-27); return(-27); } return(0);}/* ------------------------- CLOSE FILE ROUTINE ------------------------- *//* DESCRIPTION: status = close_file ( file_id ) This routine closes the file associated with "file_id". In the event thatmore files need to be written than can be opened simultaneously, this routineprovides a way to close a file so that another can be opened.Returned value: The returned value indicates whether or not the routine encountered anerror. If no error occurs, the returned value is 0. If an error occurs, thereturned value is < 0.The following errors are detected: - 'file_id' is out of range - 'file_id' corresponds to an unopened file*/close_file ( file_id )int file_id;{ strcpy(ervar.routine, "close_file"); strcpy(ervar.name, "UNKNOWN"); /* can't determine associated file name *//* * do the easy error checking: */ if (file_id < 0 || file_id >= MAX_FILES) /* bogus file_id */ { ervar.param = file_id; if (auto_er) error_exit(-11); return(-11); } if (fd[file_id].open_type == 0) /* file not open */ { ervar.param = file_id; if (auto_er) error_exit(-12); return(-12); } close(fd[file_id].fd); free(vd[var_id_gen(file_id,1)].base_addr); /* free the saved value buffer */ fd[file_id].open_type = 0; /* make file_id available */ return(0);}/* ------------------- PRINT DISK WRITE ERROR ROUTINE ------------------- *//* DESCRIPTION: print_disk_write_error ( err_num ) This routine prints an error message which corresponds to "err_num".It is printed on stderr.*/print_disk_write_error ( err_num )int err_num;{ char *disk_write_error(); if (err_num < 0) { fprintf(stderr, "Disk_IO error in routine '%s'.\n", ervar.routine); fprintf(stderr, "The filename or variable name associated with the offending call is:\n"); fprintf(stderr, "%s\n", ervar.name); fprintf(stderr, disk_write_error(err_num) ); if (ervar.param != PARAM_OK) { fprintf(stderr, "Its value was: %d\n", ervar.param); ervar.param = PARAM_OK; } } else fprintf(stderr, disk_write_error(err_num) ); return;}/* ---------------------- DISK WRITE ERROR ROUTINE ---------------------- *//* DESCRIPTION: error_string = disk_write_error ( err_num ) The disk_write_error routine returns a brief error message whichcorresponds to "err_num".*/char *disk_write_error ( err_num )int err_num;{ static char err_string[70]; static char *err_msg[] = { "No error", /* 0 *//* * OPEN FILE ERRORS: */ "The number of files currently open is the maximum", /* 1 */ "Could not create a format file", /* 2 */ "Could not create a data file", /* 3 */ "Could not open 'filename'.sg_format for reading", /* 4 */ "Could not open 'filename'.sg_data for writing", /* 5 */ "File 'filename' exists and you want to protect it", /* 6 */ "Invalid 'open_type'", /* 7 */ "File 'filename' is already open", /* 8 */ "Filename is too long", /* 9 *//* * DEFINE VARIABLE ERRORS: */ "Could not get a buffer for saved values", /* 10 */ "'file_id' is out of range", /* 11 */ "'file_id' corresponds to an unopened file", /* 12 */ "The file variables have already been defined", /* 13 */ "The specified data type is not valid", /* 14 */ "The specified number of values is not valid", /* 15 */ "The maximum number of variables have already been defined", /* 16 */ "Variable name is too long", /* 17 *//* * SAVE VARIABLE ERRORS: */ "Attempt to save less than one value", /* 18 */ "'var_id' is out of range", /* 19 */ "'var_id' corresponds to an undefined variable", /* 20 */ "All values of this variable have been saved", /* 21 */ "Number of values saved exceeded amount defined", /* 22 */ "unassigned", /* 22 */ "unassigned", /* 24 *//* * END BLOCK ERRORS: */ /* uses errors 11 & 12 from define variable */ "Current variable definition does not match that of old file", /* 25 */ "Error when writing format file", /* 26 */ "Error when writing data buffer to disk", /* 27 */ "No variables have been defined", /* 28 *//* * CLOSE FILE ERRORS: */ /* uses errors 11 & 12 from define variable */ "unassigned", /* 29 *//* * ALL OTHER ERRORS: */ "Bad value for error number" /* 30 */ };#define NUM 30 if (err_num > 0) err_num = 0; /* force positive arguments to give no error */ strcpy(err_string, (-err_num < NUM) ? err_msg[-err_num] : err_msg[NUM] ); strcat(err_string,".\n"); return(err_string);}/* -------------------------- SUPPORT ROUTINES -------------------------- *//* ----------------------------- VAR_ID_GEN ----------------------------- *//* DESCRIPTION: Given a file_id and variable number, this routine returns a variable id.The variable number range is 1 to MAX_VARS_PER_BLK inclusive.*/static var_id_gen ( file_id, var_num )int file_id, var_num;{ return(file_id * MAX_VARS_PER_BLK + var_num - 1);}/* ----------------------------- ERROR_EXIT ----------------------------- */static error_exit(err_num)int err_num;{ print_disk_write_error(err_num); exit(-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -