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