Skip to content

Commit 417f5a5

Browse files
author
Shannon Noe
committed
Add channelfd command
Add channelfd command to get the Unix file handle number from a TCL channel name.
1 parent eca60cb commit 417f5a5

File tree

4 files changed

+106
-1
lines changed

4 files changed

+106
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ _$*
2020
*.o
2121
*.obj
2222
*.so
23+
*.dylib
2324
*.exe
2425
*.Z
2526
*.elc

configure.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ TEA_ADD_SOURCES([
4444
tclXinit.c tclXkeylist.c tclXlib.c tclXlist.c
4545
tclXmath.c tclXmsgcat.c tclXprocess.c tclXprofile.c
4646
tclXselect.c tclXsignal.c tclXstring.c tclXsocket.c
47-
tclXutil.c tclXoscmds.c tclXlgets.c
47+
tclXutil.c tclXoscmds.c tclXlgets.c tclXchannelfd.c
4848
])
4949
TEA_ADD_HEADERS([generic/tclExtend.h])
5050
TEA_ADD_INCLUDES([-I\"`${CYGPATH} ${srcdir}/generic`\"])

generic/tclXinit.c

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ Tclxcmd_Init (Tcl_Interp *interp)
121121
TclX_ProfileInit (interp);
122122
TclX_SelectInit (interp);
123123
TclX_StringInit (interp);
124+
TclX_ChannelFdInit(interp);
124125

125126
if (!Tcl_IsSafe(interp)) {
126127
/*

unix/tclXchannelfd.c

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* tclXchannelfd.c --
3+
*
4+
* OS system dependent interface for unix systems. The idea behind these
5+
* functions is to provide interfaces to various functions that vary on the
6+
* various platforms. These functions either implement the call in a manner
7+
* approriate to the platform or return an error indicating the functionality
8+
* is not available on that platform. This results in code with minimal
9+
* number of #ifdefs.
10+
*-----------------------------------------------------------------------------
11+
* Copyright 2017 Shannon Noe
12+
*
13+
* Permission to use, copy, modify, and distribute this software and its
14+
* documentation for any purpose and without fee is hereby granted, provided
15+
* that the above copyright notice appear in all copies. Karl Lehenbauer and
16+
* Mark Diekhans make no representations about the suitability of this
17+
* software for any purpose. It is provided "as is" without express or
18+
* implied warranty.
19+
*-----------------------------------------------------------------------------
20+
*/
21+
22+
#include "tclExtdInt.h"
23+
24+
/*-----------------------------------------------------------------------------
25+
* ChannelToFd --
26+
*
27+
* Convert a channel to a file descriptor.
28+
*
29+
* Parameters:
30+
* o channel - Channel to get file number for.
31+
* o direction - TCL_READABLE or TCL_WRITABLE, or zero. If zero, then
32+
* return the first of the read and write numbers.
33+
* o type - The type of the file. not set if an error occurs.
34+
*
35+
* Returns:
36+
* The unix file descriptor of the channel.
37+
*-----------------------------------------------------------------------------
38+
*/
39+
static int
40+
ChannelToFd (Tcl_Channel channel,
41+
int direction)
42+
{
43+
ClientData handle;
44+
int fd = -1;
45+
46+
if (direction == 0) {
47+
if (Tcl_GetChannelHandle (channel, TCL_READABLE, &handle) != TCL_OK &&
48+
Tcl_GetChannelHandle (channel, TCL_WRITABLE, &handle) != TCL_OK) {
49+
return -1;
50+
}
51+
} else {
52+
if (Tcl_GetChannelHandle (channel, direction, &handle) != TCL_OK) {
53+
return -1;
54+
}
55+
}
56+
57+
memcpy(&fd, &handle, sizeof(fd));
58+
59+
return fd;
60+
}
61+
62+
static int
63+
TclX_ChannelFdObjCmd (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
64+
{
65+
const char *channelName;
66+
Tcl_Channel channel;
67+
int fd;
68+
69+
if (objc < 2)
70+
return TclX_WrongArgs (interp, objv [0], "arg ?arg...?");
71+
72+
channelName = Tcl_GetStringFromObj (objv [1], NULL);
73+
74+
if (channelName) {
75+
channel = Tcl_GetChannel (interp, channelName, NULL);
76+
fd = ChannelToFd(channel, 0);
77+
78+
if (fd != -1) {
79+
Tcl_SetObjResult (interp, Tcl_NewIntObj(fd));
80+
return TCL_OK;
81+
}
82+
}
83+
84+
Tcl_SetResult(interp, "failed to get file descriptor from channel", TCL_STATIC);
85+
return TCL_ERROR;
86+
}
87+
88+
/*-----------------------------------------------------------------------------
89+
* TclX_ChannelFdInit --
90+
* Initialize the channelfd command.
91+
*-----------------------------------------------------------------------------
92+
*/
93+
void
94+
TclX_ChannelFdInit (Tcl_Interp *interp)
95+
{
96+
Tcl_CreateObjCommand (interp,
97+
"channelfd",
98+
TclX_ChannelFdObjCmd,
99+
(ClientData) NULL,
100+
(Tcl_CmdDeleteProc*) NULL);
101+
}
102+
103+
/* vim: set ts=4 sw=4 sts=4 et : */

0 commit comments

Comments
 (0)