158
186
static int wait_any P((int interesting));
160
188
static IOBUF *gawk_popen P((const char *cmd, struct redirect *rp));
161
static IOBUF *iop_open P((const char *file, const char *how, IOBUF *buf));
189
static IOBUF *iop_open P((const char *file, const char *how, IOBUF *buf, int *isdir));
162
190
static IOBUF *iop_alloc P((int fd, const char *name, IOBUF *buf));
163
191
static int gawk_pclose P((struct redirect *rp));
164
192
static int do_pathopen P((const char *file));
165
193
static int str2mode P((const char *mode));
166
static void spec_setup P((IOBUF *iop, int len, int allocate));
167
static int specfdopen P((IOBUF *iop, const char *name, const char *mode));
168
static int pidopen P((IOBUF *iop, const char *name, const char *mode));
169
static int useropen P((IOBUF *iop, const char *name, const char *mode));
194
static void spec_setup P((IOBUF *iop, int len));
195
static IOBUF *specfdopen P((IOBUF *iop, const char *name, const char *mode));
196
static IOBUF *pidopen P((IOBUF *iop, const char *name, const char *mode));
197
static IOBUF *useropen P((IOBUF *iop, const char *name, const char *mode));
170
198
static int two_way_open P((const char *str, struct redirect *rp));
171
199
static int pty_vs_pipe P((const char *command));
1131
1172
#ifdef HAVE_SOCKETS
1132
1174
/* socketopen --- open a socket and set it into connected state */
1135
socketopen(enum inet_prot type, int localport, int remoteport, const char *remotehostname)
1177
socketopen(int type, const char *localpname, const char *remotepname,
1178
const char *remotehostname)
1137
struct hostent *hp = gethostbyname(remotehostname);
1138
struct sockaddr_in local_addr, remote_addr;
1140
int any_remote_host = strcmp(remotehostname, "0");
1142
socket_fd = INVALID_HANDLE;
1145
if (localport != 0 || remoteport != 0) {
1148
struct linger linger;
1150
memset(& linger, '\0', sizeof(linger));
1152
socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1153
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,
1154
(char *) & on, sizeof(on));
1157
linger.l_linger = 30; /* linger for 30/100 second */
1158
setsockopt(socket_fd, SOL_SOCKET, SO_LINGER,
1159
(char *) & linger, sizeof(linger));
1180
struct addrinfo *lres, *lres0;
1181
struct addrinfo lhints;
1182
struct addrinfo *rres, *rres0;
1183
struct addrinfo rhints;
1188
int socket_fd = INVALID_HANDLE;
1189
int any_remote_host = (strcmp(remotehostname, "0") == 0);
1191
memset (&lhints, '\0', sizeof (lhints));
1192
lhints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
1193
lhints.ai_socktype = type;
1195
lerror = getaddrinfo (NULL, localpname, &lhints, &lres);
1197
if (strcmp(localpname, "0") != 0)
1198
fatal(_("local port %s invalid in `/inet'"), localpname);
1204
while (lres != NULL) {
1205
memset (&rhints, '\0', sizeof (rhints));
1206
rhints.ai_flags = lhints.ai_flags;
1207
rhints.ai_socktype = lhints.ai_socktype;
1208
rhints.ai_family = lhints.ai_family;
1209
rhints.ai_protocol = lhints.ai_protocol;
1211
rerror = getaddrinfo (remotehostname, remotepname, &rhints, &rres);
1214
freeaddrinfo(lres0);
1215
fatal(_("remote host and port information (%s, %s) invalid"), remotehostname, remotepname);
1164
if (localport != 0 || remoteport != 0)
1165
socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1169
if (localport == 0 && remoteport == 0)
1170
socket_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
1180
if (socket_fd < 0 || socket_fd == INVALID_HANDLE
1181
|| (hp == NULL && any_remote_host != 0))
1182
return INVALID_HANDLE;
1184
local_addr.sin_family = remote_addr.sin_family = AF_INET;
1185
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
1186
remote_addr.sin_addr.s_addr = htonl(INADDR_ANY);
1187
local_addr.sin_port = htons(localport);
1188
remote_addr.sin_port = htons(remoteport);
1189
if (bind(socket_fd, (struct sockaddr *) &local_addr, sizeof(local_addr)) == 0) {
1190
if (any_remote_host != 0) { /* not ANY => create a client */
1191
if (type == INET_TCP || type == INET_UDP) {
1192
memcpy(&remote_addr.sin_addr, hp->h_addr,
1193
sizeof(remote_addr.sin_addr));
1194
if (connect(socket_fd,
1195
(struct sockaddr *) &remote_addr,
1196
sizeof(remote_addr)) != 0) {
1199
socket_fd = INVALID_HANDLE;
1201
socket_fd = socketopen(type, localport, 0, "0");
1218
socket_fd = INVALID_HANDLE;
1219
while (rres != NULL) {
1220
socket_fd = socket (rres->ai_family,
1221
rres->ai_socktype, rres->ai_protocol);
1222
if (socket_fd < 0 || socket_fd == INVALID_HANDLE)
1225
if (type == SOCK_STREAM) {
1228
struct linger linger;
1229
memset(& linger, '\0', sizeof(linger));
1231
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,
1232
(char *) & on, sizeof(on));
1235
linger.l_linger = 30; /* linger for 30/100 second */
1236
setsockopt(socket_fd, SOL_SOCKET, SO_LINGER,
1237
(char *) & linger, sizeof(linger));
1240
if (bind(socket_fd, lres->ai_addr, lres->ai_addrlen) != 0)
1243
if (! any_remote_host) { /* not ANY => create a client */
1244
if (type != SOCK_RAW) {
1245
if (connect(socket_fd, rres->ai_addr,
1246
rres->ai_addrlen) == 0)
1249
/* /inet/raw client not ready yet */
1250
fatal(_("/inet/raw client not ready yet, sorry"));
1252
/* FIXME: is this second fatal ever reached? */
1253
fatal(_("only root may use `/inet/raw'."));
1204
/* /inet/raw client not ready yet */
1205
fatal(_("/inet/raw client not ready yet, sorry"));
1207
fatal(_("only root may use `/inet/raw'."));
1209
} else { /* remote host is ANY => create a server */
1210
if (type == INET_TCP) {
1211
int clientsocket_fd = INVALID_HANDLE;
1212
socklen_t namelen = sizeof(remote_addr);
1214
if (listen(socket_fd, 1) >= 0
1215
&& (clientsocket_fd = accept(socket_fd,
1255
} else { /* remote host is ANY => create a server */
1256
if (type == SOCK_STREAM) {
1257
int clientsocket_fd = INVALID_HANDLE;
1259
struct sockaddr_storage remote_addr;
1260
socklen_t namelen = sizeof (remote_addr);
1262
if (listen(socket_fd, 1) >= 0
1263
&& (clientsocket_fd = accept(socket_fd,
1216
1264
(struct sockaddr *) &remote_addr,
1217
1265
&namelen)) >= 0) {
1219
socket_fd = clientsocket_fd;
1222
socket_fd = INVALID_HANDLE;
1224
} else if (type == INET_UDP) {
1267
socket_fd = clientsocket_fd;
1270
} else if (type == SOCK_DGRAM) {
1225
1271
#ifdef MSG_PEEK
1273
struct sockaddr_storage remote_addr;
1229
if (recvfrom(socket_fd, buf, 1, MSG_PEEK,
1230
(struct sockaddr *) & remote_addr,
1232
|| readle != sizeof(remote_addr)
1233
|| connect(socket_fd,
1234
(struct sockaddr *)& remote_addr,
1237
socket_fd = INVALID_HANDLE;
1276
if (recvfrom(socket_fd, buf, 1, MSG_PEEK,
1277
(struct sockaddr *) & remote_addr,
1280
&& connect(socket_fd,
1281
(struct sockaddr *)& remote_addr,
1286
/* /inet/raw server not ready yet */
1287
fatal(_("/inet/raw server not ready yet, sorry"));
1289
fatal(_("only root may use `/inet/raw'."));
1241
/* /inet/raw server not ready yet */
1242
fatal(_("/inet/raw server not ready yet, sorry"));
1244
fatal(_("only root may use `/inet/raw'."));
1294
if (socket_fd != INVALID_HANDLE)
1296
socket_fd = INVALID_HANDLE;
1297
rres = rres->ai_next;
1249
socket_fd = INVALID_HANDLE;
1299
freeaddrinfo(rres0);
1300
if (socket_fd != INVALID_HANDLE)
1302
lres = lres->ai_next;
1305
freeaddrinfo(lres0);
1252
1307
return socket_fd;