This is osblock.c in view mode; [Download] [Up]
/* unix/osblock.c */ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #ifndef S_ISDIR # define S_ISDIR(mode) (((mode & 0170000) == 0040000) #endif #include "elvis.h" #ifndef DEFAULT_SESSION # define DEFAULT_SESSION "%s/elvis%d.ses" #endif #ifndef F_OK # define F_OK 0 #endif #ifndef W_OK # define W_OK 2 #endif char id_osblock[] = "$Id: osblock.c,v 2.17 1996/10/01 19:48:23 steve Exp $"; 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(force, buf) BOOLEAN force; /* if True, open even if "in use" flag set */ BLK *buf; /* buffer, holds SUPER block */ { static char dfltname[100]; char dir[80]; struct stat st; int i, j; /* If no session file was explicitly requested, try successive * defaults until we find an existing file (if we're trying to * recover) or a non-existent file (if we're not trying to recover). */ if (!o_session) { /* search through sessionpath for a writable directory */ if (!o_sessionpath) o_sessionpath = toCHAR("~:."); for (i = 0, *dir = '\0'; o_sessionpath[i] && !*dir; ) { /* copy next name from o_sessionpath to dfltname */ j = 0; if (o_sessionpath[i] == '~' && !isalnum(o_sessionpath[i + 1])) { strcpy(dir, tochar8(o_home)); j = strlen(dir); i++; } while (o_sessionpath[i] && o_sessionpath[i] != ':') { dir[j++] = o_sessionpath[i++]; } dir[j] = '\0'; if (j == 0) strcpy(dir, "."); if (o_sessionpath[i] == ':') i++; /* If not writable directory, forget it */ if (stat(dir, &st) != 0 || !S_ISDIR(st.st_mode) || !(st.st_uid == geteuid() ? (st.st_mode & S_IRWXU) == S_IRWXU : st.st_gid == getegid() ? (st.st_mode & S_IRWXG) == S_IRWXG : (st.st_mode & S_IRWXO) == S_IRWXO)) { *dir = '\0'; } } if (!*dir) { msg(MSG_FATAL, "set \\$SESSIONPATH to a writable directory"); } optpreset(o_directory, CHARdup(toCHAR(dir)), OPT_FREE); /* choose the name of a session file */ i = 1; do { sprintf(dfltname, DEFAULT_SESSION, dir, i++); /* if the file exists and is writable by this user, * and we aren't recovering, then print a warning * so the user know he should recover eventually. */ if (!o_recovering && access(dfltname, W_OK) == 0) { msg(MSG_WARNING, "[s]skipping old session file $1", dfltname); } /* if user wants to cancel, then fail */ if (chosengui->poll && (*chosengui->poll)(False)) { return False; } } while (access(dfltname, F_OK) != (o_recovering ? 0 : -1)); o_session = toCHAR(dfltname); o_tempsession = True; } /* Try to open the session file */ fd = open(tochar8(o_session), O_RDWR); if (fd >= 0) { /* we're opening an existing session -- definitely not temporary */ o_tempsession = False; } else { if (errno == ENOENT) { fd = open(tochar8(o_session), O_RDWR|O_CREAT|O_EXCL, 0600); if (fd >= 0) { o_newsession = True; if (write(fd, (char *)buf, (unsigned)o_blksize) < o_blksize) { close(fd); unlink(tochar8(o_session)); fd = -1; errno = ENOENT; } else { lseek(fd, 0L, 0); } } } if (fd < 0) { msg(MSG_FATAL, "no such session"); } } /* if elvis runs other programs, they shouldn't inherit this fd */ fcntl(fd, F_SETFL, 1); /* 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, (char *)buf, sizeof buf->super) != sizeof buf->super) { msg(MSG_FATAL, "blkopen's read failed"); } if (buf->super.inuse && !force) { /* lockf(fd, ULOCK, o_blksize); */ return False; } buf->super.inuse = getpid(); lseek(fd, 0L, 0); (void)write(fd, (char *)buf, sizeof buf->super); /* lockf(fd, ULOCK, o_blksize); */ /* done! */ return True; } /* This function closes the session file, given its handle */ void blkclose(buf) BLK *buf; /* buffer, holds superblock */ { blkread(buf, 0); buf->super.inuse = 0L; blkwrite(buf, 0); close(fd); fd = -1; if (o_tempsession) { unlink(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(buf, blkno) BLK *buf; /* buffer, holds contents of block */ _BLKNO_ blkno; /* where to write it */ { /* write the block */ lseek(fd, (off_t)blkno * (off_t)o_blksize, 0); if (write(fd, (char *)buf, (size_t)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(buf, blkno) BLK *buf; /* buffer, where buffer should be read into */ _BLKNO_ blkno; /* where to read from */ { /* read the block */ lseek(fd, (off_t)blkno * o_blksize, 0); if (read(fd, (char *)buf, (size_t)o_blksize) != o_blksize) { msg(MSG_FATAL, "blkread failed"); } } /* Force changes out to disk. Ideally we would only force the session file's * blocks out to the disk, but UNIX doesn't offer a way to do that, so we * force them all out. Major bummer. */ void blksync P_((void)) { sync(); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.