26
27 /*
28 * misc.cc
29 *
30 * This file contains various unclassified routines. Some main groups:
31 * getname
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
55 /*
56 * Defined macros
57 */
58
59 /*
60 * typedefs & structs
61 */
62
63 /*
64 * Static variables
65 */
66 extern "C" {
67 void (*sigivalue)(int) = SIG_DFL;
68 void (*sigqvalue)(int) = SIG_DFL;
69 void (*sigtvalue)(int) = SIG_DFL;
70 void (*sighvalue)(int) = SIG_DFL;
71 }
72
90
91 /*
92 * getmem(size)
93 *
94 * malloc() version that checks the returned value.
95 *
96 * Return value:
97 * The memory chunk we allocated
98 *
99 * Parameters:
100 * size The size of the chunk we need
101 *
102 * Global variables used:
103 */
104 char *
105 getmem(register int size)
106 {
107 register char *result = (char *) malloc((unsigned) size);
108 if (result == NULL) {
109 char buf[FATAL_ERROR_MSG_SIZE];
110 sprintf(buf, NOCATGETS("*** Error: malloc(%d) failed: %s\n"), size, strerror(errno));
111 strcat(buf, catgets(libmksdmsi18n_catd, 1, 126, "mksh: Fatal error: Out of memory\n"));
112 fputs(buf, stderr);
113 exit_status = 1;
114 exit(1);
115 }
116 return result;
117 }
118
119 /*
120 * retmem(p)
121 *
122 * Cover funtion for free() to make it possible to insert advises.
123 *
124 * Parameters:
125 * p The memory block to free
126 *
127 * Global variables used:
128 */
129 void
130 retmem(wchar_t *p)
131 {
335 *
336 * Return value:
337 * An error message string
338 *
339 * Parameters:
340 * errnum The number of the error we want to describe
341 *
342 * Global variables used:
343 * sys_errlist A vector of error messages
344 * sys_nerr The size of sys_errlist
345 */
346 char *
347 errmsg(int errnum)
348 {
349
350 extern int sys_nerr;
351 char *errbuf;
352
353 if ((errnum < 0) || (errnum > sys_nerr)) {
354 errbuf = getmem(6+1+11+1);
355 (void) sprintf(errbuf, catgets(libmksdmsi18n_catd, 1, 127, "Error %d"), errnum);
356 return errbuf;
357 } else {
358 return strerror(errnum);
359
360 }
361 }
362
363 static char static_buf[MAXPATHLEN*3];
364
365 /*
366 * fatal_mksh(format, args...)
367 *
368 * Print a message and die
369 *
370 * Parameters:
371 * format printf type format string
372 * args Arguments to match the format
373 */
374 /*VARARGS*/
375 void
376 fatal_mksh(const char *message, ...)
377 {
378 va_list args;
379 char *buf = static_buf;
380 char *mksh_fat_err = catgets(libmksdmsi18n_catd, 1, 128, "mksh: Fatal error: ");
381 char *cur_wrk_dir = catgets(libmksdmsi18n_catd, 1, 129, "Current working directory: ");
382 int mksh_fat_err_len = strlen(mksh_fat_err);
383
384 va_start(args, message);
385 (void) fflush(stdout);
386 (void) strcpy(buf, mksh_fat_err);
387 size_t buf_len = vsnprintf(static_buf + mksh_fat_err_len,
388 sizeof(static_buf) - mksh_fat_err_len,
389 message, args)
390 + mksh_fat_err_len
391 + strlen(cur_wrk_dir)
392 + strlen(get_current_path_mksh())
393 + 3; // "\n\n"
394 va_end(args);
395 if (buf_len >= sizeof(static_buf)) {
396 buf = getmem(buf_len);
397 (void) strcpy(buf, mksh_fat_err);
398 va_start(args, message);
399 (void) vsprintf(buf + mksh_fat_err_len, message, args);
400 va_end(args);
401 }
420 /*
421 * fatal_reader_mksh(format, args...)
422 *
423 * Parameters:
424 * format printf style format string
425 * args arguments to match the format
426 */
427 /*VARARGS*/
428 void
429 fatal_reader_mksh(const char * pattern, ...)
430 {
431 va_list args;
432 char message[1000];
433
434 va_start(args, pattern);
435 /*
436 if (file_being_read != NULL) {
437 WCSTOMBS(mbs_buffer, file_being_read);
438 if (line_number != 0) {
439 (void) sprintf(message,
440 catgets(libmksdmsi18n_catd, 1, 130, "%s, line %d: %s"),
441 mbs_buffer,
442 line_number,
443 pattern);
444 } else {
445 (void) sprintf(message,
446 "%s: %s",
447 mbs_buffer,
448 pattern);
449 }
450 pattern = message;
451 }
452 */
453
454 (void) fflush(stdout);
455 (void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 131, "mksh: Fatal error in reader: "));
456 (void) vfprintf(stderr, pattern, args);
457 (void) fprintf(stderr, "\n");
458 va_end(args);
459
460 /*
461 if (temp_file_name != NULL) {
462 (void) fprintf(stderr,
463 catgets(libmksdmsi18n_catd, 1, 132, "mksh: Temp-file %s not removed\n"),
464 temp_file_name->string_mb);
465 temp_file_name = NULL;
466 }
467 */
468
469 /*
470 if (report_pwd) {
471 */
472 if (1) {
473 (void) fprintf(stderr,
474 catgets(libmksdmsi18n_catd, 1, 133, "Current working directory %s\n"),
475 get_current_path_mksh());
476 }
477 (void) fflush(stderr);
478 exit_status = 1;
479 exit(1);
480 }
481
482 /*
483 * warning_mksh(format, args...)
484 *
485 * Print a message and continue.
486 *
487 * Parameters:
488 * format printf type format string
489 * args Arguments to match the format
490 */
491 /*VARARGS*/
492 void
493 warning_mksh(char * message, ...)
494 {
495 va_list args;
496
497 va_start(args, message);
498 (void) fflush(stdout);
499 (void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 134, "mksh: Warning: "));
500 (void) vfprintf(stderr, message, args);
501 (void) fprintf(stderr, "\n");
502 va_end(args);
503 /*
504 if (report_pwd) {
505 */
506 if (1) {
507 (void) fprintf(stderr,
508 catgets(libmksdmsi18n_catd, 1, 135, "Current working directory %s\n"),
509 get_current_path_mksh());
510 }
511 (void) fflush(stderr);
512 }
513
514 /*
515 * get_current_path_mksh()
516 *
517 * Stuff current_path with the current path if it isnt there already.
518 *
519 * Parameters:
520 *
521 * Global variables used:
522 */
523 char *
524 get_current_path_mksh(void)
525 {
526 char pwd[(MAXPATHLEN * MB_LEN_MAX)];
527 static char *current_path;
528
585 break;
586 case target_prop:
587 size = sizeof (struct Target);
588 break;
589 case time_prop:
590 size = sizeof (struct STime);
591 break;
592 case vpath_alias_prop:
593 size = sizeof (struct Vpath_alias);
594 break;
595 case long_member_name_prop:
596 size = sizeof (struct Long_member_name);
597 break;
598 case macro_append_prop:
599 size = sizeof (struct _Macro_appendix);
600 break;
601 case env_mem_prop:
602 size = sizeof (struct _Env_mem);
603 break;
604 default:
605 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 136, "Internal error. Unknown prop type %d"), type);
606 }
607 for (; prop != NULL; insert = &prop->next, prop = *insert);
608 size += PROPERTY_HEAD_SIZE;
609 *insert = prop = (Property) getmem(size);
610 memset((char *) prop, 0, size);
611 prop->type = type;
612 prop->next = NULL;
613 return prop;
614 }
615
616 /*
617 * maybe_append_prop(target, type)
618 *
619 * Append a property to the Name if none of this type exists
620 * else return the one already there
621 *
622 * Return value:
623 * A property of the requested type for the target
624 *
625 * Parameters:
832 * sigivalue The original signal handler
833 * sigqvalue The original signal handler
834 * sigtvalue The original signal handler
835 * sighvalue The original signal handler
836 */
837 void
838 setup_interrupt(register void (*handler) (int))
839 {
840 sigivalue = bsd_signal(SIGINT, SIG_IGN);
841 sigqvalue = bsd_signal(SIGQUIT, SIG_IGN);
842 sigtvalue = bsd_signal(SIGTERM, SIG_IGN);
843 sighvalue = bsd_signal(SIGHUP, SIG_IGN);
844 enable_interrupt(handler);
845 }
846
847
848 void
849 mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n)
850 {
851 if(mbstowcs(pwcs, s, n) == -1) {
852 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 143, "The string `%s' is not valid in current locale"), s);
853 }
854 }
855
856
857
858 Wstring::Wstring()
859 {
860 INIT_STRING_FROM_STACK(string, string_buf);
861 }
862
863 Wstring::Wstring(struct _Name * name)
864 {
865 INIT_STRING_FROM_STACK(string, string_buf);
866 append_string(name->string_mb, &string, name->hash.length);
867 }
868
869 Wstring::~Wstring()
870 {
871 if(string.free_after_use) {
872 retmem(string.buffer.start);
|
26
27 /*
28 * misc.cc
29 *
30 * This file contains various unclassified routines. Some main groups:
31 * getname
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 <stdarg.h> /* va_list, va_start(), va_end() */
47 #include <stdlib.h> /* mbstowcs() */
48 #include <sys/signal.h> /* SIG_DFL */
49 #include <sys/wait.h> /* wait() */
50
51 #include <string.h> /* strerror() */
52 #include <libintl.h>
53
54
55 /*
56 * Defined macros
57 */
58
59 /*
60 * typedefs & structs
61 */
62
63 /*
64 * Static variables
65 */
66 extern "C" {
67 void (*sigivalue)(int) = SIG_DFL;
68 void (*sigqvalue)(int) = SIG_DFL;
69 void (*sigtvalue)(int) = SIG_DFL;
70 void (*sighvalue)(int) = SIG_DFL;
71 }
72
90
91 /*
92 * getmem(size)
93 *
94 * malloc() version that checks the returned value.
95 *
96 * Return value:
97 * The memory chunk we allocated
98 *
99 * Parameters:
100 * size The size of the chunk we need
101 *
102 * Global variables used:
103 */
104 char *
105 getmem(register int size)
106 {
107 register char *result = (char *) malloc((unsigned) size);
108 if (result == NULL) {
109 char buf[FATAL_ERROR_MSG_SIZE];
110 sprintf(buf, "*** Error: malloc(%d) failed: %s\n", size, strerror(errno));
111 strcat(buf, gettext("mksh: Fatal error: Out of memory\n"));
112 fputs(buf, stderr);
113 exit_status = 1;
114 exit(1);
115 }
116 return result;
117 }
118
119 /*
120 * retmem(p)
121 *
122 * Cover funtion for free() to make it possible to insert advises.
123 *
124 * Parameters:
125 * p The memory block to free
126 *
127 * Global variables used:
128 */
129 void
130 retmem(wchar_t *p)
131 {
335 *
336 * Return value:
337 * An error message string
338 *
339 * Parameters:
340 * errnum The number of the error we want to describe
341 *
342 * Global variables used:
343 * sys_errlist A vector of error messages
344 * sys_nerr The size of sys_errlist
345 */
346 char *
347 errmsg(int errnum)
348 {
349
350 extern int sys_nerr;
351 char *errbuf;
352
353 if ((errnum < 0) || (errnum > sys_nerr)) {
354 errbuf = getmem(6+1+11+1);
355 (void) sprintf(errbuf, gettext("Error %d"), errnum);
356 return errbuf;
357 } else {
358 return strerror(errnum);
359
360 }
361 }
362
363 static char static_buf[MAXPATHLEN*3];
364
365 /*
366 * fatal_mksh(format, args...)
367 *
368 * Print a message and die
369 *
370 * Parameters:
371 * format printf type format string
372 * args Arguments to match the format
373 */
374 /*VARARGS*/
375 void
376 fatal_mksh(const char *message, ...)
377 {
378 va_list args;
379 char *buf = static_buf;
380 char *mksh_fat_err = gettext("mksh: Fatal error: ");
381 char *cur_wrk_dir = gettext("Current working directory: ");
382 int mksh_fat_err_len = strlen(mksh_fat_err);
383
384 va_start(args, message);
385 (void) fflush(stdout);
386 (void) strcpy(buf, mksh_fat_err);
387 size_t buf_len = vsnprintf(static_buf + mksh_fat_err_len,
388 sizeof(static_buf) - mksh_fat_err_len,
389 message, args)
390 + mksh_fat_err_len
391 + strlen(cur_wrk_dir)
392 + strlen(get_current_path_mksh())
393 + 3; // "\n\n"
394 va_end(args);
395 if (buf_len >= sizeof(static_buf)) {
396 buf = getmem(buf_len);
397 (void) strcpy(buf, mksh_fat_err);
398 va_start(args, message);
399 (void) vsprintf(buf + mksh_fat_err_len, message, args);
400 va_end(args);
401 }
420 /*
421 * fatal_reader_mksh(format, args...)
422 *
423 * Parameters:
424 * format printf style format string
425 * args arguments to match the format
426 */
427 /*VARARGS*/
428 void
429 fatal_reader_mksh(const char * pattern, ...)
430 {
431 va_list args;
432 char message[1000];
433
434 va_start(args, pattern);
435 /*
436 if (file_being_read != NULL) {
437 WCSTOMBS(mbs_buffer, file_being_read);
438 if (line_number != 0) {
439 (void) sprintf(message,
440 gettext("%s, line %d: %s"),
441 mbs_buffer,
442 line_number,
443 pattern);
444 } else {
445 (void) sprintf(message,
446 "%s: %s",
447 mbs_buffer,
448 pattern);
449 }
450 pattern = message;
451 }
452 */
453
454 (void) fflush(stdout);
455 (void) fprintf(stderr, gettext("mksh: Fatal error in reader: "));
456 (void) vfprintf(stderr, pattern, args);
457 (void) fprintf(stderr, "\n");
458 va_end(args);
459
460 /*
461 if (temp_file_name != NULL) {
462 (void) fprintf(stderr,
463 gettext("mksh: Temp-file %s not removed\n"),
464 temp_file_name->string_mb);
465 temp_file_name = NULL;
466 }
467 */
468
469 /*
470 if (report_pwd) {
471 */
472 if (1) {
473 (void) fprintf(stderr,
474 gettext("Current working directory %s\n"),
475 get_current_path_mksh());
476 }
477 (void) fflush(stderr);
478 exit_status = 1;
479 exit(1);
480 }
481
482 /*
483 * warning_mksh(format, args...)
484 *
485 * Print a message and continue.
486 *
487 * Parameters:
488 * format printf type format string
489 * args Arguments to match the format
490 */
491 /*VARARGS*/
492 void
493 warning_mksh(char * message, ...)
494 {
495 va_list args;
496
497 va_start(args, message);
498 (void) fflush(stdout);
499 (void) fprintf(stderr, gettext("mksh: Warning: "));
500 (void) vfprintf(stderr, message, args);
501 (void) fprintf(stderr, "\n");
502 va_end(args);
503 /*
504 if (report_pwd) {
505 */
506 if (1) {
507 (void) fprintf(stderr,
508 gettext("Current working directory %s\n"),
509 get_current_path_mksh());
510 }
511 (void) fflush(stderr);
512 }
513
514 /*
515 * get_current_path_mksh()
516 *
517 * Stuff current_path with the current path if it isnt there already.
518 *
519 * Parameters:
520 *
521 * Global variables used:
522 */
523 char *
524 get_current_path_mksh(void)
525 {
526 char pwd[(MAXPATHLEN * MB_LEN_MAX)];
527 static char *current_path;
528
585 break;
586 case target_prop:
587 size = sizeof (struct Target);
588 break;
589 case time_prop:
590 size = sizeof (struct STime);
591 break;
592 case vpath_alias_prop:
593 size = sizeof (struct Vpath_alias);
594 break;
595 case long_member_name_prop:
596 size = sizeof (struct Long_member_name);
597 break;
598 case macro_append_prop:
599 size = sizeof (struct _Macro_appendix);
600 break;
601 case env_mem_prop:
602 size = sizeof (struct _Env_mem);
603 break;
604 default:
605 fatal_mksh(gettext("Internal error. Unknown prop type %d"), type);
606 }
607 for (; prop != NULL; insert = &prop->next, prop = *insert);
608 size += PROPERTY_HEAD_SIZE;
609 *insert = prop = (Property) getmem(size);
610 memset((char *) prop, 0, size);
611 prop->type = type;
612 prop->next = NULL;
613 return prop;
614 }
615
616 /*
617 * maybe_append_prop(target, type)
618 *
619 * Append a property to the Name if none of this type exists
620 * else return the one already there
621 *
622 * Return value:
623 * A property of the requested type for the target
624 *
625 * Parameters:
832 * sigivalue The original signal handler
833 * sigqvalue The original signal handler
834 * sigtvalue The original signal handler
835 * sighvalue The original signal handler
836 */
837 void
838 setup_interrupt(register void (*handler) (int))
839 {
840 sigivalue = bsd_signal(SIGINT, SIG_IGN);
841 sigqvalue = bsd_signal(SIGQUIT, SIG_IGN);
842 sigtvalue = bsd_signal(SIGTERM, SIG_IGN);
843 sighvalue = bsd_signal(SIGHUP, SIG_IGN);
844 enable_interrupt(handler);
845 }
846
847
848 void
849 mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n)
850 {
851 if(mbstowcs(pwcs, s, n) == -1) {
852 fatal_mksh(gettext("The string `%s' is not valid in current locale"), s);
853 }
854 }
855
856
857
858 Wstring::Wstring()
859 {
860 INIT_STRING_FROM_STACK(string, string_buf);
861 }
862
863 Wstring::Wstring(struct _Name * name)
864 {
865 INIT_STRING_FROM_STACK(string, string_buf);
866 append_string(name->string_mb, &string, name->hash.length);
867 }
868
869 Wstring::~Wstring()
870 {
871 if(string.free_after_use) {
872 retmem(string.buffer.start);
|