delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/12/29/21:21:12

Message-Id: <5.0.2.1.0.20001229205411.00a53560@pop5.banet.net>
X-Sender: usbanet DOT farley3 AT pop5 DOT banet DOT net
X-Mailer: QUALCOMM Windows Eudora Version 5.0.2
Date: Fri, 29 Dec 2000 20:55:31 -0500
To: djgpp-workers AT delorie DOT com
From: "Peter J. Farley III" <pjfarley AT banet DOT net>
Subject: RE: fcntl locking changes #3: new functions flock/lockf/llockf
Mime-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

--=====================_11067657==_
Content-Type: text/plain; charset="us-ascii"; format=flowed

And then I forgot to put in the patch.  I *really* have to get more 
sleep, Real Soon Now.

This is the right subject, right patch -- the prior flock patch left 
out the flock function, now included.

Sorry again for the confusion.

--=====================_11067657==_
Content-Type: text/plain; charset="us-ascii"

diff -ruN djgpp-cvs/include/sys/file.h djgpp/include/sys/file.h
--- djgpp-cvs/include/sys/file.h	Thu Apr 20 01:35:34 1995
+++ djgpp/include/sys/file.h	Mon Dec 11 21:56:46 2000
@@ -22,6 +22,18 @@
 #define L_CURR 1
 #define L_INCR 1
 #define L_XTND 2
+
+/* Operations for the `flock' call.  */
+#define	LOCK_SH	1	/* Shared lock.  */
+#define	LOCK_EX	2 	/* Exclusive lock.  */
+#define	LOCK_UN	8	/* Unlock.  */
+
+/* Can be OR'd in to one of the above.  */
+#define	LOCK_NB	4	/* Don't block when locking.  */
+
+/* Apply or remove an advisory lock, according to OPERATION,
+   on the file FD refers to.  */
+int	flock (int _fildes, int _op);
   
 #ifndef __dj_ENFORCE_FUNCTION_CALLS
 #endif /* !__dj_ENFORCE_FUNCTION_CALLS */
diff -ruN djgpp-cvs/include/unistd.h djgpp/include/unistd.h
--- djgpp-cvs/include/unistd.h	Fri Dec 29 04:48:04 2000
+++ djgpp/include/unistd.h	Fri Dec 29 06:22:08 2000
@@ -18,7 +18,16 @@
 #define SEEK_SET	0
 #define SEEK_CUR	1
 #define SEEK_END	2
-  
+
+/* `lockf' is a simpler interface to the locking facilities of `fcntl'.
+   LEN is always relative to the current file position.
+   The CMD argument is one of the following.  */
+
+# define F_ULOCK 0	/* Unlock a previously locked region.  */
+# define F_LOCK  1	/* Lock a region for exclusive use.  */
+# define F_TLOCK 2	/* Test and lock a region for exclusive use.  */
+# define F_TEST  3	/* Test a region for other processes locks.  */
+
 /* Some programs think they know better... */
 #undef NULL
 
@@ -61,7 +70,7 @@
 #define _SC_TZNAME_MAX		9
 #define _SC_VERSION		10
 
-#ifndef _SIZE_T 
+#ifndef _SIZE_T
 __DJ_size_t
 #define _SIZE_T
 #endif
@@ -138,6 +147,8 @@
 int		getpagesize(void);
 char *		getwd(char *__buffer);
 int             lchown(const char * file, int owner, int group);
+int		lockf(int _fildes, int _cmd, off_t _len);
+int		llockf(int _fildes, int _cmd, offset_t _len);
 offset_t	llseek(int _fildes, offset_t _offset, int _whence);
 int		nice(int _increment);
 int             readlink(const char * __file, char * __buffer, size_t __size);
diff -ruN djgpp-cvs/tests/libc/compat/unistd/makefile djgpp/tests/libc/compat/unistd/makefile
--- djgpp-cvs/tests/libc/compat/unistd/makefile	Fri Aug 25 07:37:10 2000
+++ djgpp/tests/libc/compat/unistd/makefile	Mon Dec 11 21:56:52 2000
@@ -3,6 +3,8 @@
 SRC += readlink.c
 SRC += sdirlink.c
 SRC += symlink.c
+SRC += tlockf.c
+SRC += tllockf.c
 SRC += xsymlink.c
 
 include $(TOP)/../makefile.inc
diff -ruN djgpp-cvs/tests/libc/compat/unistd/tllockf.c djgpp/tests/libc/compat/unistd/tllockf.c
--- djgpp-cvs/tests/libc/compat/unistd/tllockf.c	Thu Jan  1 00:00:00 1970
+++ djgpp/tests/libc/compat/unistd/tllockf.c	Mon Dec 11 21:56:52 2000
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <strings.h>
+#include <dos.h>
+#include <libc/dosio.h>
+
+void prdoserr(int fd) {
+  struct DOSERROR de;
+  struct DOSERROR_STR se;
+  int errsave;
+
+  printf("fd: %i\n", fd);
+  printf("errno: %i : %s\n", errno, strerror(errno));
+  dosexterr(&de);
+  errsave = de.exterror;
+  de.exterror = _doserrno;
+  dostrerr(&de, &se);
+  printf("DOS errno: %i : %s\n", _doserrno, se.exterror_str);
+  de.exterror = errsave;
+  dostrerr(&de, &se);
+  printf("DOS extended error to errno: %i : %s\n",
+    __doserr_to_errno(de.exterror),strerror(__doserr_to_errno(de.exterror)));
+  printf("Extended DOS error information:\n");
+  printf("Extended error: %i : %s\n",de.exterror,se.exterror_str);
+  printf("Class:          %02X : %s\n",de.class,se.class_str);
+  printf("Action:         %02X : %s\n",de.action,se.action_str);
+  printf("Error Locus:    %02X : %s\n",de.locus,se.locus_str);
+}
+
+
+int main(void) {
+  int retval, fd;
+
+  fd = open("tllockf.c", O_RDONLY);
+
+  errno = 0;
+  retval = llockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = llockf(fd, F_TLOCK, 0);
+  printf("F_TLOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = llockf(fd, F_TLOCK, 0);
+  printf("F_TLOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = llockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = llockf(fd, F_ULOCK, 0);
+  printf("F_ULOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = llockf(fd, F_ULOCK, 0);
+  printf("F_ULOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = llockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = llockf(fd, F_LOCK, 0);
+  printf("F_LOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  /* This call will lock the program in an endless loop,
+     since it already has the lock.
+
+     FIXME -- Need to add SIGINT interrupt handler and
+              console output (syserr?) telling user to
+              press CNTL-Break to continue the test.
+
+     Commented out for now, replaced with message about bypass.
+
+  errno = 0;
+  retval = llockf(fd, F_LOCK, 0);
+  printf("F_LOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  */
+
+  printf("F_LOCK:Bypassed to avoid lockup in endless loop.\n");
+
+  errno = 0;
+  retval = llockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = llockf(fd, F_ULOCK, 0);
+  printf("F_ULOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = llockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  close(fd);
+  exit(0);
+}
diff -ruN djgpp-cvs/tests/libc/compat/unistd/tllockf.ok djgpp/tests/libc/compat/unistd/tllockf.ok
--- djgpp-cvs/tests/libc/compat/unistd/tllockf.ok	Thu Jan  1 00:00:00 1970
+++ djgpp/tests/libc/compat/unistd/tllockf.ok	Fri Dec 29 05:15:40 2000
@@ -0,0 +1,48 @@
+F_TEST:retval=0
+F_TLOCK:retval=0
+F_TLOCK:retval=-1
+fd: 5
+errno: 4 : Permission denied (EACCES)
+DOS errno: 33 : Lock violation
+DOS extended error to errno: 4 : Permission denied (EACCES)
+Extended DOS error information:
+Extended error: 33 : Lock violation
+Class:          0A : Media error
+Action:         02 : Prompt user to reenter input
+Error Locus:    02 : Network related
+F_TEST:retval=-1
+fd: 5
+errno: 4 : Permission denied (EACCES)
+DOS errno: 33 : Lock violation
+DOS extended error to errno: 4 : Permission denied (EACCES)
+Extended DOS error information:
+Extended error: 33 : Lock violation
+Class:          0A : Media error
+Action:         02 : Prompt user to reenter input
+Error Locus:    02 : Network related
+F_ULOCK:retval=0
+F_ULOCK:retval=-1
+fd: 5
+errno: 4 : Permission denied (EACCES)
+DOS errno: 33 : Lock violation
+DOS extended error to errno: 4 : Permission denied (EACCES)
+Extended DOS error information:
+Extended error: 33 : Lock violation
+Class:          0A : Media error
+Action:         02 : Prompt user to reenter input
+Error Locus:    02 : Network related
+F_TEST:retval=0
+F_LOCK:retval=0
+F_LOCK:Bypassed to avoid lockup in endless loop.
+F_TEST:retval=-1
+fd: 5
+errno: 4 : Permission denied (EACCES)
+DOS errno: 33 : Lock violation
+DOS extended error to errno: 4 : Permission denied (EACCES)
+Extended DOS error information:
+Extended error: 33 : Lock violation
+Class:          0A : Media error
+Action:         02 : Prompt user to reenter input
+Error Locus:    02 : Network related
+F_ULOCK:retval=0
+F_TEST:retval=0
diff -ruN djgpp-cvs/tests/libc/compat/unistd/tlockf.c djgpp/tests/libc/compat/unistd/tlockf.c
--- djgpp-cvs/tests/libc/compat/unistd/tlockf.c	Thu Jan  1 00:00:00 1970
+++ djgpp/tests/libc/compat/unistd/tlockf.c	Mon Dec 11 21:56:52 2000
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <strings.h>
+#include <dos.h>
+#include <libc/dosio.h>
+
+void prdoserr(int fd) {
+  struct DOSERROR de;
+  struct DOSERROR_STR se;
+  int errsave;
+
+  printf("fd: %i\n", fd);
+  printf("errno: %i : %s\n", errno, strerror(errno));
+  dosexterr(&de);
+  errsave = de.exterror;
+  de.exterror = _doserrno;
+  dostrerr(&de, &se);
+  printf("DOS errno: %i : %s\n", _doserrno, se.exterror_str);
+  de.exterror = errsave;
+  dostrerr(&de, &se);
+  printf("DOS extended error to errno: %i : %s\n",
+    __doserr_to_errno(de.exterror),strerror(__doserr_to_errno(de.exterror)));
+  printf("Extended DOS error information:\n");
+  printf("Extended error: %i : %s\n",de.exterror,se.exterror_str);
+  printf("Class:          %02X : %s\n",de.class,se.class_str);
+  printf("Action:         %02X : %s\n",de.action,se.action_str);
+  printf("Error Locus:    %02X : %s\n",de.locus,se.locus_str);
+}
+
+
+int main(void) {
+  int retval, fd;
+
+  fd = open("tlockf.c", O_RDONLY);
+
+  errno = 0;
+  retval = lockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = lockf(fd, F_TLOCK, 0);
+  printf("F_TLOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = lockf(fd, F_TLOCK, 0);
+  printf("F_TLOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = lockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = lockf(fd, F_ULOCK, 0);
+  printf("F_ULOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = lockf(fd, F_ULOCK, 0);
+  printf("F_ULOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = lockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = lockf(fd, F_LOCK, 0);
+  printf("F_LOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  /* This call will lock the program in an endless loop,
+     since it already has the lock.
+
+     FIXME -- Need to add SIGINT interrupt handler and
+              console output (syserr?) telling user to
+              press CNTL-Break to continue the test.
+
+     Commented out for now, replaced with message about bypass.
+
+  errno = 0;
+  retval = lockf(fd, F_LOCK, 0);
+  printf("F_LOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  */
+
+  printf("F_LOCK:Bypassed to avoid lockup in endless loop.\n");
+
+  errno = 0;
+  retval = lockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = lockf(fd, F_ULOCK, 0);
+  printf("F_ULOCK:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  errno = 0;
+  retval = lockf(fd, F_TEST, 0);
+  printf("F_TEST:retval=%d\n", retval);
+  if ((retval < 0) && (errno != 0)) prdoserr(fd);
+
+  close(fd);
+  exit(0);
+}
diff -ruN djgpp-cvs/tests/libc/compat/unistd/tlockf.ok djgpp/tests/libc/compat/unistd/tlockf.ok
--- djgpp-cvs/tests/libc/compat/unistd/tlockf.ok	Thu Jan  1 00:00:00 1970
+++ djgpp/tests/libc/compat/unistd/tlockf.ok	Fri Dec 29 05:15:32 2000
@@ -0,0 +1,48 @@
+F_TEST:retval=0
+F_TLOCK:retval=0
+F_TLOCK:retval=-1
+fd: 5
+errno: 4 : Permission denied (EACCES)
+DOS errno: 33 : Lock violation
+DOS extended error to errno: 4 : Permission denied (EACCES)
+Extended DOS error information:
+Extended error: 33 : Lock violation
+Class:          0A : Media error
+Action:         02 : Prompt user to reenter input
+Error Locus:    02 : Network related
+F_TEST:retval=-1
+fd: 5
+errno: 4 : Permission denied (EACCES)
+DOS errno: 33 : Lock violation
+DOS extended error to errno: 4 : Permission denied (EACCES)
+Extended DOS error information:
+Extended error: 33 : Lock violation
+Class:          0A : Media error
+Action:         02 : Prompt user to reenter input
+Error Locus:    02 : Network related
+F_ULOCK:retval=0
+F_ULOCK:retval=-1
+fd: 5
+errno: 4 : Permission denied (EACCES)
+DOS errno: 33 : Lock violation
+DOS extended error to errno: 4 : Permission denied (EACCES)
+Extended DOS error information:
+Extended error: 33 : Lock violation
+Class:          0A : Media error
+Action:         02 : Prompt user to reenter input
+Error Locus:    02 : Network related
+F_TEST:retval=0
+F_LOCK:retval=0
+F_LOCK:Bypassed to avoid lockup in endless loop.
+F_TEST:retval=-1
+fd: 5
+errno: 4 : Permission denied (EACCES)
+DOS errno: 33 : Lock violation
+DOS extended error to errno: 4 : Permission denied (EACCES)
+Extended DOS error information:
+Extended error: 33 : Lock violation
+Class:          0A : Media error
+Action:         02 : Prompt user to reenter input
+Error Locus:    02 : Network related
+F_ULOCK:retval=0
+F_TEST:retval=0
diff -ruN djgpp-cvs/src/libc/compat/unistd/llockf.c djgpp/src/libc/compat/unistd/llockf.c
--- djgpp-cvs/src/libc/compat/unistd/llockf.c	Thu Jan  1 00:00:00 1970
+++ djgpp/src/libc/compat/unistd/llockf.c	Mon Dec 11 21:56:58 2000
@@ -0,0 +1,55 @@
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+
+/* lockf is a simplified interface to fcntl's locking facilities.  */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+int
+llockf (int _fildes, int _cmd, offset_t _len)
+{
+  struct flock64 lock_req;
+
+  memset ((char *) &lock_req, '\0', sizeof (lock_req));
+
+  /* lockf is always relative to the current file position.  */
+  lock_req.l_whence = SEEK_CUR;
+  lock_req.l_start = 0L;
+  lock_req.l_len = _len;
+
+  switch (_cmd)
+    {
+    case F_TEST:
+      lock_req.l_type = F_WRLCK;
+      /* Test the lock: return 0 if FD is unlocked;
+	return -1, set errno to EACCES, if the lock cannot be obtained.  */
+      if (fcntl (_fildes, F_GETLK64, &lock_req) < 0)
+	return -1;
+      if (lock_req.l_type == F_UNLCK)
+	return 0;
+      errno = EACCES;
+      return -1;
+
+    case F_ULOCK:
+      lock_req.l_type = F_UNLCK;
+      _cmd = F_SETLK64;
+      break;
+    case F_LOCK:
+      lock_req.l_type = F_WRLCK;
+      _cmd = F_SETLKW64;
+      break;
+    case F_TLOCK:
+      lock_req.l_type = F_WRLCK;
+      _cmd = F_SETLK64;
+      break;
+
+    default:
+      errno = EINVAL;
+      return -1;
+    }
+
+  return fcntl (_fildes, _cmd, &lock_req);
+}
diff -ruN djgpp-cvs/src/libc/compat/unistd/llockf.txh djgpp/src/libc/compat/unistd/llockf.txh
--- djgpp-cvs/src/libc/compat/unistd/llockf.txh	Thu Jan  1 00:00:00 1970
+++ djgpp/src/libc/compat/unistd/llockf.txh	Sat Dec 16 01:20:20 2000
@@ -0,0 +1,128 @@
+@node llockf, unistd
+@subheading Syntax
+
+@example
+#include <unistd.h>
+
+int llockf (int fildes, int function, offset_t size);
+@end example
+
+@subheading Description
+
+The @code{llockf} command is a simplified interface to the locking
+facilities of @code{fcntl} (see @ref{fcntl} for more detailed
+information).
+
+The @code{llockf} command performs exactly the same functions as
+@code{lockf} (see @pxref{lockf}), with exactly the same input commands
+and results, but the input @var{size} parameter is of type
+@code{offset_t} instead of @code{off_t}, and the @code{fcntl} calls are
+made using functions @code{F_GETLK64}, @code{F_SETLK64} and
+@code{F_SETLKW64}, where @code{lockf} uses functions @code{F_GETLK},
+@code{F_SETLK} and @code{F_SETLKW}.
+
+The @code{llockf} command is intended to permit using @code{fcntl}
+functions with @var{size} values greater than @math{2^31 - 1}.
+
+@var{fildes} is an open file descriptor.
+
+@var{function} is a control value which specifies the action to be
+taken.  The permissible values for function are defined in <unistd.h> as
+follows:
+
+@example
+#define   F_ULOCK   0   /* Unlock a previously locked section */
+#define   F_LOCK    1   /* Lock a section for exclusive use */
+#define   F_TLOCK   2   /* Test and lock a section for exclusive use */
+#define   F_TEST    3   /* Test section for other locks */
+@end example
+
+All other values of @var{function} are reserved for future extensions
+and will result in an error return if not implemented, with @code{errno}
+set to @code{EINVAL}.
+
+@var{size} is the number of contiguous bytes to be locked or unlocked.
+The resource to be locked starts at the current offset in the file and
+extends forward for a positive @var{size} and backward for a negative
+@var{size} (the preceding bytes up to but not including the current
+offset).  If @var{size} is zero, the section from the current offset
+through the largest file offset is locked (i.e., from the current offset
+through the end-of-file).
+
+The functions defined for @code{llockf} are as follows:
+
+@table @code
+@item F_TEST
+This function is used to detect if the specified section is already
+locked.
+
+@itemx F_LOCK
+@itemx F_TLOCK
+@code{F_LOCK} and @code{F_TLOCK} both lock a section of a file, if the
+section is available.  These two function requests differ only by the
+action taken if the resource is not available.  @code{F_LOCK} will cause
+the calling program to wait until the resource is available.
+@code{F_TLOCK} will cause the function to return a -1 and set
+@code{errno} to error @code{EACCES} if the section is already locked.
+
+@itemx F_ULOCK
+@code{F_ULOCK} removes locks from a section of the file. This function
+will release locked sections controlled by the program.
+@end table
+
+The @code{llockf} command will fail, returning -1 and setting
+@code{errno} to the following error values if the associated condition
+is true:
+
+@table @code
+@item EBADF
+Parameter @var{fildes} is not a valid open file.
+
+@itemx EACCES
+Parameter @var{function} is @code{F_TLOCK} or @code{F_TEST} and the
+section is already locked.
+
+@itemx EINVAL
+Parameter @var{function} is not one of the implemented functions.
+@end table
+
+All lock requests in this implementation are coded as exclusive locks
+(i.e., all locks use the @code{fcntl} request @code{F_WRLCK}).
+
+It is therefore wise to code @code{llockf} by using function
+@code{F_TLOCK} with all lock requests, and to test the return value to
+determine if the lock was obtained or not.  Using @code{F_TLOCK} will
+cause the implementation to use @code{F_SETLK} instead of
+@code{F_SETLKW}, which will return an error if the lock cannot be
+obtained.
+
+
+@subheading Return Value
+
+On success, zero is returned.  On error, -1 is returned, and
+@code{errno} is set appropriately, as described above.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+ /* Request a lock on file handle fd from the current position to
+    the end of the file */
+  errno = 0;
+  retval = llockf(fd, F_LOCK, 0);
+
+ /* Request a non-blocking lock on file handle fd */
+  errno = 0;
+  retval = llockf(fd, F_TLOCK, 0);
+
+ /* Test a lock on file handle fd */
+  errno = 0;
+  retval = llockf(fd, F_TEST, 0);
+
+ /* Release a lock on file handle fd */
+  errno = 0;
+  retval = llockf(fd, F_ULOCK, 0);
+@end example
diff -ruN djgpp-cvs/src/libc/compat/unistd/lockf.c djgpp/src/libc/compat/unistd/lockf.c
--- djgpp-cvs/src/libc/compat/unistd/lockf.c	Thu Jan  1 00:00:00 1970
+++ djgpp/src/libc/compat/unistd/lockf.c	Mon Dec 11 21:56:58 2000
@@ -0,0 +1,55 @@
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+
+/* lockf is a simplified interface to fcntl's locking facilities.  */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+int
+lockf (int _fildes, int _cmd, off_t _len)
+{
+  struct flock lock_req;
+
+  memset ((char *) &lock_req, '\0', sizeof (lock_req));
+
+  /* lockf is always relative to the current file position.  */
+  lock_req.l_whence = SEEK_CUR;
+  lock_req.l_start = 0;
+  lock_req.l_len = _len;
+
+  switch (_cmd)
+    {
+    case F_TEST:
+      lock_req.l_type = F_WRLCK;
+      /* Test the lock: return 0 if FD is unlocked;
+	return -1, set errno to EACCES, if the lock cannot be obtained.  */
+      if (fcntl (_fildes, F_GETLK, &lock_req) < 0)
+	return -1;
+      if (lock_req.l_type == F_UNLCK)
+	return 0;
+      errno = EACCES;
+      return -1;
+
+    case F_ULOCK:
+      lock_req.l_type = F_UNLCK;
+      _cmd = F_SETLK;
+      break;
+    case F_LOCK:
+      lock_req.l_type = F_WRLCK;
+      _cmd = F_SETLKW;
+      break;
+    case F_TLOCK:
+      lock_req.l_type = F_WRLCK;
+      _cmd = F_SETLK;
+      break;
+
+    default:
+      errno = EINVAL;
+      return -1;
+    }
+
+  return fcntl (_fildes, _cmd, &lock_req);
+}
diff -ruN djgpp-cvs/src/libc/compat/unistd/lockf.txh djgpp/src/libc/compat/unistd/lockf.txh
--- djgpp-cvs/src/libc/compat/unistd/lockf.txh	Thu Jan  1 00:00:00 1970
+++ djgpp/src/libc/compat/unistd/lockf.txh	Tue Dec 12 22:58:50 2000
@@ -0,0 +1,117 @@
+@node lockf, unistd
+@subheading Syntax
+
+@example
+#include <unistd.h>
+
+int lockf (int fildes, int function, off_t size);
+@end example
+
+@subheading Description
+
+The @code{lockf} command is a simplified interface to the locking
+facilities of @code{fcntl} (see @ref{fcntl} for more detailed
+information).
+
+@var{fildes} is an open file descriptor.
+
+@var{function} is a control value which specifies the action to be
+taken.  The permissible values for function are defined in <unistd.h> as
+follows:
+
+@example
+#define   F_ULOCK   0   /* Unlock a previously locked section */
+#define   F_LOCK    1   /* Lock a section for exclusive use */
+#define   F_TLOCK   2   /* Test and lock a section for exclusive use */
+#define   F_TEST    3   /* Test section for other locks */
+@end example
+
+All other values of @var{function} are reserved for future extensions
+and will result in an error return if not implemented, with @code{errno}
+set to @code{EINVAL}.
+
+@var{size} is the number of contiguous bytes to be locked or unlocked.
+The resource to be locked starts at the current offset in the file and
+extends forward for a positive @var{size} and backward for a negative
+@var{size} (the preceding bytes up to but not including the current
+offset).  If @var{size} is zero, the section from the current offset
+through the largest file offset is locked (i.e., from the current offset
+through the end-of-file).
+
+The functions defined for @code{lockf} are as follows:
+
+@table @code
+@item F_TEST
+This function is used to detect if the specified section is already
+locked.
+
+@itemx F_LOCK
+@itemx F_TLOCK
+@code{F_LOCK} and @code{F_TLOCK} both lock a section of a file, if the
+section is available.  These two function requests differ only by the
+action taken if the resource is not available.  @code{F_LOCK} will cause
+the calling program to wait until the resource is available.
+@code{F_TLOCK} will cause the function to return a -1 and set
+@code{errno} to error @code{EACCES} if the section is already locked.
+
+@itemx F_ULOCK
+@code{F_ULOCK} removes locks from a section of the file. This function
+will release locked sections controlled by the program.
+@end table
+
+The @code{lockf} command will fail, returning -1 and setting
+@code{errno} to the following error values if the associated condition
+is true:
+
+@table @code
+@item EBADF
+Parameter @var{fildes} is not a valid open file.
+
+@itemx EACCES
+Parameter @var{function} is @code{F_TLOCK} or @code{F_TEST} and the
+section is already locked.
+
+@itemx EINVAL
+Parameter @var{function} is not one of the implemented functions.
+@end table
+
+All lock requests in this implementation are coded as exclusive locks
+(i.e., all locks use the @code{fcntl} request @code{F_WRLCK}).
+
+It is therefore wise to code @code{lockf} by using function
+@code{F_TLOCK} with all lock requests, and to test the return value to
+determine if the lock was obtained or not.  Using @code{F_TLOCK} will
+cause the implementation to use @code{F_SETLK} instead of
+@code{F_SETLKW}, which will return an error if the lock cannot be
+obtained.
+
+
+@subheading Return Value
+
+On success, zero is returned.  On error, -1 is returned, and
+@code{errno} is set appropriately, as described above.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+ /* Request a lock on file handle fd from the current position to
+    the end of the file */
+  errno = 0;
+  retval = lockf(fd, F_LOCK, 0);
+
+ /* Request a non-blocking lock on file handle fd */
+  errno = 0;
+  retval = lockf(fd, F_TLOCK, 0);
+
+ /* Test a lock on file handle fd */
+  errno = 0;
+  retval = lockf(fd, F_TEST, 0);
+
+ /* Release a lock on file handle fd */
+  errno = 0;
+  retval = lockf(fd, F_ULOCK, 0);
+@end example
diff -ruN djgpp-cvs/src/libc/compat/unistd/makefile djgpp/src/libc/compat/unistd/makefile
--- djgpp-cvs/src/libc/compat/unistd/makefile	Fri Aug 25 07:35:36 2000
+++ djgpp/src/libc/compat/unistd/makefile	Mon Dec 11 21:56:58 2000
@@ -13,6 +13,8 @@
 SRC += getwd.c
 SRC += lchown.c
 SRC += llseek.c
+SRC += lockf.c
+SRC += llockf.c
 SRC += nice.c
 SRC += readlink.c
 SRC += sdirlink.c
diff -ruN djgpp-cvs/src/libc/posix/sys/file/flock.c djgpp/src/libc/posix/sys/file/flock.c
--- djgpp-cvs/src/libc/posix/sys/file/flock.c	Thu Jan  1 00:00:00 1970
+++ djgpp/src/libc/posix/sys/file/flock.c	Mon Dec 11 21:56:58 2000
@@ -0,0 +1,38 @@
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+
+/* This file implements the `flock' function in terms of the POSIX.1 `fcntl'
+   locking mechanism.  */
+
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/file.h>
+
+/* Apply or remove an advisory lock, according to OPERATION,
+   on the file FD refers to.  */
+int
+flock (int _fildes, int _op)
+{
+  struct flock lock_req;
+
+  switch (_op & ~LOCK_NB)
+    {
+    case LOCK_SH:
+      lock_req.l_type = F_RDLCK;
+      break;
+    case LOCK_EX:
+      lock_req.l_type = F_WRLCK;
+      break;
+    case LOCK_UN:
+      lock_req.l_type = F_UNLCK;
+      break;
+    default:
+      errno = EINVAL;
+      return -1;
+    }
+
+  lock_req.l_whence = SEEK_SET;
+  lock_req.l_start = lock_req.l_len = 0L; /* Lock the whole file.  */
+
+  return fcntl (_fildes, (_op & LOCK_NB) ? F_SETLK : F_SETLKW, &lock_req);
+}
diff -ruN djgpp-cvs/src/libc/posix/sys/file/flock.txh djgpp/src/libc/posix/sys/file/flock.txh
--- djgpp-cvs/src/libc/posix/sys/file/flock.txh	Thu Jan  1 00:00:00 1970
+++ djgpp/src/libc/posix/sys/file/flock.txh	Mon Dec 11 21:56:58 2000
@@ -0,0 +1,89 @@
+@node flock, sys
+@subheading Syntax
+
+@example
+#include <sys/file.h>
+
+int flock (int _fildes, int _op);
+@end example
+
+@subheading Description
+
+Apply or remove an advisory lock on an open file. The file is specified
+by file handle @var{_fildes}. Valid operations are given below:
+
+@table @code
+@item LOCK_SH
+Shared lock.  More than one process may hold a shared lock for a given
+file at a given time.
+
+However, all locks on DOS/Win9x are exclusive locks, so @code{LOCK_SH}
+requests are treated as if they were @code{LOCK_EX} requests.
+
+@item LOCK_EX
+Exclusive lock.  Only one process may hold an exclusive lock for a given
+file at a given time.
+
+@item LOCK_UN
+Unlock the file.
+
+@item LOCK_NB
+Don't block when locking. May be specified (by or'ing) along with one of
+the other operations.
+@end table
+
+On other systems, a single file may not simultaneously have both shared
+and exclusive locks.  However, on DOS/Win9x, all locks are exclusive
+locks, so this rule is not true for DOS/Win9x.
+
+A file is locked, not the file descriptor.  So, dup (2) does not create
+multiple instances of a lock.
+
+Dos/Win9x does not support shared locks, but the underlying
+implementation (which uses the @code{F_SETLK} (non-blocking) or
+@code{F_SETLKW} (blocking) commands to @code{fcntl}, see @ref{fcntl})
+translates all shared lock request into exclusive lock requests.  Thus,
+requests for shared locks will be treated as if exclusive locks were
+requested, and only one lock will ever be permitted at any one time on
+any specified region of the file.
+
+It is therefore wise to code @code{flock} by or'ing @code{LOCK_NB} with
+all lock requests, whether shared or exclusive, and to test the return
+value to determine if the lock was obtained or not.  Using
+@code{LOCK_NB} will cause the implementation to use @code{F_SETLK}
+instead of @code{F_SETLKW}, which will return an error if the lock
+cannot be obtained.
+
+@subheading Return Value
+
+On success, zero is returned.  On error, -1 is returned, and
+@code{errno} is set appropriately.
+
+@subheading Portability
+
+@port-note posix 4.4BSD (the flock (2) call first appeared in 4.2BSD).
+@portability !ansi, posix
+
+@subheading Example
+
+@example
+ /* Request a shared lock on file handle fd */
+  errno = 0;
+  retval = flock(fd, LOCK_SH);
+
+ /* Request a non-blocking shared lock on file handle fd */
+  errno = 0;
+  retval = flock(fd, LOCK_SH | LOCK_NB);
+
+ /* Request an exclusive lock on file handle fd */
+  errno = 0;
+  retval = flock(fd, LOCK_EX);
+
+ /* Request a non-blocking exclusive lock on file handle fd */
+  errno = 0;
+  retval = flock(fd, LOCK_EX | LOCK_NB);
+
+ /* Release a lock on file handle fd */
+  errno = 0;
+  retval = flock(fd, LOCK_UN);
+@end example
diff -ruN djgpp-cvs/src/libc/posix/sys/file/makefile djgpp/src/libc/posix/sys/file/makefile
--- djgpp-cvs/src/libc/posix/sys/file/makefile	Thu Jan  1 00:00:00 1970
+++ djgpp/src/libc/posix/sys/file/makefile	Mon Dec 11 21:56:58 2000
@@ -0,0 +1,6 @@
+# Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details
+TOP=../../..
+
+SRC += flock.c
+
+include $(TOP)/../makefile.inc

--=====================_11067657==_
Content-Type: text/plain; charset="us-ascii"; format=flowed

---------------------------------------------------------
Peter J. Farley III (pjfarley AT dorsai DOT org OR
                      pjfarley AT banet DOT net)
--=====================_11067657==_--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019