campo-sirio/cb/source/f4create.c
alex 3d6c8b3e2d Patch level : 2.0 464
Files correlati     : cb6.dll
Ricompilazione Demo : [ ]
Commento            :
Modifiche per la compilazione Linux


git-svn-id: svn://10.65.10.50/trunk@11080 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-05-01 15:14:58 +00:00

553 lines
13 KiB
C
Executable File

/* f4create.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
#include "d4all.h"
#ifdef __TURBOC__
#pragma hdrstop
#endif
#ifdef S4TEMP
#include "t4test.h"
#endif
#ifdef S4TRACK_FILES
extern unsigned int numFiles ;
extern int f4print ;
#endif
#ifdef S4WINTEL
#ifndef S4IBMOS2
#ifndef __TURBOC__
#include <sys\locking.h>
#define S4LOCKING
#endif
#ifdef __ZTC__
#ifndef S4WINDOWS
extern int errno ;
#endif
#endif
#ifdef _MSC_VER
#include <sys\types.h>
#include <sys\locking.h>
#endif
#endif
#include <sys\stat.h>
#include <share.h>
#endif
/* */
/* */
/* */
#include <fcntl.h>
#ifndef S4WINDOWS
#include <errno.h>
#ifdef S4ERRNO
extern int errno ;
#endif
#endif
/*
** file4createLow() generic outline:
**
** - clear any postive error values
** - set read/write access flag (for create it is always both read and write)
** - set the shared flag based on CODE4::accessMode
** 3 possible settings: OPEN4DENY_NONE, OPEN4DENY_WRITE, OPEN4DENY_RW.
** return failure if no the setting is invalid.
** - set the safety (open existing) flag based on CODE4::safety
** - determine if file exists
** if it does exist, ensure that nobody else has it open (exclusive access)
** many operating systems allow creates on open files, which result in
** failures for the other applications. Avoid this for safety reasons.
** - physically attempt to create the file
** - return the result
**
** Returns: 0 = success, r4noCreate = failure
**
** Notes:
** This routine shouldn't generate a CodeBase error
*/
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
#ifdef S4UNIX
static int file4createLow( FILE4 *file, CODE4 *c4, const char *name )
{
int oflag, pmode ;
int rc = 0 ;
#ifdef S4NO_FLOCK
struct flock lck;
lck.l_whence = SEEK_SET ;
lck.l_start = 0 ;
lck.l_len = 1000000000 ;
#endif
error4set( c4, 0 ) ; /* clear positive error values */
/*set to invalid by default, since not created yet.*/
file->hand = -1;
/* first determine the basic access values */
oflag = (int)(O_CREAT | O_RDWR| O_EXCL) ;
switch ( c4->accessMode )
{
case OPEN4DENY_NONE:
pmode = 0666 ; /* Allow full read/write permission */
break;
case OPEN4DENY_WRITE:
pmode = 0644 ; /*Allow full read permission */
break;
case OPEN4DENY_RW:
pmode = 0600 ; /* Allow exclusive read/write permission */
break;
default:
return r4noCreate;
}
/*Check for files existence*/
file->hand = open(name, oflag, pmode) ;
if (file->hand<0)
{ /*problem creating the file*/
if ( errno == EACCES ) /*If this is the error, we would have lost it on the next open*/
{
file->hand = -1 ;
return r4noCreate ;
}
file->hand = open(name, O_RDWR) ;
if (file->hand < 0) /*Does the file not exist*/
{
file->hand = -1;
return r4noCreate;
}
else /*file does exist*/
if ( !c4->safety )
{ /*overwrite file if no one else is using it*/
#ifndef S4NO_FLOCK
rc = flock (file->hand, LOCK_EX|LOCK_NB) ;
#else
lck.l_type = F_WRLCK ;
rc = fcntl(file->hand, F_GETLK, &lck ) ;
#endif
if (rc<0)
{ /*someone else is using it*/
close(file->hand);
file->hand = -1;
return r4noCreate;
}
else /*no one is using it so kill it*/
{
#ifdef S4NO_CHSIZE
ftruncate(file->hand, 0) ;
#else
chsize(file->hand, 0) ;
#endif
#ifndef S4NO_FLOCK
flock(file->hand,LOCK_UN);
#endif
}
}
else
{ /*SInce the file exists, and we have safeties, we can't create*/
close(file->hand);
file->hand = -1;
return r4noCreate;
}
}
/* if ( file->hand < 0 )
{
file->hand = -1 ;
return r4noCreate ;
}*/
switch ( c4->accessMode )
{
case OPEN4DENY_NONE:
case OPEN4DENY_WRITE:
#ifndef S4NO_FLOCK
rc = flock (file->hand, LOCK_SH|LOCK_NB) ;
#else
lck.l_type = F_RDLCK ;
rc = fcntl (file->hand, F_SETLK, &lck ) ;
#endif
break;
case OPEN4DENY_RW:
#ifndef S4NO_FLOCK
rc = flock (file->hand, LOCK_EX|LOCK_NB) ;
#else
lck.l_type = F_WRLCK ;
rc = fcntl (file->hand, F_SETLK, &lck ) ;
#endif
break;
default:
close(file->hand);
file->hand = -1;
return r4noCreate;
}
if (rc!=0)
return r4noCreate ;
return 0 ;
}
#endif /* S4UNIX */
#ifdef S4WIN32
static int file4createLow( FILE4 *file, CODE4 *c4, const char *name )
{
int existHandle ;
DWORD fdwAccess, fdwShareMode, fdwCreate ;
error4set( c4, 0 ) ; /* clear positive error values */
/* set to invalid by default, since not created yet */
file->hand = (int)INVALID_HANDLE_VALUE ;
/* first determine the basic access values */
fdwAccess = GENERIC_WRITE | GENERIC_READ ;
#ifdef S4OFF_MULTI
#ifdef E4DEBUG
/* open in shared mode for debugging to allow other programs to examine */
fdwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ ;
#else
/* otherwise, if single-user, file should be opened exclusively */
fdwShareMode = 0 ;
#endif
#else
switch( c4->accessMode )
{
case OPEN4DENY_NONE:
fdwShareMode = FILE_SHARE_WRITE | FILE_SHARE_READ ;
break ;
case OPEN4DENY_WRITE:
fdwShareMode = FILE_SHARE_READ ;
break ;
case OPEN4DENY_RW:
fdwShareMode = 0 ;
break ;
default:
return r4noCreate ;
}
#endif /* S4OFF_MULTI */
if ( c4->safety )
fdwCreate = CREATE_NEW ;
else
fdwCreate = CREATE_ALWAYS ;
/* existHandle will be >= 0 if the file exists and is allowed access */
existHandle = access( name, 0 ) ;
if ( existHandle >= 0 ) /* file exists and is available */
{
/* if safety is != 0, function will fall through since file
already exists */
if ( c4->safety == 0 ) /* ensure exclusive access, otherwise problems ensue */
{
file->hand = (int)CreateFile( name, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ) ;
if ( file->hand == (int)INVALID_HANDLE_VALUE )
{
file->hand = -1 ;
return r4noCreate ;
}
CloseHandle( (HANDLE)file->hand ) ;
existHandle = -1 ;
}
}
if ( existHandle < 0 ) /* file doesn't exist, or exclusive access is available, so attempt create */
file->hand = (int)CreateFile( name, fdwAccess, fdwShareMode, 0, fdwCreate, FILE_ATTRIBUTE_NORMAL, 0 ) ;
if ( file->hand == (int)INVALID_HANDLE_VALUE )
{
file->hand = -1 ;
return r4noCreate ;
}
#ifdef S4MULTI_THREAD
InitializeCriticalSection( &file->critical4file ) ;
#endif
return 0 ;
}
#endif /* S4WIN32 */
#ifdef S4WIN16
static int file4createLow( FILE4 *file, CODE4 *c4, const char *name )
{
int existHandle, shmode, omode ;
error4set( c4, 0 ) ; /* clear positive error values */
existHandle = access( name, 0 ) ; /* if file doesn't exist, create */
if ( existHandle != -1 ) /* file exists, see if open if not safety... */
{
if ( c4->safety == 0 )
{
file->hand = _lopen( name, OF_READWRITE | OF_SHARE_EXCLUSIVE ) ;
if ( file->hand < 0 )
return r4noCreate ;
_lclose( file->hand ) ;
existHandle = -1 ;
}
}
if ( existHandle < 0 ) /* if file doesn't exist, create */
{
/* do initial creation in exclusive mode */
file->hand = _lcreat( name, 0 ) ; /* attr == 0 : read/write permission */
if ( file->hand >= 0 ) /* now that file is created, move to regular r/w mode */
{
_lclose( file->hand ) ;
omode = OF_READWRITE ;
switch( c4->accessMode )
{
case OPEN4DENY_RW:
shmode = OF_SHARE_EXCLUSIVE ;
break ;
case OPEN4DENY_WRITE:
shmode = OF_SHARE_DENY_WRITE ;
break ;
case OPEN4DENY_NONE:
shmode = OF_SHARE_DENY_NONE ;
break ;
default:
file->hand = -1 ;
return r4noCreate ;
}
file->hand = _lopen( name, omode | shmode ) ;
}
}
if ( file->hand < 0 )
return r4noCreate ;
return 0 ;
}
#endif /* S4WIN16 */
/* now for all other instances */
#ifdef S4WINTEL
#ifndef S4WIN32
#ifndef S4WIN16
static int file4createLow( FILE4 *file, CODE4 *c4, const char *name )
{
int extraFlag, oflag, pmode, shmode ;
error4set( c4, 0 ) ; /* clear positive error values */
oflag = (int)( O_CREAT | O_TRUNC | O_BINARY | O_RDWR ) ;
pmode = (int)( S_IREAD | S_IWRITE ) ;
if ( c4->safety )
extraFlag = O_EXCL ;
else
extraFlag = 0 ;
/* ensure first that nobody else has access to the file */
file->hand = sopen( name, O_RDWR, SH_DENYRW, pmode ) ;
if ( file->hand < 0 )
switch ( errno )
{
case ENOENT: /* file not found, so can create */
break ;
default: /* access or misc. error, return failure */
return r4noCreate ;
}
close( file->hand ) ;
#ifdef S4OFF_MULTI
shmode = SH_DENYRW ;
#else
switch( c4->accessMode )
{
case OPEN4DENY_RW:
shmode = SH_DENYRW ;
break ;
case OPEN4DENY_WRITE:
shmode = SH_DENYWR ;
break ;
case OPEN4DENY_NONE:
shmode = SH_DENYNO ;
break ;
default:
file->hand = -1 ;
return r4noCreate ;
}
#endif
file->hand = sopen( name, extraFlag | oflag, shmode, pmode ) ;
if ( file->hand < 0 )
return r4noCreate ;
return 0 ;
}
#endif /* S4WINTEL */
#endif /* S4WIN32 */
#endif /* S4WIN16 */
int S4FUNCTION file4create( FILE4 *file, CODE4 *c4, S4CONST char *name, const int doAlloc )
{
int rc, len ;
#ifdef E4PARM_HIGH
if ( file == 0 || c4 == 0 )
return error4( c4, e4parm_null, E90602 ) ;
#endif
#ifndef S4OPTIMIZE_OFF
code4memStartMaxSet( c4, c4->memMaxPercent ) ; /* start optimization if not enabled and not suspended */
#endif
memset( (void *)file, 0, sizeof( FILE4 ) ) ;
file->codeBase = c4 ;
file->hand = -1 ;
if ( error4code( c4 ) < 0 )
return e4codeBase ;
if ( name == 0 )
{
rc = file4tempLow( file, c4, c4->createTemp ) ;
if ( rc == 0 )
return 0 ;
}
else
rc = file4createLow( file, c4, name ) ;
#ifdef S4SERVER
if ( rc == r4noCreate ) /* free up any open unused file handles */
{
error4set( c4, 0 ) ;
rc = code4dataFileCloseAll( c4 ) ;
if ( rc < 0 )
return rc ;
if ( name == 0 )
return file4tempLow( file, c4, c4->createTemp ) ;
else
rc = file4createLow( file, c4, name ) ;
}
#endif
if ( rc < 0 )
return rc ;
if ( rc == r4noCreate )
{
if ( c4->errCreate )
return error4describe( c4, e4create, E90602, name, (char *) 0, (char *) 0 ) ;
error4set( c4, r4noCreate ) ;
return r4noCreate ;
}
if ( doAlloc )
{
len = strlen(name) + 1 ;
file->nameBuf = (char *)u4allocEr( c4, (long)len ) ;
if ( file->nameBuf == 0 )
{
file4close( file ) ;
return e4memory ;
}
u4ncpy( file->nameBuf, name, (unsigned int)len ) ;
file->name = file->nameBuf ;
file->doAllocFree = 1 ;
}
else
file->name = name ;
#ifndef S4OFF_MULTI
file->lowAccessMode = c4->accessMode ;
#endif
#ifndef S4OFF_OPTIMIZE
file->fileCreated = 1 ;
#endif
if ( c4->createTemp == 1 )
file->isTemp = 1 ;
#ifdef S4TRACK_FILES
if ( f4print != -1 )
{
#ifdef S4WINDOWS
#ifdef S4TESTING
if ( mem4displayPtr == 0 )
error4( 0, e4info, E50101 ) ;
d4display_str( mem4displayPtr, "\r\nfile created: ", 1 ) ;
d4display_str( mem4displayPtr, f4print, file->name ) ;
#else
u4writeErr( "file created: ", 1 ) ;
u4writeErr( file->name, 0 ) ;
#endif
#else
if ( f4print )
fprintf( stdprn, "\r\nfile created: %s", file->name ) ;
else
printf( "\r\nfile created: %s", file->name ) ;
#endif
}
numFiles++ ;
#endif
return 0 ;
}