filetmp.cc #1

  • //
  • guest/
  • perforce_software/
  • p4/
  • 2016-1/
  • sys/
  • filetmp.cc
  • View
  • Commits
  • Open Download .zip Download (4 KB)
/*
 * Copyright 1995, 1996 Perforce Software.  All rights reserved.
 *
 * This file is part of Perforce - the FAST SCM System.
 */

# define NEED_SLEEP

# include <stdhdrs.h>
# include <pid.h>

# if defined(OS_OS2) || defined(OS_NT)
const char *lclTemp = "t%dt%d.tmp";
const char *gblTemp = ".";
# define HAVE_TEMP
# endif

# ifdef OS_VMS
# ifdef VI_WORKS_WITH_DIR
const char *lclTemp = "t%d%d.tmp";
const char *gblTemp = "sys$scratch:";
# else
const char *lclTemp = "t%d%d.tmp";
const char *gblTemp = "";
# define HAVE_TEMP
# endif
# endif

# ifndef HAVE_TEMP
const char *lclTemp = "tmp.%d.%d";
const char *gblTemp = "/tmp";
# endif

# include <error.h>
# include <strbuf.h>
# include <random.h>
# include <debug.h>
# include <tunable.h>

# include "enviro.h"
# include "pathsys.h"
# include "filesys.h"
# include "datetime.h"
# include "msgsupp.h"

/*
 * FileSys::TempName() - create a temp name in target buffer
 */

void
FileSys::TempName( char *buf )
{
	// Format temp file name

	static int count = 0;

# ifdef OS_OS2
	const int maxTemp = 1000;
# else
	const int maxTemp = p4tunable.Get( P4TUNE_FILESYS_MAXTMP );
# endif

	count = ( count + Random::Integer( 1, 100 ) ) % maxTemp;
	 
	sprintf( buf, lclTemp, Pid().GetID(), count );
}

/*
 * FileSys::MakeLocalTemp() - turn file path into a temp file in same dir
 */

void
FileSys::MakeLocalTemp( char *file )
{
	// Make tempname

	char buf[50];

	PathSys *p = PathSys::Create();
	p->SetCharSet( GetCharSetPriv() );

	int cnt = p4tunable.Get( P4TUNE_FILESYS_MAKETMP );

	do
	{
	    TempName( buf );

	    // Append it to path

	    p->Set( file );
	    p->ToParent();
	    p->SetLocal( *p, StrRef( buf ) );

	    Set( *p );
	} while ( ( Stat() & ( FSF_SYMLINK | FSF_EXISTS ) ) && --cnt > 0 );

	delete p;
}

/*
 * FileSys::MakeGlobalTemp() - create a temp file path in temp dir
 */

void
FileSys::MakeGlobalTemp()
{
	const char *tdir;

	// Use $TEMP or $TMP if given.

	Enviro enviro;
	enviro.SetCharSet( GetCharSetPriv() );

	if( 
# ifdef OS_INTERIX
	    !( tdir = enviro.Get( "TMPDIR" ) ) &&
# endif
	    !( tdir = enviro.Get( "TEMP" ) ) && 
	    !( tdir = enviro.Get( "TMP" ) ) )
		tdir = gblTemp;

	// Make tempname
	char buf[50];

	PathSys *p = PathSys::Create();
	p->SetCharSet( GetCharSetPriv() );

	int cnt = 10;

	do
	{
	    TempName( buf );

	    // Append to global temp dir

	    p->Set( tdir );
	    p->SetLocal( *p, StrRef( buf ) );

	    Set( *p );
	} while ( ( Stat() & ( FSF_SYMLINK | FSF_EXISTS ) ) && --cnt > 0 );

	delete p;
}

// This creates a lock file ment to be very temporary
FileSys *
FileSys::CreateLock( FileSys *f, Error *e )
{
	int t;
	StrBuf nameit;
	DateTime nowtime, locktime;

	FileSys *lockFile = Create( (FileSysType)( FST_BINARY|FST_M_EXCL ) );

	lockFile->SetDeleteOnClose();

	nameit.Set( f->Path() );
	nameit.UAppend( ".lck" );

	lockFile->Set( nameit );

	int lcnt = p4tunable.Get( P4TUNE_FILESYS_LOCKTRY );

	while( --lcnt > 0 )
	{
	    if( ( t = lockFile->StatModTime() ) > 0 )
	    {
		// file exists
		locktime.Set( t );
		nowtime.SetNow();
		if( nowtime.Compare( locktime ) > p4tunable.Get( P4TUNE_FILESYS_LOCKDELAY ) )
		{
		    // lock file old
		    lockFile->Unlink( e );
		    if( e->Test() )
		    {
			lockFile->ClearDeleteOnClose();
			delete lockFile;
			return NULL;
		    }
		}
		else
		{
		    // lock file exists, reasonably new, we should wait
		    sleep( 1 );
		}
	    }
	    else
	    {
		// file does not seem to exist, try create
		lockFile->Open( FOM_WRITE, e );

		if( !e->Test() )
		    return lockFile;

		// if open failed, we try agin
		e->Clear();
	    }
	}

	// too many retries, error
	// set error
	e->Set( MsgSupp::TooManyLockTrys ) << nameit;
	lockFile->ClearDeleteOnClose();
	delete lockFile;
	return NULL;
}
# Change User Description Committed
#1 19472 Liz Lam Initial add of the 2016.1 p4/p4api source code.