sequencer.c

A simple program that exploded with too many features

// =========================================================================================
// title  : sequencer_203.c
// author : Neil Rieck 
// created: 2021-11-11
// history:
// 200 20211111 NSR 1. original effort (hard-coded parameters)				DVLP
// 201 20211112 NSR 1. added support for soft-coded parameters				DVLP
// 202 20211115 NSR 1. added support for flock						DVLP
// ------------ // 203 20211202 NSR 1. fixed hacks; replaced fgetc with fread (and fputc with fwrite) PROD // notes : // 1) a tiny little program for use with email interfaces on CentOS (espp, radiovideo, etc). // Call this program when trying to determine the next WORKBENCH folder (eg. WORKBENCH9) // 2) when used from OpenVMS, getenv reads information from either logical names or shell
// vars. Logical names do not exist on CentOS // 3) setenv and putenv do not work the way most people think. On any UNIX or Linux system
// they only work on the forked process but cannot directly update anything in the calling // process. Even though OpenVMS does not fork, these routines still only affect the shell
// vars of the active process and are lost when that program exits. OpenVMS programs
// requiring this functionality can do so by calling lib$set_symbol. Linux systems with BASH
// can copy the output of this program into a shell variable like so: SEQ_NUM=$(./sequencer) // 4) all versions before 203 will only work on little endian systems where seq <= 127 // 5) CentOS build: gcc sequencer_203.c -o sequencer // ========================================================================================= #include <stdio.h> #include <stdlib.h> #include <errno.h> #define __NEW_STARLET 1 // enable new-strict starlet (>= OpenVMS7) #define SMALLER 1 // disable optional parameter support // #define DEFSEQMIN 1 // default MIN #define DEFSEQMAX 9 // default MAX #define NAMSEQMIN "SEQ_MIN" // optional parameter (define in your shell) #define NAMSEQMAX "SEQ_MAX" // optional parameter (define in your shell) #define NAMSEQDEB "SEQ_DEBUG" // optional parameter (define in your shell) #define NAMSEQNUM "SEQ_NUM" // written to your VMS shell (must already // #define LOCK_SH 1 // shared lock #define LOCK_EX 2 // exclusive lock #define LOCK_NB 4 // don't block when locking #define LOCK_UN 8 // unlock // extern int errno; // this is located elsewhere // int main(){ // ========================================= // init // ========================================= FILE *fp; char *tmp; int seqmin, seqmax; int debug; int seq; int rc; // ========================================= // get params // ========================================= #if (SMALLER==1) debug = 0; seqmin = DEFSEQMIN; seqmax = DEFSEQMAX; #else tmp = getenv(NAMSEQDEB); if (tmp==NULL){ debug = 0; }else{ debug = atoi(tmp); } // tmp = getenv(NAMSEQMIN); if (tmp==NULL){ seqmin = DEFSEQMIN; }else{ seqmin = atoi(tmp); if (debug>0) printf("-i-param seqmin: %d\n",seqmin); } // tmp = getenv(NAMSEQMAX); if (tmp==NULL){ seqmax = DEFSEQMAX; }else{ seqmax = atoi(tmp); if (debug>0) printf("-i-param seqmax: %d\n",seqmax); } #endif // // minimal tests of parameter data (KISS) // if (seqmin<DEFSEQMIN){ // seqmin = DEFSEQMIN; // } if (seqmin>=seqmax){ // seqmax = seqmin + 1; // } if (debug>0){ printf("-i-data seqmin: %d\n",seqmin); printf("-i-data seqmax: %d\n",seqmax); } // ========================================= // support the main task // ========================================= // open the file then place a lock fp = fopen("sequencer.dat","r+"); // open for read-write if ((fp == NULL)&&(errno == 2)){ // oops, handle first time fp = fopen("sequencer.dat","w+"); // create the file if (fp != NULL){ seq = seqmin; // init fwrite(&seq, sizeof(seq), 1L, fp); fseek(fp, 0L, SEEK_SET); errno = 1; } } if (fp == NULL){ perror("-e-the data file cannot be opened"); exit (2); } rc = flock(fileno(fp), LOCK_EX); // place an exclusive lock // // get down to work // seq = -1; // init fread(&seq, sizeof(seq), 1L, fp); // read if (seq<seqmin){ // oops, handle first time seq = seqmin; }; seq = seq + 1; // okay, get down to business if (seq>seqmax){ seq = seqmin; }; fseek(fp, 0L, SEEK_SET); // prep to write back fwrite(&seq, sizeof(seq), 1, fp); // write fflush(fp); // rc = flock(fileno(fp), LOCK_UN); // fclose(fp); // close if (debug>0){ // DVLP printf("-i-new sequence data: %d\n", seq); }else{ // PROD printf("%d", seq); // send stdout (then a BASH variable?) } exit(0); // okay }

left hand Back to Linux Demo Index
home Back to Home
Neil Rieck
Waterloo, Ontario, Canada.