diff options
author | larryh%netscape.com <devnull@localhost> | 1999-11-01 22:59:27 +0000 |
---|---|---|
committer | larryh%netscape.com <devnull@localhost> | 1999-11-01 22:59:27 +0000 |
commit | 346f4fd22dd44c24002184fc41cb9c1b9b59b9d4 (patch) | |
tree | 8a20273e4bbca7150522e9771552cafcc3cba2d2 | |
parent | 66e6b2177e13d1c4c4f60396990f5fb0be50fb38 (diff) | |
download | nspr-hg-346f4fd22dd44c24002184fc41cb9c1b9b59b9d4.tar.gz |
BugZilla 17558. Add PR_Open() PR_EXCL flag
-rw-r--r-- | pr/include/prio.h | 4 | ||||
-rw-r--r-- | pr/src/md/unix/unix.c | 2 | ||||
-rw-r--r-- | pr/src/md/windows/ntio.c | 10 | ||||
-rw-r--r-- | pr/src/md/windows/w95io.c | 5 | ||||
-rw-r--r-- | pr/tests/Makefile | 1 | ||||
-rw-r--r-- | pr/tests/ntioto.c | 11 | ||||
-rw-r--r-- | pr/tests/op_excl.c | 137 | ||||
-rwxr-xr-x | pr/tests/runtests.ksh | 2 |
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 |