remfile.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 504 行
C
504 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Remote file access.
*
****************************************************************************/
//#define LOGGING 1
#include <string.h>
#include "dbgdefn.h"
#include "trpcore.h"
#include "trpfile.h"
#include "dbgio.h"
#include <fcntl.h>
#include <unistd.h>
#ifdef LOGGING
#include <stdio.h>
#endif
#ifdef __NT__
#include "windows.h"
extern system_config SysConfig;
#endif
extern trap_shandle GetSuppId( char * );
extern handle LclStringToFullName( char *name, unsigned len, char *full );
extern unsigned MaxPacketLen;
extern unsigned CheckSize;
static trap_shandle SuppFileId;
file_components RemFile;
#ifdef LOGGING
static FILE *logf;
#endif
/* Remote file "cache" - correlates remote and local file handles */
typedef struct _fcache_t {
int locfile;
sys_handle remhandle;
} fcache_t;
#define CACHED_HANDLES 16
static fcache_t fcache[CACHED_HANDLES];
#define SUPP_FILE_SERVICE( in, request ) \
in.supp.core_req = REQ_PERFORM_SUPPLEMENTARY_SERVICE; \
in.supp.id = SuppFileId; \
in.req = request;
/* Return local handle of remote file equivalent */
int GetCachedHandle(sys_handle remote)
{
int i;
for( i = 0; i < CACHED_HANDLES; i++ )
if( fcache[i].remhandle == remote )
return( fcache[i].locfile );
return( -1 );
}
/* Initialize local/remote handle cache */
void InitHandleCache( void )
{
int i;
#ifdef LOGGING
logf = fopen("wdrem.log", "wt");
fprintf(logf, "InitHandleCache called\n");
#endif
for( i = 0; i < CACHED_HANDLES; i++ ) {
fcache[i].remhandle = -1;
fcache[i].locfile = -1;
}
}
/* Add entry for local/remote "cached" file */
int AddCachedHandle( int local, sys_handle remote )
{
int i = 0;
while( i < CACHED_HANDLES ) {
if( fcache[i].locfile == -1 ) {
fcache[i].remhandle = remote;
fcache[i].locfile = local;
return( 0 );
}
i++;
}
return( -1 );
}
/* Remove cached file entry from the list */
int DelCachedHandle( int local )
{
int i = 0;
while( i < CACHED_HANDLES ) {
if( fcache[i].locfile == local ) {
fcache[i].remhandle = -1;
fcache[i].locfile = -1;
return( 0 );
}
i++;
}
return( -1 );
}
bool InitFileSupp( void )
{
file_get_config_req acc;
InitHandleCache();
SuppFileId = GetSuppId( FILE_SUPP_NAME );
if( SuppFileId == 0 ) return( FALSE );
SUPP_FILE_SERVICE( acc, REQ_FILE_GET_CONFIG );
TrapSimpAccess( sizeof( acc ), &acc, sizeof( RemFile ), &RemFile );
return( TRUE );
}
bool HaveRemoteFiles( void )
{
return( SuppFileId != 0 );
}
//NYI: The 'bool executable' should be changed to allow different file types
unsigned RemoteStringToFullName( bool executable, char *name, char *res,
unsigned res_len )
{
mx_entry in[2];
mx_entry out[2];
file_string_to_fullpath_req acc;
file_string_to_fullpath_ret ret;
handle h;
if( SuppFileId == 0 ) {
h = LclStringToFullName( name, strlen( name ), res );
if( h == NIL_HANDLE ) return( 0 );
FileClose( h );
return( strlen( res ) );
}
#ifdef __NT__
// check whether short filename is necessary
switch( SysConfig.os ) {
case OS_AUTOCAD:
case OS_DOS:
case OS_RATIONAL:
case OS_PHARLAP:
case OS_WINDOWS:
// convert long file name to short "DOS" compatible form
{
char short_filename[MAX_PATH + 1] = "";
GetShortPathNameA( name, short_filename, MAX_PATH );
if( strlen( short_filename ) != 0 ) {
strcpy( name, short_filename );
}
}
break;
}
#endif
SUPP_FILE_SERVICE( acc, REQ_FILE_STRING_TO_FULLPATH );
acc.file_type = ( executable ? TF_TYPE_EXE : TF_TYPE_PRS );
in[0].ptr = &acc;
in[0].len = sizeof( acc );
in[1].ptr = name;
in[1].len = strlen( name ) + 1;
out[0].ptr = &ret;
out[0].len = sizeof( ret );
out[1].ptr = res;
out[1].len = res_len;
TrapAccess( 2, &in, 2, &out );
CONV_LE_32( ret.err );
if( ret.err != 0 ) {
*res = NULLCHAR;
return( 0 );
} else {
return( strlen( res ) );
}
}
sys_handle RemoteOpen( char *name, open_access mode )
{
mx_entry in[2];
mx_entry out[1];
file_open_req acc;
file_open_ret ret;
int locfile;
if( SuppFileId == 0 ) return( NIL_SYS_HANDLE );
SUPP_FILE_SERVICE( acc, REQ_FILE_OPEN );
acc.mode = 0;
if( mode & OP_READ )
acc.mode |= TF_READ;
if( mode & OP_WRITE )
acc.mode |= TF_WRITE;
if( mode & OP_CREATE ) {
acc.mode |= TF_CREATE;
if( mode & OP_EXEC )
acc.mode |= TF_EXEC;
}
in[0].ptr = &acc;
in[0].len = sizeof( acc );
in[1].ptr = name;
in[1].len = strlen( name ) + 1;
out[0].ptr = &ret;
out[0].len = sizeof( ret );
TrapAccess( 2, &in, 1, &out );
CONV_LE_32( ret.err );
CONV_LE_32( ret.handle );
if( ret.err != 0 ) {
StashErrCode( ret.err, OP_REMOTE );
return( NIL_SYS_HANDLE );
} else {
/* See if the file is available locally. If so, open it here as
* well as on the remote machine.
*/
// TODO: check if remote file is the same!
#ifdef LOGGING
fprintf( logf, "Trying to open local copy of remote file (remote handle %d)\n", ret.handle );
fprintf( logf, "%s\n", name );
#endif
if( (locfile = open(name, O_RDONLY | O_BINARY, 0 )) != -1 ) {
if(AddCachedHandle( locfile, ret.handle ) != 0 )
close( locfile );
#ifdef LOGGING
fprintf(logf, "Success\n", name);
#endif
}
return( ret.handle );
}
}
static unsigned DoAWrite( unsigned req, sys_handle hdl, void *ptr, unsigned len )
{
mx_entry in[2];
mx_entry out[1];
union {
file_write_req file;
file_write_console_req con;
} acc;
file_write_ret ret;
SUPP_FILE_SERVICE( acc.file, req );
if( req == REQ_FILE_WRITE_CONSOLE ) {
in[0].len = sizeof( acc.con );
} else {
acc.file.handle = hdl;
CONV_LE_32( acc.file.handle );
in[0].len = sizeof( acc.file );
}
in[0].ptr = &acc;
in[1].ptr = ptr;
in[1].len = len;
out[0].ptr = &ret;
out[0].len = sizeof( ret );
TrapAccess( 2, &in, 1, &out );
CONV_LE_32( ret.err );
CONV_LE_16( ret.len );
if( ret.err != 0 ) {
StashErrCode( ret.err, OP_REMOTE );
return( ERR_RETURN );
} else {
return( ret.len );
}
}
unsigned MaxRemoteWriteSize( void )
{
return( MaxPacketLen - sizeof( file_write_req ) );
}
static unsigned DoWrite( unsigned req, sys_handle hdl, void *ptr, unsigned len )
{
unsigned rc;
unsigned total;
unsigned max;
unsigned curr;
max = MaxRemoteWriteSize();
total = 0;
for( ;; ) {
if( len == 0 ) break;
curr = len;
if( curr > max ) curr = max;
rc = DoAWrite( req, hdl, ptr, curr );
if( rc == ERR_RETURN ) return( rc );
total += rc;
if( rc != curr ) break;
ptr = (char *)ptr + curr;
len -= curr;
}
return( total );
}
unsigned RemoteWrite( sys_handle hdl, const void *buff, unsigned len )
{
if( SuppFileId == 0 ) return( 0 );
return( DoWrite( REQ_FILE_WRITE, hdl, (void *)buff, len ) );
}
unsigned RemoteWriteConsole( void *buff, unsigned len )
{
if( SuppFileId == 0 ) return( 0 );
return( DoWrite( REQ_FILE_WRITE_CONSOLE, NIL_SYS_HANDLE, buff, len ) );
}
static unsigned DoRead( sys_handle hdl, void *ptr, unsigned len )
{
mx_entry in[1];
mx_entry out[2];
file_read_req acc;
file_read_ret ret;
unsigned got;
SUPP_FILE_SERVICE( acc, REQ_FILE_READ );
acc.handle = hdl;
acc.len = len;
in[0].ptr = &acc;
in[0].len = sizeof( acc );
out[0].ptr = &ret;
out[0].len = sizeof( ret );
out[1].ptr = ptr;
out[1].len = len;
CONV_LE_32( acc.handle );
CONV_LE_16( acc.len );
got = TrapAccess( 1, &in, 2, &out );
CONV_LE_32( ret.err );
if( ret.err != 0 ) {
StashErrCode( ret.err, OP_REMOTE );
return( ERR_RETURN );
} else {
return( got - sizeof( ret ) );
}
}
unsigned MaxRemoteReadSize( void )
{
return( MaxPacketLen - sizeof( file_read_req ) );
}
unsigned RemoteRead( sys_handle hdl, void *ptr, unsigned len )
{
unsigned total;
unsigned rc;
unsigned max;
unsigned curr;
int locfile;
if( SuppFileId == 0 ) return( 0 );
/* Try reading from local copy first */
locfile = GetCachedHandle( hdl );
if( locfile != -1 )
return( read( locfile, ptr, len ) );
max = MaxRemoteReadSize();
total = 0;
for( ;; ) {
if( len == 0 ) break;
curr = len;
if( curr > max ) curr = max;
rc = DoRead( hdl, ptr, curr );
if( rc == ERR_RETURN ) return( rc );
total += rc;
if( rc != curr ) break;
ptr = (char *)ptr + curr;
len -= curr;
}
return( total );
}
unsigned long RemoteSeek( sys_handle hdl, unsigned long pos, unsigned method )
{
file_seek_req acc;
file_seek_ret ret;
int locfile;
if( SuppFileId == 0 ) return( 0 );
/* Seek on local copy too (if available) */
locfile = GetCachedHandle( hdl );
if( locfile != -1 ) {
lseek( locfile, pos, method );
}
SUPP_FILE_SERVICE( acc, REQ_FILE_SEEK );
acc.handle = hdl;
/* Magic again! The seek mode mapped exactly to our definition! */
acc.mode = method;
acc.pos = pos;
CONV_LE_32( acc.handle );
CONV_LE_32( acc.pos );
TrapSimpAccess( sizeof( acc ), &acc, sizeof( ret ), &ret );
CONV_LE_32( ret.pos );
CONV_LE_32( ret.err );
if( ret.err != 0 ) {
StashErrCode( ret.err, OP_REMOTE );
return( -1UL );
} else {
return( ret.pos );
}
}
unsigned RemoteClose( sys_handle hdl )
{
file_close_req acc;
file_close_ret ret;
int locfile;
if( SuppFileId == 0 ) return( 0 );
locfile = GetCachedHandle( hdl );
if( locfile != -1 ) {
close( locfile );
DelCachedHandle( locfile );
#ifdef LOGGING
fprintf( logf, "Closing remote file handle %d\n", hdl );
#endif
}
SUPP_FILE_SERVICE( acc, REQ_FILE_CLOSE );
acc.handle = hdl;
CONV_LE_32( acc.handle );
TrapSimpAccess( sizeof( acc ), &acc, sizeof( ret ), &ret );
CONV_LE_32( ret.err );
return( StashErrCode( ret.err, OP_REMOTE ) );
}
unsigned RemoteErase( char *name )
{
mx_entry in[2];
mx_entry out[1];
file_erase_req acc;
file_erase_ret ret;
if( SuppFileId == 0 ) return( 0 );
SUPP_FILE_SERVICE( acc, REQ_FILE_ERASE );
in[0].ptr = &acc;
in[0].len = sizeof( acc );
in[1].ptr = name;
in[1].len = strlen( name ) + 1;
out[0].ptr = &ret;
out[0].len = sizeof( ret );
TrapAccess( 2, &in, 1, &out );
CONV_LE_32( ret.err );
return( StashErrCode( ret.err, OP_REMOTE ) );
}
long RemoteFork( char *cmd, unsigned len )
{
mx_entry in[2];
mx_entry out[1];
file_run_cmd_req acc;
file_run_cmd_ret ret;
if( SuppFileId == 0 ) return( 0 );
SUPP_FILE_SERVICE( acc, REQ_FILE_RUN_CMD );
acc.chk_size = CheckSize;
in[0].ptr = &acc;
in[0].len = sizeof( acc );
in[1].ptr = cmd;
in[1].len = len;
out[0].ptr = &ret;
out[0].len = sizeof( ret );
TrapAccess( 2, &in, 1, &out );
CONV_LE_32( ret.err );
return( StashErrCode( ret.err, OP_REMOTE ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?