fileiosym.cc #1

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

# define NEED_FILE
# define NEED_STAT

# include <stdhdrs.h>

# ifdef HAVE_SYMLINKS

# include <error.h>
# include <strbuf.h>
# include <debug.h>
# include <tunable.h>
# include <i18napi.h>
# include <charcvt.h>

# include "filesys.h"
# include "pathsys.h"
# include "fileio.h"

# ifdef OS_NT
extern int nt_readlink( StrPtr *name, StrBuf &buf, int dounicode, int lfn );
# define readlink(name,buf,dounicode,lfn) nt_readlink(name,buf,dounicode,lfn)

extern int nt_makelink( StrBuf &target, StrPtr *name, int dounicode, int lfn );
# define symlink(target,name,dounicode,lfn) nt_makelink(target,name,dounicode,lfn)
# endif

FileIOSymlink::~FileIOSymlink()
{
	Cleanup();
}

void
FileIOSymlink::Open( FileOpenMode mode, Error *e )
{
	offset = 0;
	value.Clear();
	this->mode = mode;

	// If reading, soak up the symlink now, to be passed back by Read().
	// Writing is done at close.

	if( mode == FOM_READ )
	{
# ifdef OS_NT
	    // The StrBuf allocation is done in nt_readlink().
	    int l = readlink( Path(), value, DOUNICODE, LFN );
# else
	    int size = p4tunable.Get( P4TUNE_FILESYS_MAXSYMLINK );

	    int l = readlink( Name(), value.Alloc( size ), size );
# endif

	    if( l < 0 )
	    {
		e->Sys( "readlink", Name() );
		return;
	    }

	    value.SetLength( l );

	    // Append newline for prettiness and terminate string.

	    value.Append( "\n" );
	}
}

void
FileIOSymlink::Write( const char *buf, int len, Error *e )
{
	// Just append to internal buffer.

	value.Append( buf, len );
}

int
FileIOSymlink::Read( char *buf, int len, Error *e )
{
	// Just read from internal buffer.
	// Offset tracks how much we have.
	
	int l = value.Length() - offset;

	if( len < l )
	    l = len;

	memcpy( buf, value.Text() + offset, l );

	offset += l;

	return l;
}

void
FileIOSymlink::Close( Error *e )
{
	if( mode == FOM_WRITE && value.Length() )
	{
	    // Strip newline added by Open().

	    char *p;

	    if( p = strchr( value.Text(), '\n' ) )
	    {
		value.SetEnd( p );
		value.Terminate();
	    }

# ifdef OS_NT
	    if( symlink( value, Path(), DOUNICODE, LFN ) < 0 )
# else
	    if( symlink( value.Text(), Name() ) < 0 )
# endif
		e->Sys( "symlink", Name() );
	}

	// Prevent duplicate closes

	value.Clear();
}

void
FileIOSymlink::Truncate( offL_t offset, Error *e )
{
}

void
FileIOSymlink::Truncate( Error *e )
{
}

int
FileIOSymlink::StatModTime()
{
# ifdef OS_NT
	int t = FileIO::StatModTime();
	return t >= 0 ? t : 0;
# else
	struct stat sb;

	if( lstat( Name(), &sb ) < 0 )
	    return 0;

	return (int)sb.st_mtime;
# endif
}

void
FileIOSymlink::Chmod( FilePerm perms, Error *e )
{
}

void
FileIOSymlink::ChmodTime( int modTime, Error *e )
{
}

# endif
# Change User Description Committed
#1 15903 Matt Attaway Everything should be happy now between the Workshop and the depot paths
//guest/perforce_software/p4/2014_2/sys/fileiosym.cc
#1 15901 Matt Attaway Clean up code to fit modern Workshop naming standards
//guest/perforce_software/p4/2014.2/sys/fileiosym.cc
#1 12189 Matt Attaway Initial (and much belated) drop of 2014.2 p4 source code