Mercurial > hg > xemacs-beta
comparison src/lstream.c @ 5922:4b055de36bb9 cygwin
merging heads 2
author | Henry Thompson <ht@markup.co.uk> |
---|---|
date | Fri, 27 Feb 2015 17:47:15 +0000 |
parents | a216b3c2b09e |
children |
comparison
equal
deleted
inserted
replaced
5921:68639fb08af8 | 5922:4b055de36bb9 |
---|---|
26 #include "lisp.h" | 26 #include "lisp.h" |
27 | 27 |
28 #include "buffer.h" | 28 #include "buffer.h" |
29 #include "insdel.h" | 29 #include "insdel.h" |
30 #include "lstream.h" | 30 #include "lstream.h" |
31 #include "tls.h" | |
31 | 32 |
32 #include "sysfile.h" | 33 #include "sysfile.h" |
33 | 34 |
34 /* This module provides a generic buffering stream implementation. | 35 /* This module provides a generic buffering stream implementation. |
35 Conceptually, you send data to the stream or read data from the | 36 Conceptually, you send data to the stream or read data from the |
740 Lstream_read (Lstream *lstr, void *data, Bytecount size) | 741 Lstream_read (Lstream *lstr, void *data, Bytecount size) |
741 { | 742 { |
742 return Lstream_read_1 (lstr, data, size, 0); | 743 return Lstream_read_1 (lstr, data, size, 0); |
743 } | 744 } |
744 | 745 |
746 int | |
747 Lstream_errno (Lstream *lstr) | |
748 { | |
749 return (lstr->imp->error) ? (lstr->imp->error) (lstr) : 0; | |
750 } | |
751 | |
745 Charcount | 752 Charcount |
746 Lstream_character_tell (Lstream *lstr) | 753 Lstream_character_tell (Lstream *lstr) |
747 { | 754 { |
748 Charcount ctell = lstr->imp->character_tell ? | 755 Charcount ctell = lstr->imp->character_tell ? |
749 lstr->imp->character_tell (lstr) : -1; | 756 lstr->imp->character_tell (lstr) : -1; |
982 { | 989 { |
983 unsigned char ch = (unsigned char) c; | 990 unsigned char ch = (unsigned char) c; |
984 Lstream_unread (lstr, &ch, 1); | 991 Lstream_unread (lstr, &ch, 1); |
985 } | 992 } |
986 | 993 |
994 /* Detect an active TLS session */ | |
995 | |
996 int | |
997 Lstream_tls_p (Lstream *lstr) | |
998 { | |
999 return (lstr->imp->tls_p) ? (lstr->imp->tls_p) (lstr) : 0; | |
1000 } | |
1001 | |
1002 /* STARTTLS negotiation */ | |
1003 | |
1004 int | |
1005 Lstream_tls_negotiate (Lstream *instr, Lstream *outstr, const Extbyte *host, | |
1006 Lisp_Object keylist) | |
1007 { | |
1008 return (instr->imp->tls_negotiater) | |
1009 ? (instr->imp->tls_negotiater) (instr, outstr, host, keylist) | |
1010 : 0; | |
1011 } | |
1012 | |
987 | 1013 |
988 /************************ some stream implementations *********************/ | 1014 /************************ some stream implementations *********************/ |
989 | 1015 |
990 /*********** a stdio stream ***********/ | 1016 /*********** a stdio stream ***********/ |
991 | 1017 |
1109 | 1135 |
1110 /*********** a file descriptor ***********/ | 1136 /*********** a file descriptor ***********/ |
1111 | 1137 |
1112 struct filedesc_stream | 1138 struct filedesc_stream |
1113 { | 1139 { |
1140 tls_state_t *tls_state; | |
1114 int fd; | 1141 int fd; |
1115 int pty_max_bytes; | 1142 int pty_max_bytes; |
1116 Ibyte eof_char; | 1143 Ibyte eof_char; |
1117 int starting_pos; | 1144 int starting_pos; |
1118 int current_pos; | 1145 int current_pos; |
1119 int end_pos; | 1146 int end_pos; |
1120 int chars_sans_newline; | 1147 int chars_sans_newline; |
1148 int saved_errno; | |
1121 unsigned int closing :1; | 1149 unsigned int closing :1; |
1122 unsigned int allow_quit :1; | 1150 unsigned int allow_quit :1; |
1123 unsigned int blocked_ok :1; | 1151 unsigned int blocked_ok :1; |
1124 unsigned int pty_flushing :1; | 1152 unsigned int pty_flushing :1; |
1125 unsigned int blocking_error_p :1; | 1153 unsigned int blocking_error_p :1; |
1133 OFFSET is the offset from the *current* file pointer that the reading | 1161 OFFSET is the offset from the *current* file pointer that the reading |
1134 should start at. COUNT is the number of bytes to be read (it is | 1162 should start at. COUNT is the number of bytes to be read (it is |
1135 ignored when writing); -1 for unlimited. */ | 1163 ignored when writing); -1 for unlimited. */ |
1136 static Lisp_Object | 1164 static Lisp_Object |
1137 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags, | 1165 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags, |
1138 const char *mode) | 1166 tls_state_t *state, const char *mode) |
1139 { | 1167 { |
1140 Lstream *lstr = Lstream_new (lstream_filedesc, mode); | 1168 Lstream *lstr = Lstream_new (lstream_filedesc, mode); |
1141 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr); | 1169 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr); |
1142 fstr->fd = filedesc; | 1170 fstr->tls_state = state; |
1171 fstr->fd = state ? tls_get_fd (state) : filedesc; | |
1143 fstr->closing = !!(flags & LSTR_CLOSING); | 1172 fstr->closing = !!(flags & LSTR_CLOSING); |
1144 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT); | 1173 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT); |
1145 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK); | 1174 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK); |
1146 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING); | 1175 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING); |
1147 fstr->blocking_error_p = 0; | 1176 fstr->blocking_error_p = 0; |
1148 fstr->chars_sans_newline = 0; | 1177 fstr->chars_sans_newline = 0; |
1149 fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR); | 1178 fstr->saved_errno = 0; |
1179 fstr->starting_pos = lseek (fstr->fd, offset, SEEK_CUR); | |
1150 fstr->current_pos = max (fstr->starting_pos, 0); | 1180 fstr->current_pos = max (fstr->starting_pos, 0); |
1151 if (count < 0) | 1181 if (count < 0) |
1152 fstr->end_pos = -1; | 1182 fstr->end_pos = -1; |
1153 else | 1183 else |
1154 fstr->end_pos = fstr->starting_pos + count; | 1184 fstr->end_pos = fstr->starting_pos + count; |
1174 simply causes the write function to return 0 as the number | 1204 simply causes the write function to return 0 as the number |
1175 of bytes written out. | 1205 of bytes written out. |
1176 */ | 1206 */ |
1177 | 1207 |
1178 Lisp_Object | 1208 Lisp_Object |
1179 make_filedesc_input_stream (int filedesc, int offset, int count, int flags) | 1209 make_filedesc_input_stream (int filedesc, int offset, int count, int flags, |
1180 { | 1210 tls_state_t *state) |
1181 return make_filedesc_stream_1 (filedesc, offset, count, flags, "r"); | 1211 { |
1212 return make_filedesc_stream_1 (filedesc, offset, count, flags, state, "r"); | |
1182 } | 1213 } |
1183 | 1214 |
1184 Lisp_Object | 1215 Lisp_Object |
1185 make_filedesc_output_stream (int filedesc, int offset, int count, int flags) | 1216 make_filedesc_output_stream (int filedesc, int offset, int count, int flags, |
1186 { | 1217 tls_state_t *state) |
1187 return make_filedesc_stream_1 (filedesc, offset, count, flags, "w"); | 1218 { |
1219 return make_filedesc_stream_1 (filedesc, offset, count, flags, state, "w"); | |
1188 } | 1220 } |
1189 | 1221 |
1190 static Bytecount | 1222 static Bytecount |
1191 filedesc_reader (Lstream *stream, unsigned char *data, Bytecount size) | 1223 filedesc_reader (Lstream *stream, unsigned char *data, Bytecount size) |
1192 { | 1224 { |
1193 Bytecount nread; | 1225 Bytecount nread; |
1194 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); | 1226 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); |
1227 str->saved_errno = 0; | |
1195 if (str->end_pos >= 0) | 1228 if (str->end_pos >= 0) |
1196 size = min (size, (Bytecount) (str->end_pos - str->current_pos)); | 1229 size = min (size, (Bytecount) (str->end_pos - str->current_pos)); |
1197 nread = str->allow_quit ? | 1230 nread = str->tls_state |
1198 read_allowing_quit (str->fd, data, size) : | 1231 ? tls_read (str->tls_state, data, size, str->allow_quit) |
1199 retry_read (str->fd, data, size); | 1232 : (str->allow_quit ? |
1233 read_allowing_quit (str->fd, data, size) : | |
1234 retry_read (str->fd, data, size)); | |
1200 if (nread > 0) | 1235 if (nread > 0) |
1201 str->current_pos += nread; | 1236 str->current_pos += nread; |
1202 if (nread == 0) | 1237 if (nread == 0) |
1203 return 0; /* LSTREAM_EOF; */ | 1238 return 0; /* LSTREAM_EOF; */ |
1204 if (nread < 0) | 1239 if (nread < 0) |
1205 return LSTREAM_ERROR; | 1240 { |
1241 str->saved_errno = errno; | |
1242 return LSTREAM_ERROR; | |
1243 } | |
1206 return nread; | 1244 return nread; |
1207 } | 1245 } |
1208 | 1246 |
1209 static int | 1247 static int |
1210 errno_would_block_p (int val) | 1248 errno_would_block_p (int val) |
1225 Bytecount size) | 1263 Bytecount size) |
1226 { | 1264 { |
1227 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); | 1265 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); |
1228 Bytecount retval; | 1266 Bytecount retval; |
1229 int need_newline = 0; | 1267 int need_newline = 0; |
1268 | |
1269 str->saved_errno = 0; | |
1230 | 1270 |
1231 /* This function would be simple if it were not for the blasted | 1271 /* This function would be simple if it were not for the blasted |
1232 PTY max-bytes stuff. Why the hell can't they just have written | 1272 PTY max-bytes stuff. Why the hell can't they just have written |
1233 the PTY drivers right so this problem doesn't exist? | 1273 the PTY drivers right so this problem doesn't exist? |
1234 | 1274 |
1252 size = ptr - data; | 1292 size = ptr - data; |
1253 } | 1293 } |
1254 | 1294 |
1255 /**** start of non-PTY-crap ****/ | 1295 /**** start of non-PTY-crap ****/ |
1256 if (size > 0) | 1296 if (size > 0) |
1257 retval = str->allow_quit ? | 1297 retval = str->tls_state |
1258 write_allowing_quit (str->fd, data, size) : | 1298 ? tls_write (str->tls_state, data, size, str->allow_quit) |
1259 retry_write (str->fd, data, size); | 1299 : (str->allow_quit ? |
1300 write_allowing_quit (str->fd, data, size) : | |
1301 retry_write (str->fd, data, size)); | |
1260 else | 1302 else |
1261 retval = 0; | 1303 retval = 0; |
1262 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok) | 1304 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok) |
1263 { | 1305 { |
1264 str->blocking_error_p = 1; | 1306 str->blocking_error_p = 1; |
1265 return 0; | 1307 return 0; |
1266 } | 1308 } |
1267 str->blocking_error_p = 0; | 1309 str->blocking_error_p = 0; |
1268 if (retval < 0) | 1310 if (retval < 0) |
1269 return LSTREAM_ERROR; | 1311 { |
1312 str->saved_errno = errno; | |
1313 return LSTREAM_ERROR; | |
1314 } | |
1270 /**** end non-PTY-crap ****/ | 1315 /**** end non-PTY-crap ****/ |
1271 | 1316 |
1272 if (str->pty_flushing) | 1317 if (str->pty_flushing) |
1273 { | 1318 { |
1274 str->chars_sans_newline += retval; | 1319 str->chars_sans_newline += retval; |
1296 { | 1341 { |
1297 str->blocking_error_p = 1; | 1342 str->blocking_error_p = 1; |
1298 return 0; | 1343 return 0; |
1299 } | 1344 } |
1300 else | 1345 else |
1301 return LSTREAM_ERROR; | 1346 { |
1347 str->saved_errno = errno; | |
1348 return LSTREAM_ERROR; | |
1349 } | |
1302 } | 1350 } |
1303 else | 1351 else |
1304 return retval; | 1352 return retval; |
1305 } | 1353 } |
1306 } | 1354 } |
1332 { | 1380 { |
1333 str->blocking_error_p = 1; | 1381 str->blocking_error_p = 1; |
1334 return 0; | 1382 return 0; |
1335 } | 1383 } |
1336 else | 1384 else |
1337 return LSTREAM_ERROR; | 1385 { |
1386 str->saved_errno = errno; | |
1387 return LSTREAM_ERROR; | |
1388 } | |
1338 } | 1389 } |
1339 else | 1390 else |
1340 return retval; | 1391 return retval; |
1341 } | 1392 } |
1342 } | 1393 } |
1343 | 1394 |
1344 return retval; | 1395 return retval; |
1396 } | |
1397 | |
1398 static int | |
1399 filedesc_error (Lstream *stream) | |
1400 { | |
1401 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); | |
1402 return str->saved_errno; | |
1345 } | 1403 } |
1346 | 1404 |
1347 static int | 1405 static int |
1348 filedesc_rewinder (Lstream *stream) | 1406 filedesc_rewinder (Lstream *stream) |
1349 { | 1407 { |
1377 | 1435 |
1378 static int | 1436 static int |
1379 filedesc_closer (Lstream *stream) | 1437 filedesc_closer (Lstream *stream) |
1380 { | 1438 { |
1381 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); | 1439 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); |
1382 if (str->closing) | 1440 if (str->tls_state) |
1441 return tls_close (str->tls_state); | |
1442 else if (str->closing) | |
1383 return retry_close (str->fd); | 1443 return retry_close (str->fd); |
1384 else | 1444 else |
1385 return 0; | 1445 return 0; |
1386 } | 1446 } |
1387 | 1447 |
1405 int | 1465 int |
1406 filedesc_stream_fd (Lstream *stream) | 1466 filedesc_stream_fd (Lstream *stream) |
1407 { | 1467 { |
1408 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); | 1468 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); |
1409 return str->fd; | 1469 return str->fd; |
1470 } | |
1471 | |
1472 static int | |
1473 filedesc_tls_p (Lstream *stream) | |
1474 { | |
1475 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); | |
1476 return str->tls_state != NULL; | |
1477 } | |
1478 | |
1479 static int | |
1480 filedesc_tls_negotiater (Lstream *instream, Lstream *outstream, | |
1481 const Extbyte *host, Lisp_Object keylist) | |
1482 { | |
1483 struct filedesc_stream *in_str, *out_str; | |
1484 | |
1485 if (!LSTREAM_TYPE_P (outstream, filedesc)) | |
1486 invalid_argument ("STARTTLS applies to file descriptor streams only", | |
1487 wrap_lstream (outstream)); | |
1488 | |
1489 in_str = FILEDESC_STREAM_DATA (instream); | |
1490 out_str = FILEDESC_STREAM_DATA (outstream); | |
1491 in_str->tls_state = out_str->tls_state = | |
1492 tls_negotiate (out_str->fd, host, keylist); | |
1493 if (out_str->tls_state != NULL) | |
1494 in_str->fd = out_str->fd = tls_get_fd (out_str->tls_state); | |
1495 return out_str->tls_state != NULL; | |
1410 } | 1496 } |
1411 | 1497 |
1412 /*********** read from a Lisp string ***********/ | 1498 /*********** read from a Lisp string ***********/ |
1413 | 1499 |
1414 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string) | 1500 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string) |
1924 LSTREAM_HAS_METHOD (stdio, flusher); | 2010 LSTREAM_HAS_METHOD (stdio, flusher); |
1925 LSTREAM_HAS_METHOD (stdio, closer); | 2011 LSTREAM_HAS_METHOD (stdio, closer); |
1926 | 2012 |
1927 LSTREAM_HAS_METHOD (filedesc, reader); | 2013 LSTREAM_HAS_METHOD (filedesc, reader); |
1928 LSTREAM_HAS_METHOD (filedesc, writer); | 2014 LSTREAM_HAS_METHOD (filedesc, writer); |
2015 LSTREAM_HAS_METHOD (filedesc, error); | |
1929 LSTREAM_HAS_METHOD (filedesc, was_blocked_p); | 2016 LSTREAM_HAS_METHOD (filedesc, was_blocked_p); |
1930 LSTREAM_HAS_METHOD (filedesc, rewinder); | 2017 LSTREAM_HAS_METHOD (filedesc, rewinder); |
1931 LSTREAM_HAS_METHOD (filedesc, seekable_p); | 2018 LSTREAM_HAS_METHOD (filedesc, seekable_p); |
1932 LSTREAM_HAS_METHOD (filedesc, closer); | 2019 LSTREAM_HAS_METHOD (filedesc, closer); |
2020 LSTREAM_HAS_METHOD (filedesc, tls_p); | |
2021 LSTREAM_HAS_METHOD (filedesc, tls_negotiater); | |
1933 | 2022 |
1934 LSTREAM_HAS_METHOD (lisp_string, reader); | 2023 LSTREAM_HAS_METHOD (lisp_string, reader); |
1935 LSTREAM_HAS_METHOD (lisp_string, rewinder); | 2024 LSTREAM_HAS_METHOD (lisp_string, rewinder); |
1936 LSTREAM_HAS_METHOD (lisp_string, marker); | 2025 LSTREAM_HAS_METHOD (lisp_string, marker); |
1937 | 2026 |