Intial commit
This commit is contained in:
433
tcl-dp/api/dpApi.c
Normal file
433
tcl-dp/api/dpApi.c
Normal file
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* dpAPI.c - contains a basic C API for accessing Tcl-DP RPC servers
|
||||
* This is a standalone file and does not require DP or Tcl.
|
||||
*
|
||||
* Note that unlike the Tcl and DP sources, this file
|
||||
* requires an ANSI C compiler.
|
||||
*
|
||||
* This API is extremely multithread unsafe.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "dpApi.h"
|
||||
|
||||
/*------------------ DP RPC protocol defines -----------------*/
|
||||
|
||||
#define TOK_RPC 'e'
|
||||
#define TOK_RDO 'd'
|
||||
#define TOK_RET 'r'
|
||||
#define TOK_ERR 'x'
|
||||
|
||||
/*
|
||||
* The following strings are used to provide callback and/or error
|
||||
* catching for RDOs. c = callback, e = onerror, ce = both
|
||||
*/
|
||||
/*
|
||||
* sprintf template when both callback and onerror are specified.
|
||||
* Params are cmd, onerror, callback
|
||||
*/
|
||||
static char *ceCmdTemplate =
|
||||
"if [catch {%s} dp_rv] {\
|
||||
dp_RDO $dp_rpcFile set errorInfo \"$errorInfo\n while remotely executing\n%s\"; \
|
||||
dp_RDO $dp_rpcFile eval \"%s \\{$dp_rv\\}\"\
|
||||
} else {\
|
||||
dp_RDO $dp_rpcFile eval \"%s \\{$dp_rv\\}\"\
|
||||
}";
|
||||
|
||||
/*
|
||||
* sprintf template when just onerror is specified.
|
||||
* Params are cmd, onerror
|
||||
*/
|
||||
static char *eCmdTemplate =
|
||||
"if [catch {%s} dp_rv] {\
|
||||
dp_RDO $dp_rpcFile set errorInfo \"$errorInfo\n while remotely executing\n%s\"; \
|
||||
dp_RDO $dp_rpcFile eval \"%s \\{$dp_rv\\}\"\
|
||||
}";
|
||||
|
||||
/*
|
||||
* sprintf template when just callback is specified.
|
||||
* Params are cmd, callback
|
||||
*/
|
||||
static char *cCmdTemplate =
|
||||
"set dp_rv [%s]; dp_RDO $dp_rpcFile eval \"%s \\{$dp_rv\\}\"";
|
||||
|
||||
/*----------------------- Globals --------------------------*/
|
||||
|
||||
/*
|
||||
* Holds the latest message received.
|
||||
* bufPtr points to the free space
|
||||
*/
|
||||
#define DP_BUFFER_SIZE 8192
|
||||
|
||||
char retStr[DP_BUFFER_SIZE];
|
||||
static char *bufPtr;
|
||||
|
||||
/*-------------------- Internal Routines -------------------*/
|
||||
|
||||
static int SendRPCMessage (DPServer server, char token,
|
||||
int id, char *msgStr);
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------
|
||||
*
|
||||
* Dp_RPC --
|
||||
*
|
||||
* Send an RPC message to the given server.
|
||||
*
|
||||
* If tv is NULL, there is no timeout, otherwise
|
||||
* the RPC will timeout once tv's amount of time
|
||||
* has passed.
|
||||
*
|
||||
* Results:
|
||||
* errorPtr is non-zero if there was an error.
|
||||
* Returns the Tcl result in a static string.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*--------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
Dp_RPC(server, mesgStr, tv, errorPtr)
|
||||
DPServer server; /* in: TCP socket to send on */
|
||||
char *mesgStr; /* in: RPC string to send */
|
||||
struct timeval *tv; /* in: Timeout value for select() */
|
||||
int *errorPtr; /* out: POSIX errorcode */
|
||||
{
|
||||
int rc, len;
|
||||
int amtRecv = -1, totalAmt = 0;
|
||||
|
||||
*errorPtr = 0;
|
||||
|
||||
/*
|
||||
* Send the RPC to the remote server. Note the 12 is
|
||||
* just a random ID since we don't use IDs.
|
||||
*/
|
||||
rc = SendRPCMessage(server, TOK_RPC, 12, mesgStr);
|
||||
if (rc <= 0) {
|
||||
*errorPtr = errno;
|
||||
strcpy(retStr, "Error writing on socket");
|
||||
return retStr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we want to recv the reply.
|
||||
* We spin in a loop waiting for the entire message
|
||||
* to arrive. This gets a bit messy.
|
||||
*/
|
||||
bufPtr = retStr;
|
||||
while (amtRecv < totalAmt) {
|
||||
char lengthStr[7];
|
||||
|
||||
rc = Dp_WaitForSocket(server, tv);
|
||||
if (rc <= 0) {
|
||||
if (rc == 0) {
|
||||
*errorPtr = -1;
|
||||
strcpy(retStr, "RPC timed out");
|
||||
return retStr;
|
||||
} else {
|
||||
*errorPtr = errno;
|
||||
strcpy(retStr, "Select error");
|
||||
return retStr;
|
||||
}
|
||||
}
|
||||
amtRecv = recv(server, bufPtr, (retStr + DP_BUFFER_SIZE) - bufPtr, 0);
|
||||
if ((amtRecv >= 6) && (totalAmt == 0)) {
|
||||
/*
|
||||
* Extract the length field from the incoming message
|
||||
* so we know when we have recv'd the entire message.
|
||||
*/
|
||||
strncpy(lengthStr, retStr, 6);
|
||||
lengthStr[6] = '\0';
|
||||
totalAmt = atoi(lengthStr);
|
||||
} else if (amtRecv == 0) {
|
||||
/*
|
||||
* EOF
|
||||
*/
|
||||
break;
|
||||
}
|
||||
bufPtr += amtRecv;
|
||||
}
|
||||
|
||||
if (retStr[7] == 'x') {
|
||||
*errorPtr = -1;
|
||||
}
|
||||
len = totalAmt - 16;
|
||||
memcpy(retStr, &retStr[16], len);
|
||||
retStr[len] = '\0';
|
||||
return retStr;
|
||||
}
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------
|
||||
*
|
||||
* Dp_RDOSend --
|
||||
*
|
||||
* Send an RDO message to the given server.
|
||||
* It is the caller's responsibilty to call
|
||||
* Dp_RDORead if we need a return code or error.
|
||||
* The size of the RDO is limited to BUFFER_SIZE - 1.
|
||||
*
|
||||
* Results:
|
||||
* Amount sent.
|
||||
*
|
||||
* Side effects:
|
||||
* Destroys previous value of retStr.
|
||||
*
|
||||
*--------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
Dp_RDOSend(server, mesgStr, flags)
|
||||
DPServer server;
|
||||
char *mesgStr;
|
||||
int flags;
|
||||
{
|
||||
char bigBuf[8096];
|
||||
/*
|
||||
* This is our fake callback/error Tcl script.
|
||||
* This is necessary for compatibility with DP 4.0.
|
||||
* Note since we will never evaluate the return
|
||||
* script, this can be anything.
|
||||
*/
|
||||
char *dummy = "mperham";
|
||||
int len, amt;
|
||||
|
||||
switch (flags) {
|
||||
case DP_REPORT_ERROR:
|
||||
sprintf(bigBuf, eCmdTemplate, mesgStr, mesgStr, dummy);
|
||||
break;
|
||||
case DP_RETURN_VALUE:
|
||||
sprintf(bigBuf, cCmdTemplate, mesgStr, mesgStr, dummy);
|
||||
break;
|
||||
case DP_RETURN_VALUE | DP_REPORT_ERROR:
|
||||
sprintf(bigBuf, ceCmdTemplate, mesgStr, mesgStr, dummy, dummy);
|
||||
break;
|
||||
default:
|
||||
strcpy(bigBuf, mesgStr);
|
||||
break;
|
||||
}
|
||||
|
||||
amt = SendRPCMessage(server, TOK_RDO, 0, bigBuf);
|
||||
|
||||
/*
|
||||
* Now we need to hack the amount sent because
|
||||
* the caller knows nothing about the templates
|
||||
* used above and thus will think an error
|
||||
* has happened because amtSent != strlen(mesgStr)
|
||||
*/
|
||||
|
||||
len = strlen(mesgStr);
|
||||
if (amt >= len) {
|
||||
return len;
|
||||
} else {
|
||||
return amt;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------
|
||||
*
|
||||
* Dp_RDORead --
|
||||
*
|
||||
* Recv's an RDO response from the given server.
|
||||
*
|
||||
* Results:
|
||||
* Pointer to the string from the DP server or
|
||||
* NULL with errorPtr set to a POSIX error.
|
||||
*
|
||||
* Side effects:
|
||||
* Destroys previous value of retStr.
|
||||
*
|
||||
*--------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
Dp_RDORead(server, errorPtr)
|
||||
DPServer server;
|
||||
int *errorPtr;
|
||||
{
|
||||
int amount, len;
|
||||
|
||||
amount = recv(server, retStr, DP_BUFFER_SIZE, 0);
|
||||
if (amount <= 0) {
|
||||
if (amount == 0) {
|
||||
/*
|
||||
* EOF on socket
|
||||
*/
|
||||
*errorPtr = ECONNRESET;
|
||||
return NULL;
|
||||
}
|
||||
*errorPtr = errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = amount - 16;
|
||||
memcpy(retStr, &retStr[16], len);
|
||||
retStr[len] = '\0';
|
||||
return retStr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------
|
||||
*
|
||||
* Dp_WaitForServer --
|
||||
*
|
||||
* Waits until the given socket is readable.
|
||||
*
|
||||
* Results:
|
||||
*
|
||||
* 0 if we timeout before the socket is readable
|
||||
* < 0 if there is an error.
|
||||
* > 0 if the socket is now readable.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*--------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
Dp_WaitForServer(server, tv)
|
||||
DPServer server;
|
||||
struct timeval *tv;
|
||||
{
|
||||
fd_set readFD;
|
||||
|
||||
FD_ZERO(&readFD);
|
||||
FD_SET(server, &readFD);
|
||||
return select(1, &readFD, NULL, NULL, tv);
|
||||
}
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------
|
||||
*
|
||||
* Dp_ConnectToServer --
|
||||
*
|
||||
* Creates a TCP connection to a given IP addr and port.
|
||||
*
|
||||
* Results:
|
||||
* returns the socket or -1 on error.
|
||||
*
|
||||
* Side effects:
|
||||
* Creates a new socket. This function can block forever
|
||||
* at the Dp_WaitForServer() or recv() calls. Be careful.
|
||||
*
|
||||
*--------------------------------------------------------------
|
||||
*/
|
||||
|
||||
DPServer
|
||||
Dp_ConnectToServer(int inetAddr, int port)
|
||||
{
|
||||
DPServer sock;
|
||||
struct sockaddr_in myAddr;
|
||||
struct sockaddr_in destAddr;
|
||||
int rc;
|
||||
char EOL;
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
myAddr.sin_addr.s_addr = INADDR_ANY;
|
||||
myAddr.sin_family = AF_INET;
|
||||
myAddr.sin_port = 0;
|
||||
|
||||
rc = bind(sock, (struct sockaddr *) &myAddr, sizeof(myAddr));
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
destAddr.sin_addr.s_addr = htonl(inetAddr);
|
||||
destAddr.sin_family = AF_INET;
|
||||
destAddr.sin_port = htons((unsigned short)port);
|
||||
rc = connect(sock, (struct sockaddr *) &destAddr,
|
||||
sizeof(destAddr));
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Tcl-DP RPC library sends "Connection accepted"
|
||||
* upon successful linkup with a DP RPC server. We
|
||||
* need to strip that off now so that future reads
|
||||
* don't get confused.
|
||||
*
|
||||
* There is a slight problem here in that we don't know
|
||||
* what the EOL indictator is. We'll read in 20, which
|
||||
* is 19 + 1 character for EOL. If the last char is
|
||||
* \r, we'll read in another byte since the server
|
||||
* sent \r\n. This completely overlooks the fact
|
||||
* that Macs send \r as their EOL, but since DP
|
||||
* isn't suppose to run on Macs, this is an acceptable
|
||||
* hack.
|
||||
*/
|
||||
|
||||
Dp_WaitForSocket(sock, NULL);
|
||||
|
||||
rc = recv(sock, retStr, 20, 0);
|
||||
while (rc < 20) {
|
||||
rc += recv(sock, &retStr[rc], 20 - rc, 0);
|
||||
}
|
||||
|
||||
EOL = retStr[19];
|
||||
retStr[19] = '\0';
|
||||
if (strcmp("Connection accepted", retStr)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (EOL == '\r') {
|
||||
if (recv(sock, &EOL, 1, 0) != 1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
/* ============================================================= *
|
||||
* =================== Internal Routines ======================= *
|
||||
* ============================================================= */
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------
|
||||
*
|
||||
* SendRPCMessage --
|
||||
*
|
||||
* Send an RPC message on the given socket.
|
||||
*
|
||||
* Results:
|
||||
* Number of bytes sent on the socket.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*--------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
SendRPCMessage(server, token, id, msgStr)
|
||||
DPServer server;
|
||||
char token;
|
||||
int id;
|
||||
char *msgStr;
|
||||
{
|
||||
char *bufStr;
|
||||
int result, totalLength;
|
||||
|
||||
totalLength = strlen(msgStr) + 16;
|
||||
bufStr = malloc(totalLength + 1);
|
||||
sprintf(bufStr, "%6d %c %6d %s", totalLength, token, id++%1000000,
|
||||
msgStr);
|
||||
result = send(server, bufStr, totalLength, 0);
|
||||
free(bufStr);
|
||||
if (result >= 16) {
|
||||
result -= 16;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
29
tcl-dp/api/dpApi.h
Normal file
29
tcl-dp/api/dpApi.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef _DPAPI_H
|
||||
#define _DPAPI_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock.h>
|
||||
typedef int DPServer;
|
||||
#define ECONNRESET WSAECONNRESET
|
||||
#else /* Unix */
|
||||
typedef int DPServer;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RDO flags
|
||||
*/
|
||||
|
||||
#define DP_REPORT_ERROR (1<<0)
|
||||
#define DP_RETURN_VALUE (1<<1)
|
||||
|
||||
/*---------------------- Externally visible API ----------------------*/
|
||||
|
||||
char *Dp_RPC (DPServer server, char *mesgStr,
|
||||
struct timeval *tv, int *errorPtr);
|
||||
int Dp_RDOSend (DPServer server, char *mesgStr,
|
||||
int flags);
|
||||
char *Dp_RDORead (DPServer server, int *errorPtr);
|
||||
int Dp_WaitForServer (DPServer server, struct timeval *tv);
|
||||
DPServer Dp_ConnectToServer (int inetAddr, int port);
|
||||
|
||||
#endif
|
||||
104
tcl-dp/api/dpExample.c
Normal file
104
tcl-dp/api/dpExample.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* api/dpExample.c
|
||||
*
|
||||
* This file provides an example of how to use the DP C API
|
||||
* to perform RPCs and RDOs with a Tcl-DP server.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "dpApi.h"
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
char *rdoStr = "set s 5";
|
||||
char *rpcStr = "set s";
|
||||
int host = 0x7F000001; /* "127.0.0.1" == localhost */
|
||||
int port = 7878;
|
||||
DPServer server;
|
||||
int rc, error;
|
||||
char *rcStr;
|
||||
struct timeval tv;
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Win32 requires an application to initialize
|
||||
* the sockets library before using it. I suppose
|
||||
* this has to do with multithreading...
|
||||
*/
|
||||
WORD ver = 0x0101;
|
||||
WSADATA garbage;
|
||||
|
||||
if (WSAStartup(ver, &garbage)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set our RPC timeout to 5 seconds.
|
||||
*/
|
||||
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/*
|
||||
* Simple RDO - no options
|
||||
*/
|
||||
|
||||
server = Dp_ConnectToServer(host, port);
|
||||
if (server == -1) {
|
||||
printf("Sockets suck.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rc = Dp_RDOSend(server, rdoStr, 0);
|
||||
if (rc != (int)strlen(rdoStr)) {
|
||||
printf("RDOs suck.\n");
|
||||
closesocket(server);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple RPC --
|
||||
*
|
||||
* Error must always be initialized to zero
|
||||
* so that we can tell if there was an error
|
||||
* on this call.
|
||||
*/
|
||||
|
||||
error = 0;
|
||||
rcStr = Dp_RPC(server, rpcStr, NULL, &error);
|
||||
if (error != 0) {
|
||||
printf("Error - Dp_RPC returned: %s\n", rcStr);
|
||||
closesocket(server);
|
||||
return;
|
||||
}
|
||||
printf("%s\n", rcStr);
|
||||
|
||||
/*
|
||||
* Callback RDO
|
||||
*/
|
||||
|
||||
rc = Dp_RDOSend(server, rdoStr, DP_RETURN_VALUE);
|
||||
if (rc != (int)strlen(rdoStr)) {
|
||||
printf("Sending RDOs sucks.\n");
|
||||
closesocket(server);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = Dp_WaitForServer(server, &tv);
|
||||
if (rc <= 0) {
|
||||
printf("Error waiting for reply\n");
|
||||
closesocket(server);
|
||||
return;
|
||||
}
|
||||
|
||||
rcStr = Dp_RDORead(server, &error);
|
||||
if (rcStr == NULL) {
|
||||
printf("Problem with recv\n");
|
||||
closesocket(server);
|
||||
return;
|
||||
}
|
||||
puts(rcStr);
|
||||
|
||||
closesocket(server);
|
||||
}
|
||||
204
tcl-dp/api/makefile.win
Normal file
204
tcl-dp/api/makefile.win
Normal file
@@ -0,0 +1,204 @@
|
||||
# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=api - Win32 Debug
|
||||
!MESSAGE No configuration specified. Defaulting to api - Win32 Debug.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "api - Win32 Release" && "$(CFG)" != "api - Win32 Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE on this makefile
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "api.mak" CFG="api - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "api - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "api - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
################################################################################
|
||||
# Begin Project
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "api - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
|
||||
ALL : "$(OUTDIR)\api.exe"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\dpApi.obj"
|
||||
-@erase "$(INTDIR)\dpExample.obj"
|
||||
-@erase "$(OUTDIR)\api.exe"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
|
||||
CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
|
||||
/Fp"$(INTDIR)/api.pch" /YX /Fo"$(INTDIR)/" /c
|
||||
CPP_OBJS=.\Release/
|
||||
CPP_SBRS=.\.
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)/api.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 wsock32.lib /nologo /subsystem:console /machine:I386
|
||||
LINK32_FLAGS=wsock32.lib /nologo /subsystem:console /incremental:no\
|
||||
/pdb:"$(OUTDIR)/api.pdb" /machine:I386 /out:"$(OUTDIR)/api.exe"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\dpApi.obj" \
|
||||
"$(INTDIR)\dpExample.obj"
|
||||
|
||||
"$(OUTDIR)\api.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "api - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
|
||||
ALL : "$(OUTDIR)\api.exe"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\dpApi.obj"
|
||||
-@erase "$(INTDIR)\dpExample.obj"
|
||||
-@erase "$(INTDIR)\vc40.idb"
|
||||
-@erase "$(INTDIR)\vc40.pdb"
|
||||
-@erase "$(OUTDIR)\api.exe"
|
||||
-@erase "$(OUTDIR)\api.ilk"
|
||||
-@erase "$(OUTDIR)\api.pdb"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
|
||||
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
|
||||
/Fp"$(INTDIR)/api.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
|
||||
CPP_OBJS=.\Debug/
|
||||
CPP_SBRS=.\.
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)/api.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
|
||||
# ADD LINK32 wsock32.lib /nologo /subsystem:console /debug /machine:I386
|
||||
LINK32_FLAGS=wsock32.lib /nologo /subsystem:console /incremental:yes\
|
||||
/pdb:"$(OUTDIR)/api.pdb" /debug /machine:I386 /out:"$(OUTDIR)/api.exe"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\dpApi.obj" \
|
||||
"$(INTDIR)\dpExample.obj"
|
||||
|
||||
"$(OUTDIR)\api.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
.c{$(CPP_OBJS)}.obj:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
.cpp{$(CPP_OBJS)}.obj:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
.cxx{$(CPP_OBJS)}.obj:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
.c{$(CPP_SBRS)}.sbr:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
.cpp{$(CPP_SBRS)}.sbr:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
.cxx{$(CPP_SBRS)}.sbr:
|
||||
$(CPP) $(CPP_PROJ) $<
|
||||
|
||||
################################################################################
|
||||
# Begin Target
|
||||
|
||||
# Name "api - Win32 Release"
|
||||
# Name "api - Win32 Debug"
|
||||
|
||||
!IF "$(CFG)" == "api - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "api - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dpExample.c
|
||||
DEP_CPP_DPEXA=\
|
||||
".\dpApi.h"\
|
||||
|
||||
|
||||
"$(INTDIR)\dpExample.obj" : $(SOURCE) $(DEP_CPP_DPEXA) "$(INTDIR)"
|
||||
|
||||
|
||||
# End Source File
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dpApi.c
|
||||
DEP_CPP_DPAPI=\
|
||||
".\dpApi.h"\
|
||||
|
||||
|
||||
"$(INTDIR)\dpApi.obj" : $(SOURCE) $(DEP_CPP_DPAPI) "$(INTDIR)"
|
||||
|
||||
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
################################################################################
|
||||
56
tcl-dp/api/readme.api
Normal file
56
tcl-dp/api/readme.api
Normal file
@@ -0,0 +1,56 @@
|
||||
Tcl-DP API for C
|
||||
----------------
|
||||
|
||||
The file, dpApi.c, contains functions that can be used to contact
|
||||
a Tcl-DP server and for sending RPCs and RDOs for evaluation by the
|
||||
server.
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
|
||||
DpServer Dp_ConnectToServer(int inetAddr, int port);
|
||||
|
||||
Opens a connection to a Tcl-DP RPC server. Note that the remote
|
||||
server must have been opened using dp_MakeRPCServer or this function
|
||||
will fail. -1 will be returned if there was an error. Both arguments
|
||||
should be given in host byte order.
|
||||
|
||||
|
||||
char *Dp_RPC(DpServer s, char *msg, struct timeval *tv, int *errorPtr);
|
||||
|
||||
This is the function used to send an RPC to server s. msg is the
|
||||
Tcl string to evaluate and tv is the timeout length (or NULL for infinite).
|
||||
errorPtr will be non-zero when the function returns if there was an
|
||||
error and the return value will be an error message. Otherwise the
|
||||
return value is the return value of the remote evaluation of the RPC.
|
||||
|
||||
|
||||
int Dp_RDOSend(DPServer s, char *rdoStr, int flags);
|
||||
|
||||
Sends an RDO, rdoStr, to a Tcl-DP RPC server s. flags is a combonation
|
||||
of DP_REPORT_ERROR and DP_RETURN_VALUE. These act the same as the
|
||||
-callback and -error flags in the DP API. Returns the amount of data
|
||||
sent to the server (should be strlen(rdoStr)).
|
||||
|
||||
|
||||
char *Dp_RDORead(DPServer s, int *errorPtr);
|
||||
|
||||
Receives a response from a previous RDO. This will block forever
|
||||
if there is no response to an RDO (e.g. asking for an error return
|
||||
but there is no error). Returns the Tcl return string or, if
|
||||
errorPtr is non-zero, an error message.
|
||||
|
||||
|
||||
int Dp_WaitForServer(DPServer s, struct timeval *tv);
|
||||
|
||||
Sleeps until there is a message from the server or tv expires.
|
||||
If tv is NULL, we will block until data is received from the server.
|
||||
Returns 0 if we timed out, < 0 if there was an error or > 0 if
|
||||
the socket is now readable.
|
||||
|
||||
|
||||
Bugs (oh no!)
|
||||
-------------
|
||||
|
||||
Mail tcl-dp@cs.cornell.edu.
|
||||
Reference in New Issue
Block a user