/* * lock: * Check and lock a file from access by others * returns TRUE = files was not locked and now is * FALSE = file was locked and overridden * ABORT = file was locked, abort command * * char *fname; file name to lock */ int lock(char *fname) { char *locker; /* lock error message */ int status; /* return status */ char msg[NSTRING]; /* message string */ /* attempt to lock the file */ locker = dolock(fname); if (locker == NULL) /* we win */ return TRUE; /* file failed...abort */ if (strncmp(locker, "LOCK", 4) == 0) { lckerror(locker); return ABORT; } /* someone else has it....override? */ xstrcpy(msg, "File in use by "); strcat(msg, locker); strcat(msg, ", override?"); status = mlyesno(msg); /* ask them */ if (status == TRUE) return FALSE; else return ABORT; }
int main(int argc, char** argv) { ensure_eq(argc,2); recordInit(); init_timeop(); ssize_t amt; realpath(argv[0],lackey); char* lastslash = strrchr(lackey,'/'); if(lastslash == NULL) { realpath("./lackey-bin",lackey); } else { // take the real path of us, and convert the end to lackey-bin amt = lastslash - lackey + 1; record(INFO,"realp %s",lackey+amt); memcpy(lackey+amt,"lackey-bin",sizeof("lackey-bin")); } record(INFO, "lackey '%s'",lackey); ensure_eq(0,chdir(argv[1])); // ehhhh dolock(); mkfifo("incoming",0644); // not a directory anymore // we're opening our pipe for writing, so that it doesn't go into an EOF spin loop // when there are no more writers int incoming = open("incoming",O_RDWR|O_NONBLOCK); /* block the signals we care about this does NOT ignore them, but queues them up and interrupts stuff like ppoll (which reenables getting hit by those signals atomically) then we can read info off the signalfd at our leisure, with no signal handler jammed in-between an if(numworkers == 0) and start_worker(); */ waiter_setup(); assert(0 == numworkers); pfd = malloc(sizeof(*pfd)*2); pfd[INCOMING].fd = incoming; pfd[INCOMING].events = POLLIN; pfd[ACCEPTING].fd = start_working(true); pfd[ACCEPTING].events = POLLIN; void clear_incoming(void) { char buf[512]; for(;;) { ssize_t amt = read(incoming,buf,512); if(amt <= 0) { ensure_eq(errno,EAGAIN); break; } } record(INFO,"Incoming fifo unclogged"); }
static A jtunlj(J jt,I j){B b;I*u,*v; RE(j); ASSERT(0<=j&&j<jt->flkn,EVINDEX); u=AV(jt->flkd); v=u+j*LKC; RE(b=dolock(0,(F)v[0],v[1],v[2])); if(!b)R zero; --jt->flkn; if(j<jt->flkn)ICPY(v,u+jt->flkn*LKC,LKC); else *v=0; R one; } /* unlock the j-th entry in jt->flkd */
ATF_TC_BODY(deadlock, tc) { int fd; int error; int ret; pid_t pid; (void)unlink(lockfile); fd = open (lockfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0666); ATF_REQUIRE_MSG(fd >= 0, "open(%s): %s", lockfile, strerror(errno)); ATF_REQUIRE_MSG(ftruncate(fd, filesize) >= 0, "ftruncate(%s): %s", lockfile, strerror(errno)); fsync(fd); error = dolock(fd, F_LOCK, 0, 1); ATF_REQUIRE_MSG(error == 0, "initial dolock: %s", strerror(errno)); pid = fork(); ATF_REQUIRE_MSG(pid != -1, "fork failed: %s", strerror(errno)); if (pid == 0) { error = dolock(fd, F_LOCK, 1, 1); ATF_REQUIRE_MSG(error == 0, "child dolock: %s", strerror(errno)); dolock(fd, F_LOCK, 0, 1); /* will block */ atf_tc_fail("child did not block"); } sleep(1); /* give child time to grab its lock then block */ error = dolock(fd, F_LOCK, 1, 1); ATF_REQUIRE_MSG(error == EDEADLK, "parent did not detect deadlock: %s", strerror(errno)); ret = kill(pid, SIGKILL); ATF_REQUIRE_MSG(ret != -1, "failed to kill child: %s", strerror(errno)); atf_tc_pass(); }
void *DL_PREFIX(dlopen)(const char *path, int mode) { const struct stat *sbuf; struct dlstatus *dls; const char *fullPath; dolock(); resetdlerror(); if (!path) { dls = &mainStatus; goto dlopenok; } if (!(sbuf = findFile(path, &fullPath))) { error("file \"%s\" not found", path); goto dlopenerror; } /* Now checks that it hasn't been closed already */ if ((dls = lookupStatus(sbuf)) && (dls->refs > 0)) { /* debug("status found"); */ dls = reference(dls, mode); goto dlopenok; } #ifdef RTLD_NOLOAD if (isFlagSet(mode, RTLD_NOLOAD)) { error("no existing handle and RTLD_NOLOAD specified"); goto dlopenerror; } #endif if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW)) { error("how can I load something both RTLD_LAZY and RTLD_NOW?"); goto dlopenerror; } dls = loadModule(fullPath, sbuf, mode); dlopenok: dounlock(); return (void *)dls; dlopenerror: dounlock(); return NULL; }
int main(int argc, char *argv[]) { int fd; if (argc < 3) { #define M "Usage: lockf file exe...\n" (void)write(2, M, sizeof(M)-1); exit(0); } fd = open(argv[1], O_RDWR); if (fd > -1) { if (fcntl(fd, F_SETFD, 0) == 0) dolock(fd); } execvp(argv[2], argv+2); exit(127); }
static int releaselock(int fd ) { return dolock(fd, F_UNLCK); }
static int takereadlock(int fd ) { return dolock(fd, F_RDLCK); }
static int takewritelock(int fd ) { return dolock(fd, F_WRLCK); }
int gip_unlock( char *path ) { return( dolock( path, GLOCK_UNLOCK ) ); }
int gip_lock( char *path ) { return( dolock( path, GLOCK_LOCK ) ); }
/* }}} */ static void xc_fcntl_unlock(xc_fcntl_mutex_t *fcntl_mutex) /* {{{ */ { if (dolock(fcntl_mutex, LCK_UN) < 0) { zend_error(E_ERROR, "xc_fcntl_unlock failed errno:%d", errno); } }