Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.* 1 > Newsgroup comp.lang.tcl

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 07-08-2009, 09:10 AM
Roger O
Guest
 
Posts: n/a
Default tcl file handles on Linux and Windows - advice requested

I am porting a Tcl/Tk/C application from Linux to Windows. It uses Tcl/
Tk to manage files (selection, open, etc.). In one use, a file is
opened by Tcl, and the file descriptor is set in a variable accessible
from C, and the C code can happily read()/write() to/from this file. I
use code like this to get the file descriptor on Linux:

set FileDesc [string trimleft $FileHandle file]

This results in FileDesc being the Linux file descriptor for the file
$FileHandle, which came from an earlier call to Tcl's open.

On Windows, the situation is different. The Tcl open call does not
return a file descriptor as part of the return value. I am guessing it
is, instead, a FILE *, as Windows does not support the C open() call.
I can still use the code above to get the FILE *, but the C code that
would use it can no longer use read/write.

My questions are:

- Is it the case that the Tcl open call on Windows does an fopen(),
whereas on Linux it does an open()? The Tcl open man page makes
reference to fopen() in such a way that one would think that is what
is used. However, the value returned by open is not from fdopen. Does
the Tcl open call use fileno() to get the file descriptor?

- If this is the case, C code that wants to access the open file must
use fread/fwrite on Windows. and read/write on Linux?

- Am I missing some fancy, perhaps even obvious, technique to get
around this? For example, if the Linux Tcl open is really using fopen
on all platforms, and using fileno() in the return value on non-
Windows platforms, can I get the FILE * that Tcl has?

I should point out that I am not mixing read/write between Tcl and C.
I am just letting Tcl open and configure the file.

One interesting thing is that I compile my C library for windows with
MinGW. So I do have a read/write interface. But as the Windows version
of Tcl/tk was not compiled the same way, it does not have open/read/
write/close. Does that sound reasonable? If I compiled Tcl/Tk with
MinGW, would the open/read/write/close interface be used in Tcl? This
is a hypothetical question, as I do not want to do that. I am just
curious.



Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 07-08-2009, 11:19 AM
Kieran
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

On Jul 8, 10:10*am, Roger O <roger.oberholt...@gmail.com> wrote:
> I am porting a Tcl/Tk/C application from Linux to Windows. It uses Tcl/
> Tk to manage files (selection, open, etc.). In one use, a file is
> opened by Tcl, and the file descriptor is set in a variable accessible
> from C, and the C code can happily read()/write() to/from this file.


... snipped ...

> On Windows, the situation is different. The Tcl open call does not
> return a file descriptor as part of the return value. I am guessing it
> is, instead, a FILE *, as Windows does not support the C open() call.
> I can still use the code above to get the FILE *, but the C code that
> would use it can no longer use read/write.
>


You might want to try using the Tcl_GetChannelHandle function to
get the OS-specific file handle from the channel name, rather than
trying to infer it yourself from the channel name.

I'm not a Windows programmer, so I'm not too sure how you turn a
Windows file handle into a C standard library style file descriptor
(especially with MinGW thrown in)!

But I believe there is an _open_osfhandle in the MS C run time
library, so perhaps you need something like this: (untested!)

int writeToChannel (Tcl_Object *channelNameObj) {

char *channelName;
Tcl_Channel channel;
intptr_t os_file_handle;
int fd;

channelName = Tcl_GetStringFromObj(channelNameObj, NULL);
channel = Tcl_GetChannel(interp, channelName, NULL);
if (channel == NULL) {
Tcl_AppendResult(interp,
"could not find channel ",
channelName, (char *) NULL);
return TCL_ERROR;
}

if (Tcl_GetChannelHandle(channel, TCL_WRITABLE,
(ClientData) &os_file_handle) == TCL_ERROR) {
Tcl_AppendResult(interp,
"could not get writable OS device handle for channel ",
channelName, (char *) NULL);
return TCL_ERROR;
}

char *data = "hello\n";
size_t nbytes = strlen(data);

#ifdef WINDOWS
fd = _open_osfhandle (os_file_handle, 0);
#else
fd = (int) os_file_handle;
#endif

/* NB: I've seen some Windows code use _write()
* instead of write() for some reason? */
ssize_t bytes_written = write(fd, data, nbytes);

if (bytes_written != nbytes) {
Tcl_AppendResult(interp,
"failed to write to channel ",
channelName, (char *) NULL);
return TCL_ERROR;
}

return TCL_OK;
}
Reply With Quote
  #3 (permalink)  
Old 07-08-2009, 11:46 AM
Robert Heller
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

At Wed, 8 Jul 2009 02:10:37 -0700 (PDT) Roger O <roger.oberholtzer@gmail.com> wrote:

>
> I am porting a Tcl/Tk/C application from Linux to Windows. It uses Tcl/
> Tk to manage files (selection, open, etc.). In one use, a file is
> opened by Tcl, and the file descriptor is set in a variable accessible
> from C, and the C code can happily read()/write() to/from this file. I
> use code like this to get the file descriptor on Linux:
>
> set FileDesc [string trimleft $FileHandle file]
>
> This results in FileDesc being the Linux file descriptor for the file
> $FileHandle, which came from an earlier call to Tcl's open.
>
> On Windows, the situation is different. The Tcl open call does not
> return a file descriptor as part of the return value. I am guessing it
> is, instead, a FILE *, as Windows does not support the C open() call.
> I can still use the code above to get the FILE *, but the C code that
> would use it can no longer use read/write.
>
> My questions are:
>
> - Is it the case that the Tcl open call on Windows does an fopen(),
> whereas on Linux it does an open()? The Tcl open man page makes
> reference to fopen() in such a way that one would think that is what
> is used. However, the value returned by open is not from fdopen. Does
> the Tcl open call use fileno() to get the file descriptor?
>
> - If this is the case, C code that wants to access the open file must
> use fread/fwrite on Windows. and read/write on Linux?
>
> - Am I missing some fancy, perhaps even obvious, technique to get
> around this? For example, if the Linux Tcl open is really using fopen
> on all platforms, and using fileno() in the return value on non-
> Windows platforms, can I get the FILE * that Tcl has?
>
> I should point out that I am not mixing read/write between Tcl and C.
> I am just letting Tcl open and configure the file.
>
> One interesting thing is that I compile my C library for windows with
> MinGW. So I do have a read/write interface. But as the Windows version
> of Tcl/tk was not compiled the same way, it does not have open/read/
> write/close. Does that sound reasonable? If I compiled Tcl/Tk with
> MinGW, would the open/read/write/close interface be used in Tcl? This
> is a hypothetical question, as I do not want to do that. I am just
> curious.



You really should NOT be mixing C I/O library calls and Tcl I/O calls,
even if the Tcl code is only doing the open. If Tcl opens file file,
the C code should be using the Tcl I/O functions (Tcl_Read, Tcl_Write,
etc.). Otherwise the Tcl code should just pass the [file nativename ...]
string to the C code and let the C code use its own I/O functions.
Mixing things and trying to get the channel number from the file handle
string is not a good idea.

>
>
>
>


--
Robert Heller -- 978-544-6933
Deepwoods Software -- Download the Model Railroad System
http://www.deepsoft.com/ -- Binaries for Linux and MS-Windows
heller@deepsoft.com -- http://www.deepsoft.com/ModelRailroadSystem/

Reply With Quote
  #4 (permalink)  
Old 07-08-2009, 12:17 PM
Roger O
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

On Jul 8, 1:46*pm, Robert Heller <hel...@deepsoft.com> wrote:

> You really should NOT be mixing C I/O library calls and Tcl I/O calls,
> even if the Tcl code is only doing the open. *If Tcl opens file file,
> the C code should be using the Tcl I/O functions (Tcl_Read, Tcl_Write,
> etc.). Otherwise the Tcl code should just pass the [file nativename ...]
> string to the C code and let the C code use its own I/O functions.
> Mixing things and trying to get the channel number from the file handle
> string is not a good idea. *


I know all the arguments. But it really should not be a problem if I
am not mixing the calls in a controlled fashion. As I wrote, I never
mix reading between Tcl and C. That would surely fail. Let's all agree
that I know the possible consequences of my behavior. I just want to
know how to get the OS handle, knowing that it is bastard programming
for which I take full responsibility.
Reply With Quote
  #5 (permalink)  
Old 07-08-2009, 01:06 PM
David Gravereaux
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

Roger O wrote:
...
> Let's all agree
> that I know the possible consequences of my behavior. I just want to
> know how to get the OS handle, knowing that it is bastard programming
> for which I take full responsibility.


Ok, write a Tcl extension that contains Tcl_GetChannelHandle and
executes your C code (which I'll assume is an executable).

On Windows, you'll get a HANDLE rather than a FILE*, though, so use of
fgets()/fwrite() isn't valid for good xplat'ability. I do like Kieran's
advice for use of _open_osfhandle().

What would be excellent in your situation would be to re-use your C-code
in a different manner and create a Tcl extension with it. Change all
your fgets() to be Tcl_Gets, etc. Then you won't have to derive what
the channel represents, and you can operate on the channel directly
using the channel API.

That's the Tcl way of being X-plat.

--



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkpUmcYACgkQlZadkQh/RmG01wCfQeh20rahGNTvGBMcAL2ezIR2
j3YAoKVTcGDwz8uLHgdRpHYLIvjnii4O
=bTBM
-----END PGP SIGNATURE-----

Reply With Quote
  #6 (permalink)  
Old 07-08-2009, 01:47 PM
Mark Janssen
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

On Jul 8, 3:06*pm, David Gravereaux <davyg...@pobox.com> wrote:
> Roger O wrote:
>
> ...
>
> > Let's all agree
> > that I know the possible consequences of my behavior. I just want to
> > know how to get the OS handle, knowing that it is bastard programming
> > for which I take full responsibility.

>
> Ok, write a Tcl extension that contains Tcl_GetChannelHandle and
> executes your C code (which I'll assume is an executable).
>
> On Windows, you'll get a HANDLE rather than a FILE*, though, so use of
> fgets()/fwrite() isn't valid for good xplat'ability. *I do like Kieran's
> advice for use of _open_osfhandle().
>
> What would be excellent in your situation would be to re-use your C-code
> in a different manner and create a Tcl extension with it. *Change all
> your fgets() to be Tcl_Gets, etc. *Then you won't have to derive what
> the channel represents, and you can operate on the channel directly
> using the channel API.
>
> That's the Tcl way of being X-plat.
>
> --
>
> *signature.asc
> < 1KViewDownload


As an added benefit of changing direct C I/O to the Tcl I/O calls is
that you'll get support for VFS for free. This allows your code to
read inside Tclkits for example. Transforming the C code in this way
is fairly straightforward and definitely worth the little effort.

Mark
Reply With Quote
  #7 (permalink)  
Old 07-08-2009, 02:34 PM
Roger O
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

On Jul 8, 3:06*pm, David Gravereaux <davyg...@pobox.com> wrote:

> Ok, write a Tcl extension that contains Tcl_GetChannelHandle and
> executes your C code (which I'll assume is an executable).


The code is part of an image processing library that runs in numerous
places. This is only one. Sometimes the code runs on numerous
computers in a cluster, and these file descriptors refer to sockets.
Sometimes the code runs as part of a Tcl/Tk GUI all on a local
machine, and these very same file descriptors refer to local files. In
both cases, the C code is dynamically loaded. There is Tcl/Tk GUI in
both uses. This works because in the Unix/Linux Tcl, both the open and
the socket command return the file descriptor as part of the return
value. As long as the GUI always ran on Linux, I was a happy camper.

On Windows, I do not care if it is a HANDLE reference that is
returned. I can access that as well.

> On Windows, you'll get a HANDLE rather than a FILE*, though, so use of
> fgets()/fwrite() isn't valid for good xplat'ability. *I do like Kieran's
> advice for use of _open_osfhandle().


If Windows returns a HANDLE, and Unix/Linux an integer file descriptor
(which it does and which works with read/write), than I would imagine
on no platforms does Tcl return a FILE *. I don't mind which is
returned. As long as I know what it is. I can handle the x-platform in
my image processing library. Even if Tcl offers an alternative. The
problem is that the alternative may be too obtrusive. So, I am
checking my options.
Reply With Quote
  #8 (permalink)  
Old 07-08-2009, 04:08 PM
Robert Heller
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

At Wed, 8 Jul 2009 07:34:47 -0700 (PDT) Roger O <roger.oberholtzer@gmail.com> wrote:

>
> On Jul 8, 3:06=A0pm, David Gravereaux <davyg...@pobox.com> wrote:
>
> > Ok, write a Tcl extension that contains Tcl_GetChannelHandle and
> > executes your C code (which I'll assume is an executable).

>
> The code is part of an image processing library that runs in numerous
> places. This is only one. Sometimes the code runs on numerous
> computers in a cluster, and these file descriptors refer to sockets.


To what extent is the *I/O* interspersed with the *image processing*?
From my own experience with image processing (I worked at the UMass
Image Understanding Laboratory for over 20 years), it was often the case
that an image processing program would look like this psuedo code:

get parameters;
read images from disk in to memory;
process images loaded in memory;
write output images (or other data) out to disk;
display statisics or other information;

If your image processing library can be separated into two
sub-libraries, an image I/O library (reads and writes image data between
some external source and memory) and an image processing library (which
only processes in-memory images), then it makes sense to have two
versions of the image I/O library (possibly built from a single code
source using #ifdefs -- which you will need anyway), one version using
'native' I/O (eg open/read/write/close under UNIX and whatever
MS-Windows uses instead of open/read/write/close) and one version using
Tcl's I/O functions
(Tcl_OpenChannel/Tcl_Read/Tcl_Write/Tcl_CloseChannel). Both library act
on some commonly defined in-memory image structure object which gets
passed to/from the image processing library.

> Sometimes the code runs as part of a Tcl/Tk GUI all on a local
> machine, and these very same file descriptors refer to local files. In
> both cases, the C code is dynamically loaded. There is Tcl/Tk GUI in
> both uses. This works because in the Unix/Linux Tcl, both the open and
> the socket command return the file descriptor as part of the return
> value. As long as the GUI always ran on Linux, I was a happy camper.
>
> On Windows, I do not care if it is a HANDLE reference that is
> returned. I can access that as well.
>
> > On Windows, you'll get a HANDLE rather than a FILE*, though, so use of
> > fgets()/fwrite() isn't valid for good xplat'ability. =A0I do like Kieran'=

> s
> > advice for use of _open_osfhandle().

>
> If Windows returns a HANDLE, and Unix/Linux an integer file descriptor
> (which it does and which works with read/write), than I would imagine
> on no platforms does Tcl return a FILE *. I don't mind which is
> returned. As long as I know what it is. I can handle the x-platform in
> my image processing library. Even if Tcl offers an alternative. The
> problem is that the alternative may be too obtrusive. So, I am
> checking my options.
>


--
Robert Heller -- 978-544-6933
Deepwoods Software -- Download the Model Railroad System
http://www.deepsoft.com/ -- Binaries for Linux and MS-Windows
heller@deepsoft.com -- http://www.deepsoft.com/ModelRailroadSystem/

Reply With Quote
  #9 (permalink)  
Old 07-08-2009, 05:00 PM
Gerald W. Lester
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

Roger O wrote:
> I am porting a Tcl/Tk/C application from Linux to Windows. It uses Tcl/
> Tk to manage files (selection, open, etc.). In one use, a file is
> opened by Tcl, and the file descriptor is set in a variable accessible
> from C, and the C code can happily read()/write() to/from this file. I
> use code like this to get the file descriptor on Linux:
>
> set FileDesc [string trimleft $FileHandle file]
>
> This results in FileDesc being the Linux file descriptor for the file
> $FileHandle, which came from an earlier call to Tcl's open.


That is not supported and is not portable. Please use the Tcl C API calls
to translate from a Tcl file handle to a C file descriptor.


--
+------------------------------------------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+
Reply With Quote
  #10 (permalink)  
Old 07-08-2009, 05:08 PM
Helmut Giese
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

Hi Roger,
to me the result of [open] (e.g. 'file1202ed0') looks a lot like it
contains a hexadecimal address.
If your lucky this is the address of the corresponding Tcl_Channel
struct, which surely contains something useful to you.

Of course I would never publicly recommend such an approach.
Good luck
Helmut Giese
Reply With Quote
  #11 (permalink)  
Old 07-09-2009, 09:07 AM
Roger O
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

On Jul 8, 7:00*pm, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:

> That is not supported and is not portable. *Please use the Tcl C API calls
> to translate from a Tcl file handle to a C file descriptor.


I am fully aware that this is not supported (despite the method on
Linux being described in the first Tcl book by Tcl's inventor - I did
not originate it). Sometimes one must hack. I strive not to do so. But
this is a case where I think I will continue trying to sort this out.

I am surprised that the Linux and Windows versions of Tcl do not both
return a channel in the open call. I would be more inclined to sort
out an official Tcl approach if Tcl itself was consistent in what the
open call returned. I suspect that the Linux/Unix open call value was
not changed when channels were added because there is lots of code
doing what I am doing. Even if it is not official. And I am not sure
the Windows version is returning a Channel. I am guessing it is either
a Handle or a FILE *. I will have to check the source. I say this
because I think Tcl's open was implemented on Windows before channels.

Reply With Quote
  #12 (permalink)  
Old 07-09-2009, 09:25 AM
David Gravereaux
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

Roger O wrote:
> On Jul 8, 7:00 pm, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:
>
>> That is not supported and is not portable. Please use the Tcl C API calls
>> to translate from a Tcl file handle to a C file descriptor.

>
> I am fully aware that this is not supported (despite the method on
> Linux being described in the first Tcl book by Tcl's inventor - I did
> not originate it). Sometimes one must hack. I strive not to do so. But
> this is a case where I think I will continue trying to sort this out.
>
> I am surprised that the Linux and Windows versions of Tcl do not both
> return a channel in the open call. I would be more inclined to sort
> out an official Tcl approach if Tcl itself was consistent in what the
> open call returned. I suspect that the Linux/Unix open call value was
> not changed when channels were added because there is lots of code
> doing what I am doing. Even if it is not official. And I am not sure
> the Windows version is returning a Channel. I am guessing it is either
> a Handle or a FILE *. I will have to check the source. I say this
> because I think Tcl's open was implemented on Windows before channels.


Actually, channels came about before the windows port. The thing is,
Tcl is consistent.. channels all the way through. The difference you
see regards open/write/read. There are no such Win32 API calls. The
native ones on windows are OpenFile/WriteFile/ReadFile, IIRC. I think
open/write/read on windows is managed by the runtime.

--



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkpVt30ACgkQlZadkQh/RmH1pACfSS5iG6cOC4rVVL/Ox/wuETSH
TLcAoKdetidi1MPDMje57kI27PjDjKep
=Ommy
-----END PGP SIGNATURE-----

Reply With Quote
  #13 (permalink)  
Old 07-09-2009, 01:56 PM
Gerald W. Lester
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

Roger O wrote:
> On Jul 8, 7:00 pm, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:
>
>> That is not supported and is not portable. Please use the Tcl C API calls
>> to translate from a Tcl file handle to a C file descriptor.

>
> I am fully aware that this is not supported (despite the method on
> Linux being described in the first Tcl book by Tcl's inventor - I did
> not originate it). Sometimes one must hack. I strive not to do so. But
> this is a case where I think I will continue trying to sort this out.


Tcl is consistent -- the value is an opaque handle to be used by Tcl's
internals. You need to use the API call to convert the opaque handle to a C
file descriptor or handle.

Please note, that at *any* release of Tcl -- even a x.y.z bug fix release --
the appearance of that opaque handle may change and your hacks into it will
cease to work. You really need to use the C API.

Suggestion: create a very tiny extension that exposes the
Tcl_GetChannelHandle and Tcl_GetOpenFile in a meaningful way to you.

--
+------------------------------------------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+
Reply With Quote
  #14 (permalink)  
Old 07-09-2009, 04:01 PM
am
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

Roger O wrote:

> On Jul 8, 6:08*pm, Robert Heller <hel...@deepsoft.com> wrote:
>...
> involve 50 kilometers of images (continuous, with 1.6mm per pixel
> resolution). ... individual JPEG2000 images ... are chunked into images of

a
> couple of meters in length, which are analyzed, ...


Wow!
-------------
While there is very good advice given in this thread, there is one more
thing you could look into:

Make sure your filehandle does not start with an "e":
Your
> set FileDesc [string trimleft $FileHandle file]

makes an filee12abcdef into 12abcdef
It is much better to use
set FileDesc [string range $FileHandle 4 end]

man n string
--
Mit freundlichen Grüßen (best regards)

Albrecht Mucha
Software Entwicklung
----------------------------------------------------------------------
MediTec GmbH
IT-Lösungen für das Gesundheitswesen
Griesbergstr. 1b-c eMail : [string map {X {}}
a.Xmucha@Xmeditec-gmbh.com]
31162 Bad Salzdetfurth Internet : www.meditec-gmbh.com
Reply With Quote
  #15 (permalink)  
Old 07-10-2009, 06:16 AM
Roger O
Guest
 
Posts: n/a
Default Re: tcl file handles on Linux and Windows - advice requested

On Jul 9, 6:01*pm, am <a...@medi.xx> wrote:

> Make sure your filehandle does not start with an "e":
> Your> set FileDesc [string trimleft $FileHandle file]
>
> makes an filee12abcdef into 12abcdef
> It is much better to use
> set FileDesc [string range $FileHandle 4 end]


This is a good point. On Linux/Unix, the values following the 'file'
were always '0'-'9'. Windows changed that to be a HEX value. Thanks
for pointing that out.
Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 02:39 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.