From: Rolf K. <rol...@ci...> - 2004-03-10 12:49:26
|
Jim Kring [mailto:ji...@ji...] wrote: > Regarding TortoiseCVS and piping into Plink, here is a snip > from an email I > got back from Ian: > > ########### > > My first take used the WinAPI file functions to read/write > pipes (ReadFile and WriteFile). I now see that the Tortoise > project has now added POSIX calls for the non-Win32 interface. > It might be possible to use POSIX calls from msvcrt instead > of Win32 calls from User32. Not sure what the advantage of this would be. Win32 specific code will be in there anyway and msvcrt is just built on top of the Win32 API so you basically add another software layer to it. And last but not least msvcrt is not fully POSIX complaint so you may end up with platform differences even there. > Both chunks of code are in the link below (see the "run" > function about two-thirds of the way down). I'll take a quick > peek at using execvp() from LabVIEW. > > <http://cvs.sourceforge.net/viewcvs.py/tortoisecvs/TortoiseCVS > /src/cvsgui/cv > sgui_process.cpp?rev=1.7&view=auto> I think the clean solution here would be rather to create a DLL which provides the same interface as that used by the Linux VIs. That will be enough problems to tackle I'm sure. Enclosed is a first version of what I have in mind. Rough and not tested yet but what I would see a possible implementation. Need yet to add the PipeOpenCmd implementation. Rolf Kalbermatter /* * Pipe shared library for LabVIEW * * Copyright (C) 2004 Rolf Kalbermatter, r.k...@hc... * * Please visit http://www.OpenG.org to learn about the * Open Source LabVIEW software movement. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "extcode.h" #include <windows.h> #ifdef _DEBUG #define DebugBreaking() {__asm int 3} #else #define DebugBreaking() #endif #if defined(PIPES_EXPORTS) #define LibAPI __declspec(dllexport) __cdecl #else #define LibAPI static #endif typedef enum { kReadMode, kWriteMode, kReadWriteMode } Modes; MgErr LibAPI PipeOpen(CStr name, uInt8 mode, uInt32 *fd); MgErr LibAPI PipeOpenCmd(CStr name, uInt8 mode, uInt32 *fdIn, uInt32 *fdOut, uInt32 *fdErr, uInt32 processID); MgErr LibAPI PipeClose(uInt32 fd); MgErr LibAPI PipeRead(uInt32 fd, uInt32 *bytesRead, LStrHandle data, uInt32 *eof); MgErr LibAPI PipeWrite(uInt32 fd, uInt32 *bytesWritten, LStrHandle data); #if defined(MSWin) static MgErr Win32ToLVErr(DWORD error); #elif defined (Unix) static MgErr UnixToLVErr(int32 errno); #endif MgErr LibAPI PipeOpen(CStr name, uInt8 mode, uInt32 *fd) { MgErr err = noErr; #if defined(MSWin) HANDLE handle; DWORD dwMode; DebugBreaking(); if (mode > kReadWriteMode) return mgArgErr; if (WaitNamedPipe(name, 2000)) { switch (mode) { case kReadMode: dwMode = FILE_READ_DATA; break; case kWriteMode: dwMode = FILE_WRITE_DATA; break; case kReadWriteMode: dwMode = FILE_READ_DATA | FILE_WRITE_DATA; break; } /* There is a server to connect to, so connect as client */ handle = CreateFile(name, dwMode, 0, NULL, OPEN_EXISTING, 0 /* SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION */, NULL); } else { switch (mode) { case kReadMode: dwMode = PIPE_ACCESS_INBOUND; break; case kWriteMode: dwMode = PIPE_ACCESS_OUTBOUND; break; case kReadWriteMode: dwMode = PIPE_ACCESS_DUPLEX; break; } /* There is no server to connect to, so create our own server */ handle = CreateNamedPipe(name, dwMode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, PIPE_UNLIMITED_INSTANCES, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); } if (handle == INVALID_HANDLE_VALUE) { err = Win32ToLVErr(GetLastError()); *fd = 0; } else *fd = (uInt32)handle; #elif defined(Unix) #else err = mgNotImplementd: #endif return err; } MgErr LibAPI PipeOpenCmd(CStr name, uInt8 mode, uInt32 *fdIn, uInt32 *fdOut, uInt32 *fdErr, uInt32 processID) { SECURITY_ATTRIBUTES lsa = { 0 }; STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; MgErr err = noErr; return err; } MgErr LibAPI PipeClose(uInt32 fd) { MgErr err = noErr; if (!fd) return mgArgErr; #if defined(MSWin) if (!CloseHandle((HANDLE)fd)) err = Win32ToLVErr(GetLastError()); #elif defined(Unix) if (close((pipe_t)fd) < 0) ..err = UnixToLVErr(errno); #else err = mgNotImplementd: #endif return err;} MgErr LibAPI PipeRead(uInt32 fd, uInt32 *bytesRead, LStrHandle data, uInt32 *eof) { MgErr err = noErr; DWORD ret, bytes = *bytesRead; if (!fd) return mgArgErr; *eof = FALSE; err = NumericArrayResize(uB, 1, (UHandle*)&data, bytes); if (err) return err; /* We need to do this in LabVIEW 7.0 as otherwise the next NumericArrayResize() will optimize out and only copy as much characters as it sees to be in the array into the new handle if any. */ LStrLen(*data) = bytes; #if defined(MSWin) if (!ReadFile((HANDLE)fd, LStrBuf(*data), bytes, bytesRead, NULL)) { ret = GetLastError(); *eof = (ret == ERROR_HANDLE_EOF); if (!*eof) err = Win32ToLVErr(ret); } #elif defined(Unix) *bytesRead = read((pipe_t)fd, LStrBuf(*data), bytes) if (*bytesRead == 0xFFFFFFFF) { *eof = (errno == EEOF); if (!*eof) err = UnixToLVErr(errno); } #else err = mgNotImplementd; #endif if (!err && (bytes != *bytesRead)) { err = NumericArrayResize(uB, 1, &(UHandle)data, *bytesRead); LStrLen(*data) = *bytesRead; } return err; } MgErr LibAPI PipeWrite(uInt32 fd, uInt32 *bytesWritten, LStrHandle data) { MgErr err = noErr; if (!fd) return mgArgErr; #if defined(MSWin) if (!WriteFile((HANDLE)fd, LStrBuf(*data), LStrLen(*data), bytesWritten, NULL) ) err = Win32ToLVErr(GetLastError()); #elif defined(Unix) *bytesWritten = write((pipe_t)fd, LStrBuf(*data), LStrLen(*data); if (*bytesWritten == -1) err = UnixToLVErr(errno); #else err = mgNotImplementd: #endif return err; } #if defined(MSWin) static MgErr Win32ToLVErr(DWORD error) { /* No translation yet */ return error; } #elif defined(Unix) static MgErr UnixToLVErr(int32 errno) { /* No translation yet */ return error; } #endif |