1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */ 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #include "uucp.h" 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #include <unistd.h> 31*7c478bd9Sstevel@tonic-gate /* #include <sys/types.h> */ 32*7c478bd9Sstevel@tonic-gate /* #include <sys/stat.h> */ 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate static struct stat _st_buf; 35*7c478bd9Sstevel@tonic-gate static char lockname[BUFSIZ]; 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #ifdef V7 38*7c478bd9Sstevel@tonic-gate #define O_RDONLY 0 39*7c478bd9Sstevel@tonic-gate #endif 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate static void stlock(); 42*7c478bd9Sstevel@tonic-gate static int onelock(); 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * make a lock file with given 'name' 46*7c478bd9Sstevel@tonic-gate * If one already exists, send a signal 0 to the process--if 47*7c478bd9Sstevel@tonic-gate * it fails, then unlink it and make a new one. 48*7c478bd9Sstevel@tonic-gate * 49*7c478bd9Sstevel@tonic-gate * input: 50*7c478bd9Sstevel@tonic-gate * name - name of the lock file to make 51*7c478bd9Sstevel@tonic-gate * 52*7c478bd9Sstevel@tonic-gate * return: 53*7c478bd9Sstevel@tonic-gate * 0 -> success 54*7c478bd9Sstevel@tonic-gate * FAIL -> failure 55*7c478bd9Sstevel@tonic-gate */ 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate GLOBAL int 58*7c478bd9Sstevel@tonic-gate mklock(name) 59*7c478bd9Sstevel@tonic-gate register char *name; 60*7c478bd9Sstevel@tonic-gate { 61*7c478bd9Sstevel@tonic-gate static char pid[SIZEOFPID+2] = { '\0' }; /* +2 for '\n' and NULL */ 62*7c478bd9Sstevel@tonic-gate static char tempfile[MAXNAMESIZE]; 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate #ifdef V8 65*7c478bd9Sstevel@tonic-gate char *cp; 66*7c478bd9Sstevel@tonic-gate #endif 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate if (pid[0] == '\0') { 69*7c478bd9Sstevel@tonic-gate (void) sprintf(pid, "%*ld\n", SIZEOFPID, (long) getpid()); 70*7c478bd9Sstevel@tonic-gate (void) sprintf(tempfile, "%s/LTMP.%ld", X_LOCKDIR, (long) getpid()); 71*7c478bd9Sstevel@tonic-gate } 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate #ifdef V8 /* this wouldn't be a problem if we used lock directories */ 74*7c478bd9Sstevel@tonic-gate /* some day the truncation of system names will bite us */ 75*7c478bd9Sstevel@tonic-gate cp = rindex(name, '/'); 76*7c478bd9Sstevel@tonic-gate if (cp++ != CNULL) 77*7c478bd9Sstevel@tonic-gate if (strlen(cp) > MAXBASENAME) 78*7c478bd9Sstevel@tonic-gate *(cp+MAXBASENAME) = NULLCHAR; 79*7c478bd9Sstevel@tonic-gate #endif /* V8 */ 80*7c478bd9Sstevel@tonic-gate if (onelock(pid, tempfile, name) == -1) { 81*7c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 82*7c478bd9Sstevel@tonic-gate if (cklock(name)) 83*7c478bd9Sstevel@tonic-gate return(FAIL); 84*7c478bd9Sstevel@tonic-gate else { 85*7c478bd9Sstevel@tonic-gate if (onelock(pid, tempfile, name)) { 86*7c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 87*7c478bd9Sstevel@tonic-gate DEBUG(4,"ulockf failed in onelock()\n%s", ""); 88*7c478bd9Sstevel@tonic-gate return(FAIL); 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate } 91*7c478bd9Sstevel@tonic-gate } 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate stlock(name); 94*7c478bd9Sstevel@tonic-gate return(0); 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate /* 98*7c478bd9Sstevel@tonic-gate * check to see if the lock file exists and is still active 99*7c478bd9Sstevel@tonic-gate * - use kill(pid,0) 100*7c478bd9Sstevel@tonic-gate * 101*7c478bd9Sstevel@tonic-gate * return: 102*7c478bd9Sstevel@tonic-gate * 0 -> success (lock file removed - no longer active 103*7c478bd9Sstevel@tonic-gate * FAIL -> lock file still active 104*7c478bd9Sstevel@tonic-gate */ 105*7c478bd9Sstevel@tonic-gate GLOBAL int 106*7c478bd9Sstevel@tonic-gate cklock(name) 107*7c478bd9Sstevel@tonic-gate register char *name; 108*7c478bd9Sstevel@tonic-gate { 109*7c478bd9Sstevel@tonic-gate register int ret; 110*7c478bd9Sstevel@tonic-gate pid_t lpid = -1; 111*7c478bd9Sstevel@tonic-gate char alpid[SIZEOFPID+2]; /* +2 for '\n' and NULL */ 112*7c478bd9Sstevel@tonic-gate int fd; 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate fd = open(name, O_RDONLY); 115*7c478bd9Sstevel@tonic-gate DEBUG(4, "ulockf name %s\n", name); 116*7c478bd9Sstevel@tonic-gate if (fd == -1) { 117*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) /* file does not exist -- OK */ 118*7c478bd9Sstevel@tonic-gate return(0); 119*7c478bd9Sstevel@tonic-gate DEBUG(4,"Lock File--can't read (errno %d) --remove it!\n", errno); 120*7c478bd9Sstevel@tonic-gate goto unlk; 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate ret = read(fd, (char *) alpid, SIZEOFPID+1); /* +1 for '\n' */ 123*7c478bd9Sstevel@tonic-gate (void) close(fd); 124*7c478bd9Sstevel@tonic-gate if (ret != (SIZEOFPID+1)) { 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate DEBUG(4, "Lock File--bad format--remove it!\n%s", ""); 127*7c478bd9Sstevel@tonic-gate goto unlk; 128*7c478bd9Sstevel@tonic-gate } 129*7c478bd9Sstevel@tonic-gate lpid = (pid_t) strtol(alpid, (char **) NULL, 10); 130*7c478bd9Sstevel@tonic-gate if ((ret=kill(lpid, 0)) == 0 || errno == EPERM) { 131*7c478bd9Sstevel@tonic-gate DEBUG(4, "Lock File--process still active--not removed\n%s", ""); 132*7c478bd9Sstevel@tonic-gate return(FAIL); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate else { /* process no longer active */ 135*7c478bd9Sstevel@tonic-gate DEBUG(4, "kill pid (%ld), ", (long) lpid); 136*7c478bd9Sstevel@tonic-gate DEBUG(4, "returned %d", ret); 137*7c478bd9Sstevel@tonic-gate DEBUG(4, "--ok to remove lock file (%s)\n", name); 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate unlk: 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate if (unlink(name) != 0) { 142*7c478bd9Sstevel@tonic-gate DEBUG(4,"ulockf failed in unlink()\n%s", ""); 143*7c478bd9Sstevel@tonic-gate return(FAIL); 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate return(0); 146*7c478bd9Sstevel@tonic-gate } 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate #define MAXLOCKS 10 /* maximum number of lock files */ 149*7c478bd9Sstevel@tonic-gate static char *Lockfile[MAXLOCKS]; 150*7c478bd9Sstevel@tonic-gate GLOBAL int Nlocks = 0; 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate /* 153*7c478bd9Sstevel@tonic-gate * put name in list of lock files 154*7c478bd9Sstevel@tonic-gate * return: 155*7c478bd9Sstevel@tonic-gate * none 156*7c478bd9Sstevel@tonic-gate */ 157*7c478bd9Sstevel@tonic-gate static void 158*7c478bd9Sstevel@tonic-gate stlock(name) 159*7c478bd9Sstevel@tonic-gate char *name; 160*7c478bd9Sstevel@tonic-gate { 161*7c478bd9Sstevel@tonic-gate register int i; 162*7c478bd9Sstevel@tonic-gate char *p; 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate for (i = 0; i < Nlocks; i++) { 165*7c478bd9Sstevel@tonic-gate if (Lockfile[i] == NULL) 166*7c478bd9Sstevel@tonic-gate break; 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", "", i); 169*7c478bd9Sstevel@tonic-gate if (i >= Nlocks) 170*7c478bd9Sstevel@tonic-gate i = Nlocks++; 171*7c478bd9Sstevel@tonic-gate p = (char*) calloc((unsigned) strlen(name) + 1, sizeof (char)); 172*7c478bd9Sstevel@tonic-gate ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", name, 0); 173*7c478bd9Sstevel@tonic-gate (void) strcpy(p, name); 174*7c478bd9Sstevel@tonic-gate Lockfile[i] = p; 175*7c478bd9Sstevel@tonic-gate return; 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* 179*7c478bd9Sstevel@tonic-gate * remove the named lock. If named lock is NULL, 180*7c478bd9Sstevel@tonic-gate * then remove all locks currently in list. 181*7c478bd9Sstevel@tonic-gate * return: 182*7c478bd9Sstevel@tonic-gate * none 183*7c478bd9Sstevel@tonic-gate */ 184*7c478bd9Sstevel@tonic-gate GLOBAL void 185*7c478bd9Sstevel@tonic-gate rmlock(name) 186*7c478bd9Sstevel@tonic-gate register char *name; 187*7c478bd9Sstevel@tonic-gate { 188*7c478bd9Sstevel@tonic-gate register int i; 189*7c478bd9Sstevel@tonic-gate #ifdef V8 190*7c478bd9Sstevel@tonic-gate char *cp; 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate cp = rindex(name, '/'); 193*7c478bd9Sstevel@tonic-gate if (cp++ != CNULL) 194*7c478bd9Sstevel@tonic-gate if (strlen(cp) > MAXBASENAME) 195*7c478bd9Sstevel@tonic-gate *(cp+MAXBASENAME) = NULLCHAR; 196*7c478bd9Sstevel@tonic-gate #endif /* V8 */ 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate for (i = 0; i < Nlocks; i++) { 200*7c478bd9Sstevel@tonic-gate if (Lockfile[i] == NULL) 201*7c478bd9Sstevel@tonic-gate continue; 202*7c478bd9Sstevel@tonic-gate if (name == NULL || EQUALS(name, Lockfile[i])) { 203*7c478bd9Sstevel@tonic-gate (void) unlink(Lockfile[i]); 204*7c478bd9Sstevel@tonic-gate free(Lockfile[i]); 205*7c478bd9Sstevel@tonic-gate Lockfile[i] = NULL; 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate return; 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate /* 214*7c478bd9Sstevel@tonic-gate * remove a lock file 215*7c478bd9Sstevel@tonic-gate * 216*7c478bd9Sstevel@tonic-gate * Parameters: 217*7c478bd9Sstevel@tonic-gate * pre - Path and first part of file name of the lock file to be 218*7c478bd9Sstevel@tonic-gate * removed. 219*7c478bd9Sstevel@tonic-gate * s - The suffix part of the lock file. The name of the lock file 220*7c478bd9Sstevel@tonic-gate * will be derrived by concatenating pre, a period, and s. 221*7c478bd9Sstevel@tonic-gate * 222*7c478bd9Sstevel@tonic-gate * return: 223*7c478bd9Sstevel@tonic-gate * none 224*7c478bd9Sstevel@tonic-gate */ 225*7c478bd9Sstevel@tonic-gate GLOBAL void 226*7c478bd9Sstevel@tonic-gate delock(pre, s) 227*7c478bd9Sstevel@tonic-gate char * pre; 228*7c478bd9Sstevel@tonic-gate char *s; 229*7c478bd9Sstevel@tonic-gate { 230*7c478bd9Sstevel@tonic-gate char ln[MAXNAMESIZE]; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate (void) sprintf(ln, "%s.%s", pre, s); 233*7c478bd9Sstevel@tonic-gate BASENAME(ln, '/')[MAXBASENAME] = '\0'; 234*7c478bd9Sstevel@tonic-gate rmlock(ln); 235*7c478bd9Sstevel@tonic-gate return; 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* 240*7c478bd9Sstevel@tonic-gate * create lock file 241*7c478bd9Sstevel@tonic-gate * 242*7c478bd9Sstevel@tonic-gate * Parameters: 243*7c478bd9Sstevel@tonic-gate * pre - Path and first part of file name of the lock file to be 244*7c478bd9Sstevel@tonic-gate * created. 245*7c478bd9Sstevel@tonic-gate * name - The suffix part of the lock file. The name of the lock file 246*7c478bd9Sstevel@tonic-gate * will be derrived by concatenating pre, a period, and name. 247*7c478bd9Sstevel@tonic-gate * 248*7c478bd9Sstevel@tonic-gate * return: 249*7c478bd9Sstevel@tonic-gate * 0 -> success 250*7c478bd9Sstevel@tonic-gate * FAIL -> failure 251*7c478bd9Sstevel@tonic-gate */ 252*7c478bd9Sstevel@tonic-gate GLOBAL int 253*7c478bd9Sstevel@tonic-gate mlock(pre, name) 254*7c478bd9Sstevel@tonic-gate char * pre; 255*7c478bd9Sstevel@tonic-gate char *name; 256*7c478bd9Sstevel@tonic-gate { 257*7c478bd9Sstevel@tonic-gate char lname[MAXNAMESIZE]; 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate /* 260*7c478bd9Sstevel@tonic-gate * if name has a '/' in it, then it's a device name and it's 261*7c478bd9Sstevel@tonic-gate * not in /dev (i.e., it's a remotely-mounted device or it's 262*7c478bd9Sstevel@tonic-gate * in a subdirectory of /dev). in either case, creating our normal 263*7c478bd9Sstevel@tonic-gate * lockfile (/var/spool/locks/LCK..<dev>) is going to bomb if 264*7c478bd9Sstevel@tonic-gate * <dev> is "/remote/dev/term/14" or "/dev/net/foo/clone", so never 265*7c478bd9Sstevel@tonic-gate * mind. since we're using advisory filelocks on the devices 266*7c478bd9Sstevel@tonic-gate * themselves, it'll be safe. 267*7c478bd9Sstevel@tonic-gate * 268*7c478bd9Sstevel@tonic-gate * of course, programs and people who are used to looking at the 269*7c478bd9Sstevel@tonic-gate * lockfiles to find out what's going on are going to be a trifle 270*7c478bd9Sstevel@tonic-gate * misled. we really need to re-consider the lockfile naming structure 271*7c478bd9Sstevel@tonic-gate * to accomodate devices in directories other than /dev ... maybe in 272*7c478bd9Sstevel@tonic-gate * the next release. 273*7c478bd9Sstevel@tonic-gate */ 274*7c478bd9Sstevel@tonic-gate if ( strchr(name, '/') != NULL ) 275*7c478bd9Sstevel@tonic-gate return(0); 276*7c478bd9Sstevel@tonic-gate (void) sprintf(lname, "%s.%s", pre, BASENAME(name, '/')); 277*7c478bd9Sstevel@tonic-gate BASENAME(lname, '/')[MAXBASENAME] = '\0'; 278*7c478bd9Sstevel@tonic-gate return(mklock(lname)); 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate /* 282*7c478bd9Sstevel@tonic-gate * makes a lock on behalf of pid. 283*7c478bd9Sstevel@tonic-gate * input: 284*7c478bd9Sstevel@tonic-gate * pid - process id 285*7c478bd9Sstevel@tonic-gate * tempfile - name of a temporary in the same file system 286*7c478bd9Sstevel@tonic-gate * name - lock file name (full path name) 287*7c478bd9Sstevel@tonic-gate * return: 288*7c478bd9Sstevel@tonic-gate * -1 - failed 289*7c478bd9Sstevel@tonic-gate * 0 - lock made successfully 290*7c478bd9Sstevel@tonic-gate */ 291*7c478bd9Sstevel@tonic-gate static int 292*7c478bd9Sstevel@tonic-gate onelock(pid,tempfile,name) 293*7c478bd9Sstevel@tonic-gate char *pid; 294*7c478bd9Sstevel@tonic-gate char *tempfile, *name; 295*7c478bd9Sstevel@tonic-gate { 296*7c478bd9Sstevel@tonic-gate register int fd; 297*7c478bd9Sstevel@tonic-gate char cb[100]; 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate fd=creat(tempfile, (mode_t) 0444); 300*7c478bd9Sstevel@tonic-gate if(fd < 0){ 301*7c478bd9Sstevel@tonic-gate (void) sprintf(cb, "%s %s %d",tempfile, name, errno); 302*7c478bd9Sstevel@tonic-gate logent("ULOCKC", cb); 303*7c478bd9Sstevel@tonic-gate if((errno == EMFILE) || (errno == ENFILE)) 304*7c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 305*7c478bd9Sstevel@tonic-gate return(-1); 306*7c478bd9Sstevel@tonic-gate } 307*7c478bd9Sstevel@tonic-gate /* +1 for '\n' */ 308*7c478bd9Sstevel@tonic-gate if (write(fd, pid, SIZEOFPID+1) != (SIZEOFPID+1)) { 309*7c478bd9Sstevel@tonic-gate (void) sprintf(cb, "%s %s %d",tempfile, name, errno); 310*7c478bd9Sstevel@tonic-gate logent("ULOCKW", cb); 311*7c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 312*7c478bd9Sstevel@tonic-gate return (-1); 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate (void) chmod(tempfile, (mode_t) 0444); 315*7c478bd9Sstevel@tonic-gate (void) chown(tempfile, UUCPUID, UUCPGID); 316*7c478bd9Sstevel@tonic-gate (void) close(fd); 317*7c478bd9Sstevel@tonic-gate if(link(tempfile,name)<0){ 318*7c478bd9Sstevel@tonic-gate DEBUG(4, "%s: ", sys_errlist[errno]); 319*7c478bd9Sstevel@tonic-gate DEBUG(4, "link(%s, ", tempfile); 320*7c478bd9Sstevel@tonic-gate DEBUG(4, "%s)\n", name); 321*7c478bd9Sstevel@tonic-gate if(unlink(tempfile)< 0){ 322*7c478bd9Sstevel@tonic-gate (void) sprintf(cb, "ULK err %s %d", tempfile, errno); 323*7c478bd9Sstevel@tonic-gate logent("ULOCKLNK", cb); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate return(-1); 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate if(unlink(tempfile)<0){ 328*7c478bd9Sstevel@tonic-gate (void) sprintf(cb, "%s %d",tempfile,errno); 329*7c478bd9Sstevel@tonic-gate logent("ULOCKF", cb); 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate return(0); 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate /* 335*7c478bd9Sstevel@tonic-gate * fd_mklock(fd) - lock the device indicated by fd is possible 336*7c478bd9Sstevel@tonic-gate * 337*7c478bd9Sstevel@tonic-gate * return - 338*7c478bd9Sstevel@tonic-gate * SUCCESS - this process now has the fd locked 339*7c478bd9Sstevel@tonic-gate * FAIL - this process was not able to lock the fd 340*7c478bd9Sstevel@tonic-gate */ 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate GLOBAL int 343*7c478bd9Sstevel@tonic-gate fd_mklock(fd) 344*7c478bd9Sstevel@tonic-gate int fd; 345*7c478bd9Sstevel@tonic-gate { 346*7c478bd9Sstevel@tonic-gate int tries = 0; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate if ( fstat(fd, &_st_buf) != 0 ) 349*7c478bd9Sstevel@tonic-gate return(FAIL); 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s.%3.3lu.%3.3lu.%3.3lu", L_LOCK, 352*7c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_dev), 353*7c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_rdev), 354*7c478bd9Sstevel@tonic-gate (unsigned long) minor(_st_buf.st_rdev)); 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate if ( mklock(lockname) == FAIL ) 357*7c478bd9Sstevel@tonic-gate return(FAIL); 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate while ( lockf(fd, F_TLOCK, 0L) != 0 ) { 360*7c478bd9Sstevel@tonic-gate DEBUG(7, "fd_mklock: lockf returns %d\n", errno); 361*7c478bd9Sstevel@tonic-gate if ( (++tries >= MAX_LOCKTRY) || (errno != EAGAIN) ) { 362*7c478bd9Sstevel@tonic-gate rmlock(lockname); 363*7c478bd9Sstevel@tonic-gate logent("fd_mklock","lockf failed"); 364*7c478bd9Sstevel@tonic-gate return(FAIL); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate (void)sleep(2); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate DEBUG(7, "fd_mklock: ok\n%s", ""); 369*7c478bd9Sstevel@tonic-gate return(SUCCESS); 370*7c478bd9Sstevel@tonic-gate } 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate /* 373*7c478bd9Sstevel@tonic-gate * fn_cklock(name) - determine if the device indicated by name is locked 374*7c478bd9Sstevel@tonic-gate * 375*7c478bd9Sstevel@tonic-gate * return - 376*7c478bd9Sstevel@tonic-gate * SUCCESS - the name is not locked 377*7c478bd9Sstevel@tonic-gate * FAIL - the name is locked by another process 378*7c478bd9Sstevel@tonic-gate */ 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate GLOBAL int 381*7c478bd9Sstevel@tonic-gate fn_cklock(name) 382*7c478bd9Sstevel@tonic-gate char *name; 383*7c478bd9Sstevel@tonic-gate { 384*7c478bd9Sstevel@tonic-gate /* we temporarily use lockname to hold full path name */ 385*7c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s%s", (*name == '/' ? "" : "/dev/"), name); 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate if ( stat(lockname, &_st_buf) != 0 ) 388*7c478bd9Sstevel@tonic-gate return(FAIL); 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s.%3.3lu.%3.3lu.%3.3lu", L_LOCK, 391*7c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_dev), 392*7c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_rdev), 393*7c478bd9Sstevel@tonic-gate (unsigned long) minor(_st_buf.st_rdev)); 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate return(cklock(lockname)); 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate /* 399*7c478bd9Sstevel@tonic-gate * fd_cklock(fd) - determine if the device indicated by fd is locked 400*7c478bd9Sstevel@tonic-gate * 401*7c478bd9Sstevel@tonic-gate * return - 402*7c478bd9Sstevel@tonic-gate * SUCCESS - the fd is not locked 403*7c478bd9Sstevel@tonic-gate * FAIL - the fd is locked by another process 404*7c478bd9Sstevel@tonic-gate */ 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate GLOBAL int 407*7c478bd9Sstevel@tonic-gate fd_cklock(fd) 408*7c478bd9Sstevel@tonic-gate int fd; 409*7c478bd9Sstevel@tonic-gate { 410*7c478bd9Sstevel@tonic-gate if ( fstat(fd, &_st_buf) != 0 ) 411*7c478bd9Sstevel@tonic-gate return(FAIL); 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s.%3.3lu.%3.3lu.%3.3lu", L_LOCK, 414*7c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_dev), 415*7c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_rdev), 416*7c478bd9Sstevel@tonic-gate (unsigned long) minor(_st_buf.st_rdev)); 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate if ( cklock(lockname) == FAIL ) 419*7c478bd9Sstevel@tonic-gate return(FAIL); 420*7c478bd9Sstevel@tonic-gate else 421*7c478bd9Sstevel@tonic-gate return( lockf(fd, F_TEST, 0L) ); 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate /* 425*7c478bd9Sstevel@tonic-gate * remove the locks associated with the device file descriptor 426*7c478bd9Sstevel@tonic-gate * 427*7c478bd9Sstevel@tonic-gate * return - 428*7c478bd9Sstevel@tonic-gate * SUCCESS - both BNU lock file and advisory locks removed 429*7c478bd9Sstevel@tonic-gate * FAIL - 430*7c478bd9Sstevel@tonic-gate */ 431*7c478bd9Sstevel@tonic-gate 432*7c478bd9Sstevel@tonic-gate GLOBAL void 433*7c478bd9Sstevel@tonic-gate fd_rmlock(fd) 434*7c478bd9Sstevel@tonic-gate int fd; 435*7c478bd9Sstevel@tonic-gate { 436*7c478bd9Sstevel@tonic-gate if ( fstat(fd, &_st_buf) == 0 ) { 437*7c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s.%3.3lu.%3.3lu.%3.3lu", L_LOCK, 438*7c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_dev), 439*7c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_rdev), 440*7c478bd9Sstevel@tonic-gate (unsigned long) minor(_st_buf.st_rdev)); 441*7c478bd9Sstevel@tonic-gate rmlock(lockname); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate (void) lockf(fd, F_ULOCK, 0L); 444*7c478bd9Sstevel@tonic-gate return; 445*7c478bd9Sstevel@tonic-gate } 446