17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*ace1a5f1Sdp * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include "uucp.h" 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <unistd.h> 367c478bd9Sstevel@tonic-gate /* #include <sys/types.h> */ 377c478bd9Sstevel@tonic-gate /* #include <sys/stat.h> */ 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate static struct stat _st_buf; 407c478bd9Sstevel@tonic-gate static char lockname[BUFSIZ]; 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate #ifdef V7 437c478bd9Sstevel@tonic-gate #define O_RDONLY 0 447c478bd9Sstevel@tonic-gate #endif 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate static void stlock(); 477c478bd9Sstevel@tonic-gate static int onelock(); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* 507c478bd9Sstevel@tonic-gate * make a lock file with given 'name' 517c478bd9Sstevel@tonic-gate * If one already exists, send a signal 0 to the process--if 527c478bd9Sstevel@tonic-gate * it fails, then unlink it and make a new one. 537c478bd9Sstevel@tonic-gate * 547c478bd9Sstevel@tonic-gate * input: 557c478bd9Sstevel@tonic-gate * name - name of the lock file to make 567c478bd9Sstevel@tonic-gate * 577c478bd9Sstevel@tonic-gate * return: 587c478bd9Sstevel@tonic-gate * 0 -> success 597c478bd9Sstevel@tonic-gate * FAIL -> failure 607c478bd9Sstevel@tonic-gate */ 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate GLOBAL int 637c478bd9Sstevel@tonic-gate mklock(name) 647c478bd9Sstevel@tonic-gate register char *name; 657c478bd9Sstevel@tonic-gate { 667c478bd9Sstevel@tonic-gate static char pid[SIZEOFPID+2] = { '\0' }; /* +2 for '\n' and NULL */ 677c478bd9Sstevel@tonic-gate static char tempfile[MAXNAMESIZE]; 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate #ifdef V8 707c478bd9Sstevel@tonic-gate char *cp; 717c478bd9Sstevel@tonic-gate #endif 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate if (pid[0] == '\0') { 747c478bd9Sstevel@tonic-gate (void) sprintf(pid, "%*ld\n", SIZEOFPID, (long) getpid()); 757c478bd9Sstevel@tonic-gate (void) sprintf(tempfile, "%s/LTMP.%ld", X_LOCKDIR, (long) getpid()); 767c478bd9Sstevel@tonic-gate } 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate #ifdef V8 /* this wouldn't be a problem if we used lock directories */ 797c478bd9Sstevel@tonic-gate /* some day the truncation of system names will bite us */ 807c478bd9Sstevel@tonic-gate cp = rindex(name, '/'); 817c478bd9Sstevel@tonic-gate if (cp++ != CNULL) 827c478bd9Sstevel@tonic-gate if (strlen(cp) > MAXBASENAME) 837c478bd9Sstevel@tonic-gate *(cp+MAXBASENAME) = NULLCHAR; 847c478bd9Sstevel@tonic-gate #endif /* V8 */ 857c478bd9Sstevel@tonic-gate if (onelock(pid, tempfile, name) == -1) { 867c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 877c478bd9Sstevel@tonic-gate if (cklock(name)) 887c478bd9Sstevel@tonic-gate return(FAIL); 897c478bd9Sstevel@tonic-gate else { 907c478bd9Sstevel@tonic-gate if (onelock(pid, tempfile, name)) { 917c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 927c478bd9Sstevel@tonic-gate DEBUG(4,"ulockf failed in onelock()\n%s", ""); 937c478bd9Sstevel@tonic-gate return(FAIL); 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate stlock(name); 997c478bd9Sstevel@tonic-gate return(0); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate /* 1037c478bd9Sstevel@tonic-gate * check to see if the lock file exists and is still active 1047c478bd9Sstevel@tonic-gate * - use kill(pid,0) 1057c478bd9Sstevel@tonic-gate * 1067c478bd9Sstevel@tonic-gate * return: 1077c478bd9Sstevel@tonic-gate * 0 -> success (lock file removed - no longer active 1087c478bd9Sstevel@tonic-gate * FAIL -> lock file still active 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate GLOBAL int 1117c478bd9Sstevel@tonic-gate cklock(name) 1127c478bd9Sstevel@tonic-gate register char *name; 1137c478bd9Sstevel@tonic-gate { 1147c478bd9Sstevel@tonic-gate register int ret; 1157c478bd9Sstevel@tonic-gate pid_t lpid = -1; 1167c478bd9Sstevel@tonic-gate char alpid[SIZEOFPID+2]; /* +2 for '\n' and NULL */ 1177c478bd9Sstevel@tonic-gate int fd; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate fd = open(name, O_RDONLY); 1207c478bd9Sstevel@tonic-gate DEBUG(4, "ulockf name %s\n", name); 1217c478bd9Sstevel@tonic-gate if (fd == -1) { 1227c478bd9Sstevel@tonic-gate if (errno == ENOENT) /* file does not exist -- OK */ 1237c478bd9Sstevel@tonic-gate return(0); 1247c478bd9Sstevel@tonic-gate DEBUG(4,"Lock File--can't read (errno %d) --remove it!\n", errno); 1257c478bd9Sstevel@tonic-gate goto unlk; 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate ret = read(fd, (char *) alpid, SIZEOFPID+1); /* +1 for '\n' */ 1287c478bd9Sstevel@tonic-gate (void) close(fd); 1297c478bd9Sstevel@tonic-gate if (ret != (SIZEOFPID+1)) { 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate DEBUG(4, "Lock File--bad format--remove it!\n%s", ""); 1327c478bd9Sstevel@tonic-gate goto unlk; 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate lpid = (pid_t) strtol(alpid, (char **) NULL, 10); 1357c478bd9Sstevel@tonic-gate if ((ret=kill(lpid, 0)) == 0 || errno == EPERM) { 1367c478bd9Sstevel@tonic-gate DEBUG(4, "Lock File--process still active--not removed\n%s", ""); 1377c478bd9Sstevel@tonic-gate return(FAIL); 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate else { /* process no longer active */ 1407c478bd9Sstevel@tonic-gate DEBUG(4, "kill pid (%ld), ", (long) lpid); 1417c478bd9Sstevel@tonic-gate DEBUG(4, "returned %d", ret); 1427c478bd9Sstevel@tonic-gate DEBUG(4, "--ok to remove lock file (%s)\n", name); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate unlk: 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate if (unlink(name) != 0) { 1477c478bd9Sstevel@tonic-gate DEBUG(4,"ulockf failed in unlink()\n%s", ""); 1487c478bd9Sstevel@tonic-gate return(FAIL); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate return(0); 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate #define MAXLOCKS 10 /* maximum number of lock files */ 1547c478bd9Sstevel@tonic-gate static char *Lockfile[MAXLOCKS]; 1557c478bd9Sstevel@tonic-gate GLOBAL int Nlocks = 0; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate /* 1587c478bd9Sstevel@tonic-gate * put name in list of lock files 1597c478bd9Sstevel@tonic-gate * return: 1607c478bd9Sstevel@tonic-gate * none 1617c478bd9Sstevel@tonic-gate */ 1627c478bd9Sstevel@tonic-gate static void 1637c478bd9Sstevel@tonic-gate stlock(name) 1647c478bd9Sstevel@tonic-gate char *name; 1657c478bd9Sstevel@tonic-gate { 1667c478bd9Sstevel@tonic-gate register int i; 1677c478bd9Sstevel@tonic-gate char *p; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate for (i = 0; i < Nlocks; i++) { 1707c478bd9Sstevel@tonic-gate if (Lockfile[i] == NULL) 1717c478bd9Sstevel@tonic-gate break; 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", "", i); 1747c478bd9Sstevel@tonic-gate if (i >= Nlocks) 1757c478bd9Sstevel@tonic-gate i = Nlocks++; 1767c478bd9Sstevel@tonic-gate p = (char*) calloc((unsigned) strlen(name) + 1, sizeof (char)); 1777c478bd9Sstevel@tonic-gate ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", name, 0); 1787c478bd9Sstevel@tonic-gate (void) strcpy(p, name); 1797c478bd9Sstevel@tonic-gate Lockfile[i] = p; 1807c478bd9Sstevel@tonic-gate return; 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate /* 1847c478bd9Sstevel@tonic-gate * remove the named lock. If named lock is NULL, 1857c478bd9Sstevel@tonic-gate * then remove all locks currently in list. 1867c478bd9Sstevel@tonic-gate * return: 1877c478bd9Sstevel@tonic-gate * none 1887c478bd9Sstevel@tonic-gate */ 1897c478bd9Sstevel@tonic-gate GLOBAL void 1907c478bd9Sstevel@tonic-gate rmlock(name) 1917c478bd9Sstevel@tonic-gate register char *name; 1927c478bd9Sstevel@tonic-gate { 1937c478bd9Sstevel@tonic-gate register int i; 1947c478bd9Sstevel@tonic-gate #ifdef V8 1957c478bd9Sstevel@tonic-gate char *cp; 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate cp = rindex(name, '/'); 1987c478bd9Sstevel@tonic-gate if (cp++ != CNULL) 1997c478bd9Sstevel@tonic-gate if (strlen(cp) > MAXBASENAME) 2007c478bd9Sstevel@tonic-gate *(cp+MAXBASENAME) = NULLCHAR; 2017c478bd9Sstevel@tonic-gate #endif /* V8 */ 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate for (i = 0; i < Nlocks; i++) { 2057c478bd9Sstevel@tonic-gate if (Lockfile[i] == NULL) 2067c478bd9Sstevel@tonic-gate continue; 2077c478bd9Sstevel@tonic-gate if (name == NULL || EQUALS(name, Lockfile[i])) { 2087c478bd9Sstevel@tonic-gate (void) unlink(Lockfile[i]); 2097c478bd9Sstevel@tonic-gate free(Lockfile[i]); 2107c478bd9Sstevel@tonic-gate Lockfile[i] = NULL; 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate return; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate /* 2197c478bd9Sstevel@tonic-gate * remove a lock file 2207c478bd9Sstevel@tonic-gate * 2217c478bd9Sstevel@tonic-gate * Parameters: 2227c478bd9Sstevel@tonic-gate * pre - Path and first part of file name of the lock file to be 2237c478bd9Sstevel@tonic-gate * removed. 2247c478bd9Sstevel@tonic-gate * s - The suffix part of the lock file. The name of the lock file 2257c478bd9Sstevel@tonic-gate * will be derrived by concatenating pre, a period, and s. 2267c478bd9Sstevel@tonic-gate * 2277c478bd9Sstevel@tonic-gate * return: 2287c478bd9Sstevel@tonic-gate * none 2297c478bd9Sstevel@tonic-gate */ 2307c478bd9Sstevel@tonic-gate GLOBAL void 2317c478bd9Sstevel@tonic-gate delock(pre, s) 2327c478bd9Sstevel@tonic-gate char * pre; 2337c478bd9Sstevel@tonic-gate char *s; 2347c478bd9Sstevel@tonic-gate { 2357c478bd9Sstevel@tonic-gate char ln[MAXNAMESIZE]; 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate (void) sprintf(ln, "%s.%s", pre, s); 2387c478bd9Sstevel@tonic-gate BASENAME(ln, '/')[MAXBASENAME] = '\0'; 2397c478bd9Sstevel@tonic-gate rmlock(ln); 2407c478bd9Sstevel@tonic-gate return; 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate /* 2457c478bd9Sstevel@tonic-gate * create lock file 2467c478bd9Sstevel@tonic-gate * 2477c478bd9Sstevel@tonic-gate * Parameters: 2487c478bd9Sstevel@tonic-gate * pre - Path and first part of file name of the lock file to be 2497c478bd9Sstevel@tonic-gate * created. 2507c478bd9Sstevel@tonic-gate * name - The suffix part of the lock file. The name of the lock file 2517c478bd9Sstevel@tonic-gate * will be derrived by concatenating pre, a period, and name. 2527c478bd9Sstevel@tonic-gate * 2537c478bd9Sstevel@tonic-gate * return: 2547c478bd9Sstevel@tonic-gate * 0 -> success 2557c478bd9Sstevel@tonic-gate * FAIL -> failure 2567c478bd9Sstevel@tonic-gate */ 2577c478bd9Sstevel@tonic-gate GLOBAL int 2587c478bd9Sstevel@tonic-gate umlock(pre, name) 2597c478bd9Sstevel@tonic-gate char * pre; 2607c478bd9Sstevel@tonic-gate char *name; 2617c478bd9Sstevel@tonic-gate { 2627c478bd9Sstevel@tonic-gate char lname[MAXNAMESIZE]; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* 2657c478bd9Sstevel@tonic-gate * if name has a '/' in it, then it's a device name and it's 2667c478bd9Sstevel@tonic-gate * not in /dev (i.e., it's a remotely-mounted device or it's 2677c478bd9Sstevel@tonic-gate * in a subdirectory of /dev). in either case, creating our normal 2687c478bd9Sstevel@tonic-gate * lockfile (/var/spool/locks/LCK..<dev>) is going to bomb if 2697c478bd9Sstevel@tonic-gate * <dev> is "/remote/dev/term/14" or "/dev/net/foo/clone", so never 2707c478bd9Sstevel@tonic-gate * mind. since we're using advisory filelocks on the devices 2717c478bd9Sstevel@tonic-gate * themselves, it'll be safe. 2727c478bd9Sstevel@tonic-gate * 2737c478bd9Sstevel@tonic-gate * of course, programs and people who are used to looking at the 2747c478bd9Sstevel@tonic-gate * lockfiles to find out what's going on are going to be a trifle 2757c478bd9Sstevel@tonic-gate * misled. we really need to re-consider the lockfile naming structure 2767c478bd9Sstevel@tonic-gate * to accomodate devices in directories other than /dev ... maybe in 2777c478bd9Sstevel@tonic-gate * the next release. 2787c478bd9Sstevel@tonic-gate */ 2797c478bd9Sstevel@tonic-gate if ( strchr(name, '/') != NULL ) 2807c478bd9Sstevel@tonic-gate return(0); 2817c478bd9Sstevel@tonic-gate (void) sprintf(lname, "%s.%s", pre, BASENAME(name, '/')); 2827c478bd9Sstevel@tonic-gate BASENAME(lname, '/')[MAXBASENAME] = '\0'; 2837c478bd9Sstevel@tonic-gate return(mklock(lname)); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate /* 2877c478bd9Sstevel@tonic-gate * makes a lock on behalf of pid. 2887c478bd9Sstevel@tonic-gate * input: 2897c478bd9Sstevel@tonic-gate * pid - process id 2907c478bd9Sstevel@tonic-gate * tempfile - name of a temporary in the same file system 2917c478bd9Sstevel@tonic-gate * name - lock file name (full path name) 2927c478bd9Sstevel@tonic-gate * return: 2937c478bd9Sstevel@tonic-gate * -1 - failed 2947c478bd9Sstevel@tonic-gate * 0 - lock made successfully 2957c478bd9Sstevel@tonic-gate */ 2967c478bd9Sstevel@tonic-gate static int 2977c478bd9Sstevel@tonic-gate onelock(pid,tempfile,name) 2987c478bd9Sstevel@tonic-gate char *pid; 2997c478bd9Sstevel@tonic-gate char *tempfile, *name; 3007c478bd9Sstevel@tonic-gate { 3017c478bd9Sstevel@tonic-gate register int fd; 3027c478bd9Sstevel@tonic-gate char cb[100]; 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate fd=creat(tempfile, (mode_t) 0444); 3057c478bd9Sstevel@tonic-gate if(fd < 0){ 3067c478bd9Sstevel@tonic-gate (void) sprintf(cb, "%s %s %d",tempfile, name, errno); 3077c478bd9Sstevel@tonic-gate logent("ULOCKC", cb); 3087c478bd9Sstevel@tonic-gate if((errno == EMFILE) || (errno == ENFILE)) 3097c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 3107c478bd9Sstevel@tonic-gate return(-1); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate /* +1 for '\n' */ 3137c478bd9Sstevel@tonic-gate if (write(fd, pid, SIZEOFPID+1) != (SIZEOFPID+1)) { 3147c478bd9Sstevel@tonic-gate (void) sprintf(cb, "%s %s %d",tempfile, name, errno); 3157c478bd9Sstevel@tonic-gate logent("ULOCKW", cb); 3167c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 3177c478bd9Sstevel@tonic-gate return (-1); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate (void) chmod(tempfile, (mode_t) 0444); 3207c478bd9Sstevel@tonic-gate (void) chown(tempfile, UUCPUID, UUCPGID); 3217c478bd9Sstevel@tonic-gate (void) close(fd); 3227c478bd9Sstevel@tonic-gate if(link(tempfile,name)<0){ 323*ace1a5f1Sdp DEBUG(4, "%s: ", strerror(errno)); 3247c478bd9Sstevel@tonic-gate DEBUG(4, "link(%s, ", tempfile); 3257c478bd9Sstevel@tonic-gate DEBUG(4, "%s)\n", name); 3267c478bd9Sstevel@tonic-gate if(unlink(tempfile)< 0){ 3277c478bd9Sstevel@tonic-gate (void) sprintf(cb, "ULK err %s %d", tempfile, errno); 3287c478bd9Sstevel@tonic-gate logent("ULOCKLNK", cb); 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate return(-1); 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate if(unlink(tempfile)<0){ 3337c478bd9Sstevel@tonic-gate (void) sprintf(cb, "%s %d",tempfile,errno); 3347c478bd9Sstevel@tonic-gate logent("ULOCKF", cb); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate return(0); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate /* 3407c478bd9Sstevel@tonic-gate * fd_mklock(fd) - lock the device indicated by fd if possible 3417c478bd9Sstevel@tonic-gate * 3427c478bd9Sstevel@tonic-gate * return - 3437c478bd9Sstevel@tonic-gate * SUCCESS - this process now has the fd locked 3447c478bd9Sstevel@tonic-gate * FAIL - this process was not able to lock the fd 3457c478bd9Sstevel@tonic-gate */ 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate GLOBAL int 3487c478bd9Sstevel@tonic-gate fd_mklock(fd) 3497c478bd9Sstevel@tonic-gate int fd; 3507c478bd9Sstevel@tonic-gate { 3517c478bd9Sstevel@tonic-gate int tries = 0; 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate if ( fstat(fd, &_st_buf) != 0 ) 3547c478bd9Sstevel@tonic-gate return(FAIL); 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s.%3.3lu.%3.3lu.%3.3lu", L_LOCK, 3577c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_dev), 3587c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_rdev), 3597c478bd9Sstevel@tonic-gate (unsigned long) minor(_st_buf.st_rdev)); 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate if ( mklock(lockname) == FAIL ) 3627c478bd9Sstevel@tonic-gate return(FAIL); 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate while ( lockf(fd, F_TLOCK, 0L) != 0 ) { 3657c478bd9Sstevel@tonic-gate DEBUG(7, "fd_mklock: lockf returns %d\n", errno); 3667c478bd9Sstevel@tonic-gate if ( (++tries >= MAX_LOCKTRY) || (errno != EAGAIN) ) { 3677c478bd9Sstevel@tonic-gate rmlock(lockname); 3687c478bd9Sstevel@tonic-gate logent("fd_mklock","lockf failed"); 3697c478bd9Sstevel@tonic-gate return(FAIL); 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate sleep(2); 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate DEBUG(7, "fd_mklock: ok\n%s", ""); 3747c478bd9Sstevel@tonic-gate return(SUCCESS); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate /* 3787c478bd9Sstevel@tonic-gate * fn_cklock(name) - determine if the device indicated by name is locked 3797c478bd9Sstevel@tonic-gate * 3807c478bd9Sstevel@tonic-gate * return - 3817c478bd9Sstevel@tonic-gate * SUCCESS - the name is not locked 3827c478bd9Sstevel@tonic-gate * FAIL - the name is locked by another process 3837c478bd9Sstevel@tonic-gate */ 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate GLOBAL int 3867c478bd9Sstevel@tonic-gate fn_cklock(name) 3877c478bd9Sstevel@tonic-gate char *name; 3887c478bd9Sstevel@tonic-gate { 3897c478bd9Sstevel@tonic-gate /* we temporarily use lockname to hold full path name */ 3907c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s%s", (*name == '/' ? "" : "/dev/"), name); 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate if ( stat(lockname, &_st_buf) != 0 ) 3937c478bd9Sstevel@tonic-gate return(FAIL); 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s.%3.3lu.%3.3lu.%3.3lu", L_LOCK, 3967c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_dev), 3977c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_rdev), 3987c478bd9Sstevel@tonic-gate (unsigned long) minor(_st_buf.st_rdev)); 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate return(cklock(lockname)); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate /* 4047c478bd9Sstevel@tonic-gate * fd_cklock(fd) - determine if the device indicated by fd is locked 4057c478bd9Sstevel@tonic-gate * 4067c478bd9Sstevel@tonic-gate * return - 4077c478bd9Sstevel@tonic-gate * SUCCESS - the fd is not locked 4087c478bd9Sstevel@tonic-gate * FAIL - the fd is locked by another process 4097c478bd9Sstevel@tonic-gate */ 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate GLOBAL int 4127c478bd9Sstevel@tonic-gate fd_cklock(fd) 4137c478bd9Sstevel@tonic-gate int fd; 4147c478bd9Sstevel@tonic-gate { 4157c478bd9Sstevel@tonic-gate if ( fstat(fd, &_st_buf) != 0 ) 4167c478bd9Sstevel@tonic-gate return(FAIL); 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s.%3.3lu.%3.3lu.%3.3lu", L_LOCK, 4197c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_dev), 4207c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_rdev), 4217c478bd9Sstevel@tonic-gate (unsigned long) minor(_st_buf.st_rdev)); 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate if ( cklock(lockname) == FAIL ) 4247c478bd9Sstevel@tonic-gate return(FAIL); 4257c478bd9Sstevel@tonic-gate else 4267c478bd9Sstevel@tonic-gate return( lockf(fd, F_TEST, 0L) ); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate /* 4307c478bd9Sstevel@tonic-gate * remove the locks associated with the device file descriptor 4317c478bd9Sstevel@tonic-gate * 4327c478bd9Sstevel@tonic-gate * return - 4337c478bd9Sstevel@tonic-gate * SUCCESS - both BNU lock file and advisory locks removed 4347c478bd9Sstevel@tonic-gate * FAIL - 4357c478bd9Sstevel@tonic-gate */ 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate GLOBAL void 4387c478bd9Sstevel@tonic-gate fd_rmlock(fd) 4397c478bd9Sstevel@tonic-gate int fd; 4407c478bd9Sstevel@tonic-gate { 4417c478bd9Sstevel@tonic-gate if ( fstat(fd, &_st_buf) == 0 ) { 4427c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%s.%3.3lu.%3.3lu.%3.3lu", L_LOCK, 4437c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_dev), 4447c478bd9Sstevel@tonic-gate (unsigned long) major(_st_buf.st_rdev), 4457c478bd9Sstevel@tonic-gate (unsigned long) minor(_st_buf.st_rdev)); 4467c478bd9Sstevel@tonic-gate rmlock(lockname); 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate (void) lockf(fd, F_ULOCK, 0L); 4497c478bd9Sstevel@tonic-gate return; 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate #ifdef BSD4_2 4537c478bd9Sstevel@tonic-gate #include <sys/file.h> 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate static int 4567c478bd9Sstevel@tonic-gate lockf(fd, cmd, size) 4577c478bd9Sstevel@tonic-gate int fd, cmd; 4587c478bd9Sstevel@tonic-gate long size; 4597c478bd9Sstevel@tonic-gate { 4607c478bd9Sstevel@tonic-gate int ret; 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate if (size != 0) { 4637c478bd9Sstevel@tonic-gate errno = EINVAL; 4647c478bd9Sstevel@tonic-gate return (-1); 4657c478bd9Sstevel@tonic-gate } 4667c478bd9Sstevel@tonic-gate switch (cmd) { 4677c478bd9Sstevel@tonic-gate case F_LOCK: 4687c478bd9Sstevel@tonic-gate cmd = LOCK_EX; 4697c478bd9Sstevel@tonic-gate break; 4707c478bd9Sstevel@tonic-gate case F_TLOCK: 4717c478bd9Sstevel@tonic-gate cmd = LOCK_EX|LOCK_NB; 4727c478bd9Sstevel@tonic-gate break; 4737c478bd9Sstevel@tonic-gate case F_ULOCK: 4747c478bd9Sstevel@tonic-gate cmd = LOCK_UN; 4757c478bd9Sstevel@tonic-gate break; 4767c478bd9Sstevel@tonic-gate case F_TEST: 4777c478bd9Sstevel@tonic-gate if (flock(fd, LOCK_EX|LOCK_NB) == 0 && flock(fd, LOCK_UN) == 0) 4787c478bd9Sstevel@tonic-gate return (0); 4797c478bd9Sstevel@tonic-gate errno = EAGAIN; 4807c478bd9Sstevel@tonic-gate return (-1); 4817c478bd9Sstevel@tonic-gate default: 4827c478bd9Sstevel@tonic-gate errno = EINVAL; 4837c478bd9Sstevel@tonic-gate return (-1); 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate ret = flock(fd, cmd); 4867c478bd9Sstevel@tonic-gate if (ret < 0 && errno == EWOULDBLOCK) 4877c478bd9Sstevel@tonic-gate errno = EAGAIN; 4887c478bd9Sstevel@tonic-gate } 4897c478bd9Sstevel@tonic-gate #endif /* BSD4_2 */ 490