00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "mit-copyright.h"
00010
00011
00012
00013
00014
00015
00016
00017 #include "main.h"
00018 #include "new_string.h"
00019 #include "port_dictionary.h"
00020 #include "port.h"
00021 #include "notice.h"
00022 #include "variables.h"
00023
00024
00025
00026
00027
00028
00029
00030 static string
00031 port_get(p)
00032 port *p;
00033 {
00034 char *(*get_proc) ();
00035 char *error = NULL;
00036 char *result;
00037
00038 if (p->status & INPUT_CLOSED) {
00039 var_set_variable("error",
00040 "Attempt to read from a port whose input has been closed");
00041 return (string_Copy(""));
00042 }
00043
00044 get_proc = p->get;
00045 if (!get_proc) {
00046 var_set_variable("error",
00047 "Attempt to read from a port which does not support reading");
00048 return (string_Copy(""));
00049 }
00050
00051 result = get_proc(p, &error);
00052 if (!result) {
00053 var_set_variable("error", error);
00054 return (string_Copy(""));
00055 }
00056 else
00057 return (result);
00058 }
00059
00060 static void
00061 port_put(p, data, length)
00062 port *p;
00063 char *data;
00064 int length;
00065 {
00066 char *(*put_proc) ();
00067 char *error;
00068
00069 if (p->status & OUTPUT_CLOSED) {
00070 var_set_variable("error",
00071 "Attempt to write to a port whose output has been closed");
00072 return;
00073 }
00074
00075 put_proc = p->put;
00076 if (!put_proc) {
00077 var_set_variable("error",
00078 "Attempt to write to a port which does not support writing");
00079 return;
00080 }
00081
00082 error = put_proc(p, data, length);
00083 if (error)
00084 var_set_variable("error", error);
00085 }
00086
00087 static void
00088 port_close_input(p)
00089 port *p;
00090 {
00091 char *(*close_input_proc) ();
00092 char *error;
00093
00094 if (p->status & INPUT_CLOSED)
00095 return;
00096 p->status |= INPUT_CLOSED;
00097
00098 close_input_proc = p->close_input;
00099 if (!close_input_proc)
00100 return;
00101
00102 if ((error = close_input_proc(p)))
00103 var_set_variable("error", error);
00104 }
00105
00106 static void
00107 port_close_output(p)
00108 port *p;
00109 {
00110 char *(*close_output_proc) ();
00111 char *error;
00112
00113 if (p->status & OUTPUT_CLOSED)
00114 return;
00115 p->status |= OUTPUT_CLOSED;
00116
00117 close_output_proc = p->close_output;
00118 if (!close_output_proc)
00119 return;
00120
00121 if ((error = close_output_proc(p)))
00122 var_set_variable("error", error);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 static port_dictionary port_dict = NULL;
00136
00137
00138
00139
00140
00141
00142
00143
00144 static void
00145 close_port_from_binding(b)
00146 port_dictionary_binding *b;
00147 {
00148 port_close_input(&(b->value));
00149 port_close_output(&(b->value));
00150 }
00151
00152 void
00153 init_ports()
00154 {
00155 if (port_dict) {
00156 port_dictionary_Enumerate(port_dict, close_port_from_binding);
00157 port_dictionary_Destroy(port_dict);
00158 }
00159
00160 port_dict = port_dictionary_Create(31);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 static port *
00177 create_named_port(name)
00178 string name;
00179 {
00180 int already_exists;
00181 port_dictionary_binding *binding;
00182
00183 binding = port_dictionary_Define(port_dict, name, &already_exists);
00184 if (already_exists) {
00185 port_close_input(&(binding->value));
00186 port_close_output(&(binding->value));
00187 }
00188
00189 return (&(binding->value));
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 static port *
00202 get_named_port(name)
00203 string name;
00204 {
00205 port_dictionary_binding *binding;
00206
00207 binding = port_dictionary_Lookup(port_dict, name);
00208 if (!binding)
00209 return (NULL);
00210
00211 return (&(binding->value));
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 string
00233 read_from_port(name)
00234 string name;
00235 {
00236 port *p;
00237
00238 if (!(p = get_named_port(name))) {
00239 var_set_variable("error", "No such port");
00240 return (string_Copy(""));
00241 }
00242
00243 return (port_get(p));
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 void
00257 write_on_port(name, text, length)
00258 string name;
00259 char *text;
00260 int length;
00261 {
00262 port *p;
00263
00264 if (!(p = get_named_port(name))) {
00265 var_set_variable("error", "No such port");
00266 return;
00267 }
00268
00269 port_put(p, text, length);
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 void
00285 close_port_input(name)
00286 string name;
00287 {
00288 port_dictionary_binding *binding;
00289
00290 binding = port_dictionary_Lookup(port_dict, name);
00291 if (!binding)
00292 return;
00293
00294 port_close_input(&(binding->value));
00295 if (binding->value.status == PORT_CLOSED)
00296 port_dictionary_Delete(port_dict, binding);
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 void
00312 close_port_output(name)
00313 string name;
00314 {
00315 port_dictionary_binding *binding;
00316
00317 binding = port_dictionary_Lookup(port_dict, name);
00318 if (!binding)
00319 return;
00320
00321 port_close_output(&(binding->value));
00322 if (binding->value.status == PORT_CLOSED)
00323 port_dictionary_Delete(port_dict, binding);
00324 }
00325
00326
00327
00328
00329
00330
00331
00332 static string
00333 get_file(p, error_p)
00334 port *p;
00335 char **error_p;
00336 {
00337 char buffer[10000];
00338
00339 if (!p->data.file.input_connector) {
00340 *error_p = "Attempt to read past end of file";
00341 return (NULL);
00342 }
00343
00344 buffer[0] = 0;
00345 errno = 0;
00346 if (!fgets(buffer, 9999, p->data.file.input_connector)) {
00347 if (errno)
00348 *error_p = strerror(errno);
00349 else
00350 *error_p = "Attempt to read past end of file";
00351
00352 return (NULL);
00353 }
00354
00355 buffer[9999] = 0;
00356 return (string_Copy(buffer));
00357 }
00358
00359 static char *
00360 put_file(p, text, length)
00361 port *p;
00362 string text;
00363 int length;
00364 {
00365 if (!p->data.file.output_connector)
00366 return (NULL);
00367
00368 errno = 0;
00369 fwrite(text, 1, length, p->data.file.output_connector);
00370 fflush(p->data.file.output_connector);
00371
00372 if (errno)
00373 return (strerror(errno));
00374
00375 return (NULL);
00376 }
00377
00378 static char *
00379 close_file_input(p)
00380 port *p;
00381 {
00382 errno = 0;
00383 if (p->data.file.input_connector) {
00384 fclose(p->data.file.input_connector);
00385 p->data.file.input_connector = 0;
00386 }
00387
00388 if (errno)
00389 return (strerror(errno));
00390
00391 return (NULL);
00392 }
00393
00394 static char *
00395 close_file_output(p)
00396 port *p;
00397 {
00398 errno = 0;
00399 if (p->data.file.output_connector) {
00400 fclose(p->data.file.output_connector);
00401 p->data.file.output_connector = 0;
00402 }
00403
00404 if (errno)
00405 return (strerror(errno));
00406
00407 return (NULL);
00408 }
00409
00410 void
00411 create_port_from_files(name, input, output)
00412 string name;
00413 FILE *input;
00414 FILE *output;
00415 {
00416 port *p = create_named_port(name);
00417
00418 #if !defined(__HIGHC__)
00419 p->get = input ? get_file : NULL;
00420 p->put = output ? put_file : NULL;
00421 #else
00422
00423 if (input)
00424 p->get = get_file;
00425 else
00426 p->get = NULL;
00427 if (output)
00428 p->put = put_file;
00429 else
00430 p->put = NULL;
00431 #endif
00432 p->close_input = close_file_input;
00433 p->close_output = close_file_output;
00434 p->status = 0;
00435 p->data.file.input_connector = input;
00436 p->data.file.output_connector = output;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445 void
00446 create_subprocess_port(name, argv)
00447 string name;
00448 char **argv;
00449 {
00450 int pid;
00451 int to_child_descriptors[2];
00452 int to_parent_descriptors[2];
00453 FILE *in = 0;
00454 FILE *out = 0;
00455
00456
00457 if (pipe(to_child_descriptors) != 0 || pipe(to_parent_descriptors) != 0)
00458 return;
00459
00460 pid = fork();
00461 if (pid == -1) {
00462 fprintf(stderr, "jwgc: error while attempting to fork: ");
00463 perror("");
00464 return;
00465 }
00466 else if (pid == 0) {
00467 close(0);
00468 close(1);
00469 dup2(to_child_descriptors[0], 0);
00470 dup2(to_parent_descriptors[1], 1);
00471 close(to_child_descriptors[1]);
00472 close(to_parent_descriptors[0]);
00473
00474 execvp(argv[0], argv);
00475 fprintf(stderr, "jwgc: unable to exec %s: ", argv[0]);
00476 perror("");
00477 _exit(errno);
00478 }
00479
00480 fcntl(to_parent_descriptors[0], F_SETFD, 1);
00481 fcntl(to_child_descriptors[1], F_SETFD, 1);
00482 in = fdopen(to_parent_descriptors[0], "r");
00483 out = fdopen(to_child_descriptors[1], "w");
00484 close(to_child_descriptors[0]);
00485 close(to_parent_descriptors[1]);
00486
00487 create_port_from_files(name, in, out);
00488 }
00489
00490 void
00491 create_file_append_port(name, filename)
00492 string name;
00493 string filename;
00494 {
00495 FILE *out;
00496 int oumask;
00497
00498 errno = 0;
00499
00500 oumask = umask(077);
00501 out = fopen(filename, "a");
00502 (void) umask(oumask);
00503 if (out == NULL) {
00504 var_set_variable("error", strerror(errno));
00505 return;
00506 }
00507
00508 create_port_from_files(name, 0, out);
00509 }
00510
00511 void
00512 create_file_input_port(name, filename)
00513 string name;
00514 string filename;
00515 {
00516 FILE *in;
00517
00518 errno = 0;
00519 in = fopen(filename, "r");
00520 if (in == NULL) {
00521 var_set_variable("error", strerror(errno));
00522 return;
00523 }
00524
00525 create_port_from_files(name, in, 0);
00526 }
00527
00528 void
00529 create_file_output_port(name, filename)
00530 string name;
00531 string filename;
00532 {
00533 FILE *out;
00534 int oumask;
00535
00536 errno = 0;
00537
00538 oumask = umask(077);
00539 out = fopen(filename, "w");
00540 (void) umask(oumask);
00541 if (out == NULL) {
00542 var_set_variable("error", strerror(errno));
00543 return;
00544 }
00545
00546 create_port_from_files(name, 0, out);
00547 }
00548
00549
00550
00551
00552
00553
00554
00555 static string
00556 get_filter(p, error_p)
00557 port *p;
00558 char **error_p;
00559 {
00560 string result;
00561
00562 if (string_stack_empty(p->data.filter.waiting_packets)) {
00563 *error_p = "Attempt to read from port when no data available";
00564 return (NULL);
00565 }
00566
00567 result = string_stack_top(p->data.filter.waiting_packets);
00568 string_stack_pop(p->data.filter.waiting_packets);
00569 return (result);
00570 }
00571
00572 static char *
00573 put_filter(p, text, length)
00574 port *p;
00575 string text;
00576 int length;
00577 {
00578 string input;
00579 string output;
00580
00581 if (p->status & INPUT_CLOSED)
00582 return (NULL);
00583
00584 input = convert_nulls_to_newlines(text, length);
00585 output = (*(p->data.filter.filter)) (input);
00586 free(input);
00587 string_stack_push(p->data.filter.waiting_packets, output);
00588 return (NULL);
00589 }
00590
00591 static char *
00592 close_filter_input(p)
00593 port *p;
00594 {
00595 while (!string_stack_empty(p->data.filter.waiting_packets))
00596 string_stack_pop(p->data.filter.waiting_packets);
00597
00598 return (NULL);
00599 }
00600
00601
00602 static char *
00603 close_filter_output(p)
00604 port *p;
00605 {
00606 return (NULL);
00607 }
00608
00609 void
00610 create_port_from_filter(name, filter)
00611 string name;
00612 string(*filter) ();
00613 {
00614 port *p = create_named_port(name);
00615
00616 p->get = get_filter;
00617 p->put = put_filter;
00618 p->close_input = close_filter_input;
00619 p->close_output = close_filter_output;
00620 p->status = 0;
00621 p->data.filter.waiting_packets = string_stack_create();
00622 p->data.filter.filter = filter;
00623 }
00624
00625
00626
00627
00628
00629
00630
00631 static char *
00632 put_output(p, text, length)
00633 port *p;
00634 string text;
00635 int length;
00636 {
00637 string input;
00638 char *error;
00639
00640 input = convert_nulls_to_newlines(text, length);
00641 error = p->data.output.output(input);
00642 free(input);
00643 return (error);
00644 }
00645
00646
00647 static char *
00648 close_output(p)
00649 port *p;
00650 {
00651 return (NULL);
00652 }
00653
00654 void
00655 create_port_from_output_proc(name, output)
00656 string name;
00657 char *(*output) ();
00658 {
00659 #ifdef SABER
00660 port *p;
00661 #else
00662 port *p = create_named_port(name);
00663 #endif
00664
00665 #ifdef SABER
00666 p = create_named_port(name);
00667 #endif
00668
00669 p->get = NULL;
00670 p->put = put_output;
00671 p->close_input = close_output;
00672 p->close_output = close_output;
00673 p->status = 0;
00674 p->data.output.output = output;
00675 }