32 * Memory allocation
33 * String handling
34 * Property handling
35 * Error message handling
36 * Make internal state dumping
37 * main routine support
38 */
39
40 /*
41 * Included files
42 */
43 #include <bsd/bsd.h> /* bsd_signal() */
44 #include <mksh/i18n.h> /* get_char_semantics_value() */
45 #include <mksh/misc.h>
46 #include <mksdmsi18n/mksdmsi18n.h>
47 #include <stdarg.h> /* va_list, va_start(), va_end() */
48 #include <stdlib.h> /* mbstowcs() */
49 #include <sys/signal.h> /* SIG_DFL */
50 #include <sys/wait.h> /* wait() */
51
52 #ifdef SUN5_0
53 #include <string.h> /* strerror() */
54 #endif
55
56 #if defined (HP_UX) || defined (linux)
57 #include <unistd.h>
58 #endif
59
60 /*
61 * Defined macros
62 */
63
64 /*
65 * typedefs & structs
66 */
67
68 /*
69 * Static variables
70 */
71 #ifdef SUN5_0
72 extern "C" {
73 void (*sigivalue)(int) = SIG_DFL;
74 void (*sigqvalue)(int) = SIG_DFL;
75 void (*sigtvalue)(int) = SIG_DFL;
76 void (*sighvalue)(int) = SIG_DFL;
77 }
78 #else
79 static void (*sigivalue)(int) = (void (*) (int)) SIG_DFL;
80 static void (*sigqvalue)(int) = (void (*) (int)) SIG_DFL;
81 static void (*sigtvalue)(int) = (void (*) (int)) SIG_DFL;
82 static void (*sighvalue)(int) = (void (*) (int)) SIG_DFL;
83 #endif
84
85 long getname_bytes_count = 0;
86 long getname_names_count = 0;
87 long getname_struct_count = 0;
88
89 long freename_bytes_count = 0;
90 long freename_names_count = 0;
91 long freename_struct_count = 0;
92
93 long expandstring_count = 0;
94 long getwstring_count = 0;
95
96 /*
97 * File table of contents
98 */
99 static void expand_string(register String string, register int length);
100
101 #define FATAL_ERROR_MSG_SIZE 200
102
103 /*
105 *
106 * malloc() version that checks the returned value.
107 *
108 * Return value:
109 * The memory chunk we allocated
110 *
111 * Parameters:
112 * size The size of the chunk we need
113 *
114 * Global variables used:
115 */
116 char *
117 getmem(register int size)
118 {
119 register char *result = (char *) malloc((unsigned) size);
120 if (result == NULL) {
121 char buf[FATAL_ERROR_MSG_SIZE];
122 sprintf(buf, NOCATGETS("*** Error: malloc(%d) failed: %s\n"), size, strerror(errno));
123 strcat(buf, catgets(libmksdmsi18n_catd, 1, 126, "mksh: Fatal error: Out of memory\n"));
124 fputs(buf, stderr);
125 #ifdef SUN5_0
126 exit_status = 1;
127 #endif
128 exit(1);
129 }
130 return result;
131 }
132
133 /*
134 * retmem(p)
135 *
136 * Cover funtion for free() to make it possible to insert advises.
137 *
138 * Parameters:
139 * p The memory block to free
140 *
141 * Global variables used:
142 */
143 void
144 retmem(wchar_t *p)
145 {
146 (void) free((char *) p);
147 }
267 }
268
269 /*
270 * enable_interrupt(handler)
271 *
272 * This routine sets a new interrupt handler for the signals make
273 * wants to deal with.
274 *
275 * Parameters:
276 * handler The function installed as interrupt handler
277 *
278 * Static variables used:
279 * sigivalue The original signal handler
280 * sigqvalue The original signal handler
281 * sigtvalue The original signal handler
282 * sighvalue The original signal handler
283 */
284 void
285 enable_interrupt(register void (*handler) (int))
286 {
287 #ifdef SUN5_0
288 if (sigivalue != SIG_IGN) {
289 #else
290 if (sigivalue != (void (*) (int)) SIG_IGN) {
291 #endif
292 (void) bsd_signal(SIGINT, (SIG_PF) handler);
293 }
294 #ifdef SUN5_0
295 if (sigqvalue != SIG_IGN) {
296 #else
297 if (sigqvalue != (void (*) (int)) SIG_IGN) {
298 #endif
299 (void) bsd_signal(SIGQUIT, (SIG_PF) handler);
300 }
301 #ifdef SUN5_0
302 if (sigtvalue != SIG_IGN) {
303 #else
304 if (sigtvalue != (void (*) (int)) SIG_IGN) {
305 #endif
306 (void) bsd_signal(SIGTERM, (SIG_PF) handler);
307 }
308 #ifdef SUN5_0
309 if (sighvalue != SIG_IGN) {
310 #else
311 if (sighvalue != (void (*) (int)) SIG_IGN) {
312 #endif
313 (void) bsd_signal(SIGHUP, (SIG_PF) handler);
314 }
315 }
316
317 /*
318 * setup_char_semantics()
319 *
320 * Load the vector char_semantics[] with lexical markers
321 *
322 * Parameters:
323 *
324 * Global variables used:
325 * char_semantics The vector of character semantics that we set
326 */
327 void
328 setup_char_semantics(void)
329 {
330 const char *s;
331 wchar_t wc_buffer[1];
332 int entry;
377 errmsg(int errnum)
378 {
379 #ifdef linux
380 return strerror(errnum);
381 #else // linux
382
383 extern int sys_nerr;
384 #ifdef SUN4_x
385 extern char *sys_errlist[];
386 #endif
387 char *errbuf;
388
389 if ((errnum < 0) || (errnum > sys_nerr)) {
390 errbuf = getmem(6+1+11+1);
391 (void) sprintf(errbuf, catgets(libmksdmsi18n_catd, 1, 127, "Error %d"), errnum);
392 return errbuf;
393 } else {
394 #ifdef SUN4_x
395 return(sys_errlist[errnum]);
396 #endif
397 #ifdef SUN5_0
398 return strerror(errnum);
399 #endif
400
401 }
402 #endif // linux
403 }
404
405 static char static_buf[MAXPATHLEN*3];
406
407 /*
408 * fatal_mksh(format, args...)
409 *
410 * Print a message and die
411 *
412 * Parameters:
413 * format printf type format string
414 * args Arguments to match the format
415 */
416 /*VARARGS*/
417 void
418 fatal_mksh(const char *message, ...)
419 {
438 buf = getmem(buf_len);
439 (void) strcpy(buf, mksh_fat_err);
440 va_start(args, message);
441 (void) vsprintf(buf + mksh_fat_err_len, message, args);
442 va_end(args);
443 }
444 (void) strcat(buf, "\n");
445 /*
446 if (report_pwd) {
447 */
448 if (1) {
449 (void) strcat(buf, cur_wrk_dir);
450 (void) strcat(buf, get_current_path_mksh());
451 (void) strcat(buf, "\n");
452 }
453 (void) fputs(buf, stderr);
454 (void) fflush(stderr);
455 if (buf != static_buf) {
456 retmem_mb(buf);
457 }
458 #ifdef SUN5_0
459 exit_status = 1;
460 #endif
461 exit(1);
462 }
463
464 /*
465 * fatal_reader_mksh(format, args...)
466 *
467 * Parameters:
468 * format printf style format string
469 * args arguments to match the format
470 */
471 /*VARARGS*/
472 void
473 fatal_reader_mksh(const char * pattern, ...)
474 {
475 va_list args;
476 char message[1000];
477
478 va_start(args, pattern);
479 /*
480 if (file_being_read != NULL) {
502 va_end(args);
503
504 /*
505 if (temp_file_name != NULL) {
506 (void) fprintf(stderr,
507 catgets(libmksdmsi18n_catd, 1, 132, "mksh: Temp-file %s not removed\n"),
508 temp_file_name->string_mb);
509 temp_file_name = NULL;
510 }
511 */
512
513 /*
514 if (report_pwd) {
515 */
516 if (1) {
517 (void) fprintf(stderr,
518 catgets(libmksdmsi18n_catd, 1, 133, "Current working directory %s\n"),
519 get_current_path_mksh());
520 }
521 (void) fflush(stderr);
522 #ifdef SUN5_0
523 exit_status = 1;
524 #endif
525 exit(1);
526 }
527
528 /*
529 * warning_mksh(format, args...)
530 *
531 * Print a message and continue.
532 *
533 * Parameters:
534 * format printf type format string
535 * args Arguments to match the format
536 */
537 /*VARARGS*/
538 void
539 warning_mksh(char * message, ...)
540 {
541 va_list args;
542
543 va_start(args, message);
544 (void) fflush(stdout);
556 }
557 (void) fflush(stderr);
558 }
559
560 /*
561 * get_current_path_mksh()
562 *
563 * Stuff current_path with the current path if it isnt there already.
564 *
565 * Parameters:
566 *
567 * Global variables used:
568 */
569 char *
570 get_current_path_mksh(void)
571 {
572 char pwd[(MAXPATHLEN * MB_LEN_MAX)];
573 static char *current_path;
574
575 if (current_path == NULL) {
576 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
577 getcwd(pwd, sizeof(pwd));
578 #else
579 (void) getwd(pwd);
580 #endif
581 if (pwd[0] == (int) nul_char) {
582 pwd[0] = (int) slash_char;
583 pwd[1] = (int) nul_char;
584 }
585 current_path = strdup(pwd);
586 }
587 return current_path;
588 }
589
590 /*
591 * append_prop(target, type)
592 *
593 * Create a new property and append it to the property list of a Name.
594 *
595 * Return value:
596 * A new property block for the target
597 *
598 * Parameters:
599 * target The target that wants a new property
600 * type The type of property being requested
849 expand_string(to, to->buffer.end - to->buffer.start + 32);
850 }
851 *(to->text.p)++ = from;
852 *(to->text.p) = (int) nul_char;
853 }
854
855 /*
856 * handle_interrupt_mksh()
857 *
858 * This is where C-C traps are caught.
859 */
860 void
861 handle_interrupt_mksh(int)
862 {
863 (void) fflush(stdout);
864 /* Make sure the processes running under us terminate first. */
865 if (childPid > 0) {
866 kill(childPid, SIGTERM);
867 childPid = -1;
868 }
869 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
870 while (wait((int *) NULL) != -1);
871 #if defined(SUN5_0)
872 exit_status = 2;
873 #endif
874 #else
875 while (wait((union wait *) NULL) != -1);
876 #endif
877 exit(2);
878 }
879
880 /*
881 * setup_interrupt()
882 *
883 * This routine saves the original interrupt handler pointers
884 *
885 * Parameters:
886 *
887 * Static variables used:
888 * sigivalue The original signal handler
889 * sigqvalue The original signal handler
890 * sigtvalue The original signal handler
891 * sighvalue The original signal handler
892 */
893 void
894 setup_interrupt(register void (*handler) (int))
895 {
896 #ifdef SUN5_0
897 sigivalue = bsd_signal(SIGINT, SIG_IGN);
898 sigqvalue = bsd_signal(SIGQUIT, SIG_IGN);
899 sigtvalue = bsd_signal(SIGTERM, SIG_IGN);
900 sighvalue = bsd_signal(SIGHUP, SIG_IGN);
901 #else
902 sigivalue = (void (*) (int)) bsd_signal(SIGINT, SIG_IGN);
903 sigqvalue = (void (*) (int)) bsd_signal(SIGQUIT, SIG_IGN);
904 sigtvalue = (void (*) (int)) bsd_signal(SIGTERM, SIG_IGN);
905 sighvalue = (void (*) (int)) bsd_signal(SIGHUP, SIG_IGN);
906 #endif
907 enable_interrupt(handler);
908 }
909
910
911 void
912 mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n)
913 {
914 if(mbstowcs(pwcs, s, n) == -1) {
915 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 143, "The string `%s' is not valid in current locale"), s);
916 }
917 }
918
919
920
921 Wstring::Wstring()
922 {
923 INIT_STRING_FROM_STACK(string, string_buf);
924 }
925
926 Wstring::Wstring(struct _Name * name)
|
32 * Memory allocation
33 * String handling
34 * Property handling
35 * Error message handling
36 * Make internal state dumping
37 * main routine support
38 */
39
40 /*
41 * Included files
42 */
43 #include <bsd/bsd.h> /* bsd_signal() */
44 #include <mksh/i18n.h> /* get_char_semantics_value() */
45 #include <mksh/misc.h>
46 #include <mksdmsi18n/mksdmsi18n.h>
47 #include <stdarg.h> /* va_list, va_start(), va_end() */
48 #include <stdlib.h> /* mbstowcs() */
49 #include <sys/signal.h> /* SIG_DFL */
50 #include <sys/wait.h> /* wait() */
51
52 #include <string.h> /* strerror() */
53
54 #if defined (HP_UX) || defined (linux)
55 #include <unistd.h>
56 #endif
57
58 /*
59 * Defined macros
60 */
61
62 /*
63 * typedefs & structs
64 */
65
66 /*
67 * Static variables
68 */
69 extern "C" {
70 void (*sigivalue)(int) = SIG_DFL;
71 void (*sigqvalue)(int) = SIG_DFL;
72 void (*sigtvalue)(int) = SIG_DFL;
73 void (*sighvalue)(int) = SIG_DFL;
74 }
75
76 long getname_bytes_count = 0;
77 long getname_names_count = 0;
78 long getname_struct_count = 0;
79
80 long freename_bytes_count = 0;
81 long freename_names_count = 0;
82 long freename_struct_count = 0;
83
84 long expandstring_count = 0;
85 long getwstring_count = 0;
86
87 /*
88 * File table of contents
89 */
90 static void expand_string(register String string, register int length);
91
92 #define FATAL_ERROR_MSG_SIZE 200
93
94 /*
96 *
97 * malloc() version that checks the returned value.
98 *
99 * Return value:
100 * The memory chunk we allocated
101 *
102 * Parameters:
103 * size The size of the chunk we need
104 *
105 * Global variables used:
106 */
107 char *
108 getmem(register int size)
109 {
110 register char *result = (char *) malloc((unsigned) size);
111 if (result == NULL) {
112 char buf[FATAL_ERROR_MSG_SIZE];
113 sprintf(buf, NOCATGETS("*** Error: malloc(%d) failed: %s\n"), size, strerror(errno));
114 strcat(buf, catgets(libmksdmsi18n_catd, 1, 126, "mksh: Fatal error: Out of memory\n"));
115 fputs(buf, stderr);
116 exit_status = 1;
117 exit(1);
118 }
119 return result;
120 }
121
122 /*
123 * retmem(p)
124 *
125 * Cover funtion for free() to make it possible to insert advises.
126 *
127 * Parameters:
128 * p The memory block to free
129 *
130 * Global variables used:
131 */
132 void
133 retmem(wchar_t *p)
134 {
135 (void) free((char *) p);
136 }
256 }
257
258 /*
259 * enable_interrupt(handler)
260 *
261 * This routine sets a new interrupt handler for the signals make
262 * wants to deal with.
263 *
264 * Parameters:
265 * handler The function installed as interrupt handler
266 *
267 * Static variables used:
268 * sigivalue The original signal handler
269 * sigqvalue The original signal handler
270 * sigtvalue The original signal handler
271 * sighvalue The original signal handler
272 */
273 void
274 enable_interrupt(register void (*handler) (int))
275 {
276 if (sigivalue != SIG_IGN) {
277 (void) bsd_signal(SIGINT, (SIG_PF) handler);
278 }
279 if (sigqvalue != SIG_IGN) {
280 (void) bsd_signal(SIGQUIT, (SIG_PF) handler);
281 }
282 if (sigtvalue != SIG_IGN) {
283 (void) bsd_signal(SIGTERM, (SIG_PF) handler);
284 }
285 if (sighvalue != SIG_IGN) {
286 (void) bsd_signal(SIGHUP, (SIG_PF) handler);
287 }
288 }
289
290 /*
291 * setup_char_semantics()
292 *
293 * Load the vector char_semantics[] with lexical markers
294 *
295 * Parameters:
296 *
297 * Global variables used:
298 * char_semantics The vector of character semantics that we set
299 */
300 void
301 setup_char_semantics(void)
302 {
303 const char *s;
304 wchar_t wc_buffer[1];
305 int entry;
350 errmsg(int errnum)
351 {
352 #ifdef linux
353 return strerror(errnum);
354 #else // linux
355
356 extern int sys_nerr;
357 #ifdef SUN4_x
358 extern char *sys_errlist[];
359 #endif
360 char *errbuf;
361
362 if ((errnum < 0) || (errnum > sys_nerr)) {
363 errbuf = getmem(6+1+11+1);
364 (void) sprintf(errbuf, catgets(libmksdmsi18n_catd, 1, 127, "Error %d"), errnum);
365 return errbuf;
366 } else {
367 #ifdef SUN4_x
368 return(sys_errlist[errnum]);
369 #endif
370 return strerror(errnum);
371
372 }
373 #endif // linux
374 }
375
376 static char static_buf[MAXPATHLEN*3];
377
378 /*
379 * fatal_mksh(format, args...)
380 *
381 * Print a message and die
382 *
383 * Parameters:
384 * format printf type format string
385 * args Arguments to match the format
386 */
387 /*VARARGS*/
388 void
389 fatal_mksh(const char *message, ...)
390 {
409 buf = getmem(buf_len);
410 (void) strcpy(buf, mksh_fat_err);
411 va_start(args, message);
412 (void) vsprintf(buf + mksh_fat_err_len, message, args);
413 va_end(args);
414 }
415 (void) strcat(buf, "\n");
416 /*
417 if (report_pwd) {
418 */
419 if (1) {
420 (void) strcat(buf, cur_wrk_dir);
421 (void) strcat(buf, get_current_path_mksh());
422 (void) strcat(buf, "\n");
423 }
424 (void) fputs(buf, stderr);
425 (void) fflush(stderr);
426 if (buf != static_buf) {
427 retmem_mb(buf);
428 }
429 exit_status = 1;
430 exit(1);
431 }
432
433 /*
434 * fatal_reader_mksh(format, args...)
435 *
436 * Parameters:
437 * format printf style format string
438 * args arguments to match the format
439 */
440 /*VARARGS*/
441 void
442 fatal_reader_mksh(const char * pattern, ...)
443 {
444 va_list args;
445 char message[1000];
446
447 va_start(args, pattern);
448 /*
449 if (file_being_read != NULL) {
471 va_end(args);
472
473 /*
474 if (temp_file_name != NULL) {
475 (void) fprintf(stderr,
476 catgets(libmksdmsi18n_catd, 1, 132, "mksh: Temp-file %s not removed\n"),
477 temp_file_name->string_mb);
478 temp_file_name = NULL;
479 }
480 */
481
482 /*
483 if (report_pwd) {
484 */
485 if (1) {
486 (void) fprintf(stderr,
487 catgets(libmksdmsi18n_catd, 1, 133, "Current working directory %s\n"),
488 get_current_path_mksh());
489 }
490 (void) fflush(stderr);
491 exit_status = 1;
492 exit(1);
493 }
494
495 /*
496 * warning_mksh(format, args...)
497 *
498 * Print a message and continue.
499 *
500 * Parameters:
501 * format printf type format string
502 * args Arguments to match the format
503 */
504 /*VARARGS*/
505 void
506 warning_mksh(char * message, ...)
507 {
508 va_list args;
509
510 va_start(args, message);
511 (void) fflush(stdout);
523 }
524 (void) fflush(stderr);
525 }
526
527 /*
528 * get_current_path_mksh()
529 *
530 * Stuff current_path with the current path if it isnt there already.
531 *
532 * Parameters:
533 *
534 * Global variables used:
535 */
536 char *
537 get_current_path_mksh(void)
538 {
539 char pwd[(MAXPATHLEN * MB_LEN_MAX)];
540 static char *current_path;
541
542 if (current_path == NULL) {
543 getcwd(pwd, sizeof(pwd));
544 if (pwd[0] == (int) nul_char) {
545 pwd[0] = (int) slash_char;
546 pwd[1] = (int) nul_char;
547 }
548 current_path = strdup(pwd);
549 }
550 return current_path;
551 }
552
553 /*
554 * append_prop(target, type)
555 *
556 * Create a new property and append it to the property list of a Name.
557 *
558 * Return value:
559 * A new property block for the target
560 *
561 * Parameters:
562 * target The target that wants a new property
563 * type The type of property being requested
812 expand_string(to, to->buffer.end - to->buffer.start + 32);
813 }
814 *(to->text.p)++ = from;
815 *(to->text.p) = (int) nul_char;
816 }
817
818 /*
819 * handle_interrupt_mksh()
820 *
821 * This is where C-C traps are caught.
822 */
823 void
824 handle_interrupt_mksh(int)
825 {
826 (void) fflush(stdout);
827 /* Make sure the processes running under us terminate first. */
828 if (childPid > 0) {
829 kill(childPid, SIGTERM);
830 childPid = -1;
831 }
832 while (wait((int *) NULL) != -1);
833 exit_status = 2;
834 exit(2);
835 }
836
837 /*
838 * setup_interrupt()
839 *
840 * This routine saves the original interrupt handler pointers
841 *
842 * Parameters:
843 *
844 * Static variables used:
845 * sigivalue The original signal handler
846 * sigqvalue The original signal handler
847 * sigtvalue The original signal handler
848 * sighvalue The original signal handler
849 */
850 void
851 setup_interrupt(register void (*handler) (int))
852 {
853 sigivalue = bsd_signal(SIGINT, SIG_IGN);
854 sigqvalue = bsd_signal(SIGQUIT, SIG_IGN);
855 sigtvalue = bsd_signal(SIGTERM, SIG_IGN);
856 sighvalue = bsd_signal(SIGHUP, SIG_IGN);
857 enable_interrupt(handler);
858 }
859
860
861 void
862 mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n)
863 {
864 if(mbstowcs(pwcs, s, n) == -1) {
865 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 143, "The string `%s' is not valid in current locale"), s);
866 }
867 }
868
869
870
871 Wstring::Wstring()
872 {
873 INIT_STRING_FROM_STACK(string, string_buf);
874 }
875
876 Wstring::Wstring(struct _Name * name)
|