This is osblock.c in view mode; [Download] [Up]
/* osmsdos/osblock.c */
#include <sys/types.h>
#include <dos.h>
#include <io.h>
#include <errno.h>
#include <fcntl.h>
#include "elvis.h"
#ifndef DEFAULT_SESSION
# define DEFAULT_SESSION "ELVIS%d.SES"
#endif
/* Microsoft seems to think that the goal of ANSI C's namespace pollution
* conventions is to make the language incompatible with existing C code.
*/
#ifndef O_RDWR
# define O_RDWR _O_RDWR
# define O_RDONLY _O_RDONLY
# define O_WRONLY _O_WRONLY
# define O_CREAT _O_CREAT
# define O_EXCL _O_EXCL
# define O_BINARY _O_BINARY
#endif
static int fd = -1; /* file descriptor of the session file */
/* This function creates a new block file, and returns True if successful,
* or False if failed because the file was already busy.
*/
BOOLEAN blkopen(BOOLEAN force, BLK *buf)
{
char sesname[100];
char *sespath;
int len, i;
/* If no session file was explicitly requested, use the default */
if (!o_session)
{
/* search through SESSIONPATH for a writable directory */
sespath = getenv("SESSIONPATH");
if (!sespath)
sespath = getenv("TMP");
if (!sespath)
sespath = "C:\\TMP;~;";
do
{
for (len = 0; *sespath && *sespath != ';'; sespath++)
{
if (len == 0 && *sespath == '~')
{
strcpy(sesname, tochar8(o_home));
len = strlen(sesname);
}
else
{
sesname[len++] = *sespath;
}
}
if (len == 0)
{
strcpy(sesname, ".");
len = 1;
}
if (sesname[len - 1] != '\\')
sesname[len++] = '\\';
strcpy(sesname + len, "elvis.tmp");
} while ((i = open(sesname, O_RDWR|O_CREAT, 0666)) < 0 && *sespath++);
if (i < 0)
{
msg(MSG_FATAL, "set \\$SESSIONPATH to a writable directory");
}
close(i);
remove(sesname);
/* create a unique session file in that directory */
for (i = 1; i <= 999; i++)
{
sprintf(sesname + len, DEFAULT_SESSION, i);
if (o_recovering)
{
if (access(sesname, 0) == 0)
break;
}
else
{
if (access(sesname, 0) != 0)
break;
}
/* If the user wants to cancel, then fail */
if (chosengui->poll && (*chosengui->poll)(False))
return False;
}
if (i > 999)
{
msg(MSG_FATAL, "could not find default session file");
}
optpreset(o_session, CHARdup(toCHAR(sesname)), OPT_LOCK|OPT_FREE);
o_tempsession = (BOOLEAN)!o_recovering;
}
/* Try to open the session file */
fd = open(tochar8(o_session), O_RDWR|O_BINARY);
if (fd < 0)
{
if (errno == ENOENT)
{
fd = open(o_session, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600);
if (fd >= 0)
{
if (write(fd, (char *)buf, (unsigned)o_blksize) < o_blksize)
{
close(fd);
remove((char *)o_session);
fd = -1;
errno = ENOENT;
}
else
{
lseek(fd, 0L, 0);
}
}
}
if (fd < 0)
{
msg(MSG_FATAL, "[Sd]$1: no such session, errno=$2", o_session, (long)errno);
}
}
else
{
/* if the session existed before elvis, it'll exist after */
o_tempsession = False;
}
/* Read the first block & mark the session file as being "in use".
* If already marked as "in use" and !force, then fail.
*/
/* lockf(fd, LOCK, sizeof buf->super); */
if (read(fd, buf, sizeof buf->super) != sizeof buf->super)
{
msg(MSG_FATAL, "blkopen's read failed");
}
if (buf->super.inuse && !force)
{
return False;
}
buf->super.inuse = 1;
lseek(fd, 0L, 0);
(void)write(fd, buf, sizeof buf->super);
/* done! */
return True;
}
/* This function closes the session file, given its handle */
void blkclose(BLK *buf)
{
blkread(buf, 0);
buf->super.inuse = 0L;
blkwrite(buf, 0);
close(fd);
fd = -1;
if (o_tempsession)
remove(tochar8(o_session));
}
/* Write the contents of buf into record # blkno, for the block file
* identified by blkhandle. Blocks are numbered starting at 0. The
* requested block may be past the end of the file, in which case
* this function is expected to extend the file.
*/
void blkwrite(BLK *buf, _BLKNO_ blkno)
{
/* write the block */
lseek(fd, (long)blkno * (long)o_blksize, 0);
if (write(fd, buf, (unsigned)o_blksize) != o_blksize)
{
msg(MSG_FATAL, "blkwrite failed");
}
}
/* Read the contends of record # blkno into buf, for the block file
* identified by blkhandle. The request block will always exist;
* it will never be beyond the end of the file.
*/
void blkread(BLK *buf, _BLKNO_ blkno)
{
/* read the block */
lseek(fd, (long)blkno * o_blksize, 0);
if (read(fd, buf, (unsigned)o_blksize) != o_blksize)
{
msg(MSG_FATAL, "blkread failed");
}
}
/* Force changes out to disk. */
void blksync P_((void))
{
close(fd);
fd = open(tochar8(o_session), O_RDWR|O_BINARY);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.