3d6c8b3e2d
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
553 lines
13 KiB
C
Executable File
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 ;
|
|
}
|