summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlarryh%netscape.com <devnull@localhost>1999-11-01 22:59:27 +0000
committerlarryh%netscape.com <devnull@localhost>1999-11-01 22:59:27 +0000
commit346f4fd22dd44c24002184fc41cb9c1b9b59b9d4 (patch)
tree8a20273e4bbca7150522e9771552cafcc3cba2d2
parent66e6b2177e13d1c4c4f60396990f5fb0be50fb38 (diff)
downloadnspr-hg-346f4fd22dd44c24002184fc41cb9c1b9b59b9d4.tar.gz
BugZilla 17558. Add PR_Open() PR_EXCL flag
-rw-r--r--pr/include/prio.h4
-rw-r--r--pr/src/md/unix/unix.c2
-rw-r--r--pr/src/md/windows/ntio.c10
-rw-r--r--pr/src/md/windows/w95io.c5
-rw-r--r--pr/tests/Makefile1
-rw-r--r--pr/tests/ntioto.c11
-rw-r--r--pr/tests/op_excl.c137
-rwxr-xr-xpr/tests/runtests.ksh2
8 files changed, 168 insertions, 4 deletions
diff --git a/pr/include/prio.h b/pr/include/prio.h
index 5df417eb..2000b884 100644
--- a/pr/include/prio.h
+++ b/pr/include/prio.h
@@ -551,6 +551,9 @@ PR_EXTERN(PRFileDesc*) PR_PopIOLayer(PRFileDesc *fd_stack, PRDescIdentity id);
* PR_APPEND The file pointer is set to the end of
* the file prior to each write.
* PR_TRUNCATE If the file exists, its length is truncated to 0.
+ * PR_EXCL With PR_CREATE_FILE, if the file does not exist,
+ * the file is created. If the file already
+ * exists, no action and NULL is returned
*
* PRIntn mode
* The access permission bits of the file mode, if the file is
@@ -580,6 +583,7 @@ PR_EXTERN(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
#define PR_APPEND 0x10
#define PR_TRUNCATE 0x20
#define PR_SYNC 0x40
+#define PR_EXCL 0x80
/*
** File modes ....
diff --git a/pr/src/md/unix/unix.c b/pr/src/md/unix/unix.c
index ffda1d9a..c736db9c 100644
--- a/pr/src/md/unix/unix.c
+++ b/pr/src/md/unix/unix.c
@@ -2195,6 +2195,8 @@ PRInt32 _MD_open(const char *name, PRIntn flags, PRIntn mode)
osflags = O_RDONLY;
}
+ if (flags & PR_EXCL)
+ osflags |= O_EXCL;
if (flags & PR_APPEND)
osflags |= O_APPEND;
if (flags & PR_TRUNCATE)
diff --git a/pr/src/md/windows/ntio.c b/pr/src/md/windows/ntio.c
index 8225da9b..35bd82fb 100644
--- a/pr/src/md/windows/ntio.c
+++ b/pr/src/md/windows/ntio.c
@@ -2111,10 +2111,13 @@ _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode)
if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
- if (osflags & PR_CREATE_FILE)
+ if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+ flags = CREATE_NEW;
+ else if (osflags & PR_CREATE_FILE)
flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
else flags = OPEN_EXISTING;
+
flag6 |= FILE_FLAG_OVERLAPPED;
@@ -2147,7 +2150,10 @@ _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode)
access |= GENERIC_READ;
if (osflags & PR_WRONLY || osflags & PR_RDWR)
access |= GENERIC_WRITE;
- if (osflags & PR_CREATE_FILE) {
+
+ if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+ flags = CREATE_NEW;
+ else if (osflags & PR_CREATE_FILE) {
if (osflags & PR_TRUNCATE)
flags = CREATE_ALWAYS;
else
diff --git a/pr/src/md/windows/w95io.c b/pr/src/md/windows/w95io.c
index 2b21efb9..928332f2 100644
--- a/pr/src/md/windows/w95io.c
+++ b/pr/src/md/windows/w95io.c
@@ -149,7 +149,10 @@ _PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
access |= GENERIC_READ;
if (osflags & PR_WRONLY || osflags & PR_RDWR)
access |= GENERIC_WRITE;
- if (osflags & PR_CREATE_FILE) {
+
+ if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+ flags = CREATE_NEW;
+ else if (osflags & PR_CREATE_FILE) {
if (osflags & PR_TRUNCATE)
flags = CREATE_ALWAYS;
else
diff --git a/pr/tests/Makefile b/pr/tests/Makefile
index bfa9c112..7bc2d367 100644
--- a/pr/tests/Makefile
+++ b/pr/tests/Makefile
@@ -92,6 +92,7 @@ CSRCS = \
nonblock.c \
ntioto.c \
op_2long.c \
+ op_excl.c \
op_filnf.c \
op_filok.c \
op_noacc.c \
diff --git a/pr/tests/ntioto.c b/pr/tests/ntioto.c
index a84b5f38..e5c9ecea 100644
--- a/pr/tests/ntioto.c
+++ b/pr/tests/ntioto.c
@@ -84,6 +84,7 @@ volatile enum {
PRFileDesc *file1;
PRIntn iCounter = 0;
PRIntn jitter = JITTER_DEFAULT;
+PRBool resume = PR_FALSE;
/*
** Emit help text for this test
@@ -155,6 +156,11 @@ static void ConnectThread( void *arg )
PR_ASSERT(clientSock);
+ if ( resume ) {
+ if ( debug ) printf("pausing 3 seconds before connect\n");
+ PR_Sleep( PR_SecondsToInterval(3));
+ }
+
memset(&serverAddress, 0, sizeof(serverAddress));
rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddress);
PR_ASSERT( PR_SUCCESS == rv );
@@ -187,7 +193,7 @@ PRIntn main(PRIntn argc, char *argv[])
** Get command line options
*/
PLOptStatus os;
- PLOptState *opt = PL_CreateOptState(argc, argv, "hdvj:");
+ PLOptState *opt = PL_CreateOptState(argc, argv, "hdrvj:");
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
{
@@ -207,6 +213,9 @@ PRIntn main(PRIntn argc, char *argv[])
if ( jitter == 0)
jitter = JITTER_DEFAULT;
break;
+ case 'r':
+ resume = PR_TRUE;
+ break;
case 'h': /* help message */
Help();
break;
diff --git a/pr/tests/op_excl.c b/pr/tests/op_excl.c
new file mode 100644
index 00000000..bfbd33d3
--- /dev/null
+++ b/pr/tests/op_excl.c
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+/***********************************************************************
+**
+** Name: op_excl.c
+**
+** Description: Test Program to verify function of PR_EXCL open flag
+**
+** Modification History:
+** 27-Oct-1999 lth. Initial version
+***********************************************************************/
+
+#include <plgetopt.h>
+#include <nspr.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRIntn debug = 0;
+PRUint32 failed_already = 0;
+/* end Test harness infrastructure */
+/*
+** Emit help text for this test
+*/
+static void Help( void )
+{
+ printf("op_excl: Help");
+ printf("op_excl [-d]");
+ printf("-d enables debug messages");
+ exit(1);
+} /* end Help() */
+
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+ PRFileDesc *fd;
+ PRStatus rv;
+ PRInt32 written;
+ char outBuf[] = "op_excl.c test file";
+#define OUT_SIZE sizeof(outBuf)
+#define NEW_FILENAME "xxxExclNewFile"
+
+ {
+ /*
+ ** Get command line options
+ */
+ PLOptStatus os;
+ PLOptState *opt = PL_CreateOptState(argc, argv, "hd");
+
+ while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+ {
+ if (PL_OPT_BAD == os) continue;
+ switch (opt->option)
+ {
+ case 'd': /* debug */
+ debug = 1;
+ msgLevel = PR_LOG_ERROR;
+ break;
+ case 'h': /* help message */
+ Help();
+ break;
+ default:
+ break;
+ }
+ }
+ PL_DestroyOptState(opt);
+ }
+
+ lm = PR_NewLogModule("Test"); /* Initialize logging */
+
+ /*
+ ** First, open a file, PR_EXCL, we believe not to exist
+ */
+ fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 );
+ if ( NULL == fd ) {
+ if (debug) fprintf( stderr, "Open exclusive. Expected success, got failure\n");
+ failed_already = 1;
+ goto Finished;
+ }
+
+ written = PR_Write( fd, outBuf, OUT_SIZE );
+ if ( OUT_SIZE != written ) {
+ if (debug) fprintf( stderr, "Write after open exclusive failed\n");
+ failed_already = 1;
+ goto Finished;
+ }
+
+ rv = PR_Close(fd);
+ if ( PR_FAILURE == rv ) {
+ if (debug) fprintf( stderr, "Close after open exclusive failed\n");
+ failed_already = 1;
+ goto Finished;
+ }
+
+ /*
+ ** Second, open the same file, PR_EXCL, expect it to fail
+ */
+ fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 );
+ if ( NULL != fd ) {
+ if (debug) fprintf( stderr, "Open exclusive. Expected failure, got success");
+ failed_already = 1;
+ PR_Close(fd);
+ }
+
+ rv = PR_Delete( NEW_FILENAME );
+ if ( PR_FAILURE == rv ) {
+ if (debug) fprintf( stderr, "PR_Delete() failed\n");
+ failed_already = 1;
+ }
+
+Finished:
+ if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
+ return( (failed_already == PR_TRUE )? 1 : 0 );
+} /* main() */
+/* end op_excl.c */
+
diff --git a/pr/tests/runtests.ksh b/pr/tests/runtests.ksh
index 6af8698d..28759a12 100755
--- a/pr/tests/runtests.ksh
+++ b/pr/tests/runtests.ksh
@@ -112,7 +112,9 @@ multiwait
nameshm1
nblayer
nonblock
+ntioto
op_2long
+op_excl
op_filnf
op_filok
op_nofil