]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/runtime/error.c
Make recursion_check work for multiple threads
[thirdparty/gcc.git] / libgfortran / runtime / error.c
1 /* Copyright (C) 2002-2018 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3
4 This file is part of the GNU Fortran runtime library (libgfortran).
5
6 Libgfortran is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 Libgfortran is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
24
25
26 #include "libgfortran.h"
27 #include "io.h"
28 #include "async.h"
29
30 #include <assert.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <signal.h>
34
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38
39 #ifdef HAVE_SYS_TIME_H
40 #include <sys/time.h>
41 #endif
42
43 /* <sys/time.h> has to be included before <sys/resource.h> to work
44 around PR 30518; otherwise, MacOS 10.3.9 headers are just broken. */
45 #ifdef HAVE_SYS_RESOURCE_H
46 #include <sys/resource.h>
47 #endif
48
49
50 #include <locale.h>
51
52 #ifdef HAVE_XLOCALE_H
53 #include <xlocale.h>
54 #endif
55
56
57 #ifdef __MINGW32__
58 #define HAVE_GETPID 1
59 #include <process.h>
60 #endif
61
62
63 /* Termination of a program: F2008 2.3.5 talks about "normal
64 termination" and "error termination". Normal termination occurs as
65 a result of e.g. executing the end program statement, and executing
66 the STOP statement. It includes the effect of the C exit()
67 function.
68
69 Error termination is initiated when the ERROR STOP statement is
70 executed, when ALLOCATE/DEALLOCATE fails without STAT= being
71 specified, when some of the co-array synchronization statements
72 fail without STAT= being specified, and some I/O errors if
73 ERR/IOSTAT/END/EOR is not present, and finally EXECUTE_COMMAND_LINE
74 failure without CMDSTAT=.
75
76 2.3.5 also explains how co-images synchronize during termination.
77
78 In libgfortran we have three ways of ending a program. exit(code)
79 is a normal exit; calling exit() also causes open units to be
80 closed. No backtrace or core dump is needed here. For error
81 termination, we have exit_error(status), which prints a backtrace
82 if backtracing is enabled, then exits. Finally, when something
83 goes terribly wrong, we have sys_abort() which tries to print the
84 backtrace if -fbacktrace is enabled, and then dumps core; whether a
85 core file is generated is system dependent. When aborting, we don't
86 flush and close open units, as program memory might be corrupted
87 and we'd rather risk losing dirty data in the buffers rather than
88 corrupting files on disk.
89
90 */
91
92 /* Error conditions. The tricky part here is printing a message when
93 * it is the I/O subsystem that is severely wounded. Our goal is to
94 * try and print something making the fewest assumptions possible,
95 * then try to clean up before actually exiting.
96 *
97 * The following exit conditions are defined:
98 * 0 Normal program exit.
99 * 1 Terminated because of operating system error.
100 * 2 Error in the runtime library
101 * 3 Internal error in runtime library
102 *
103 * Other error returns are reserved for the STOP statement with a numeric code.
104 */
105
106
107 /* Write a null-terminated C string to standard error. This function
108 is async-signal-safe. */
109
110 ssize_t
111 estr_write (const char *str)
112 {
113 return write (STDERR_FILENO, str, strlen (str));
114 }
115
116
117 /* Write a vector of strings to standard error. This function is
118 async-signal-safe. */
119
120 ssize_t
121 estr_writev (const struct iovec *iov, int iovcnt)
122 {
123 #ifdef HAVE_WRITEV
124 return writev (STDERR_FILENO, iov, iovcnt);
125 #else
126 ssize_t w = 0;
127 for (int i = 0; i < iovcnt; i++)
128 {
129 ssize_t r = write (STDERR_FILENO, iov[i].iov_base, iov[i].iov_len);
130 if (r == -1)
131 return r;
132 w += r;
133 }
134 return w;
135 #endif
136 }
137
138
139 #ifndef HAVE_VSNPRINTF
140 static int
141 gf_vsnprintf (char *str, size_t size, const char *format, va_list ap)
142 {
143 int written;
144
145 written = vsprintf(buffer, format, ap);
146
147 if (written >= size - 1)
148 {
149 /* The error message was longer than our buffer. Ouch. Because
150 we may have messed up things badly, report the error and
151 quit. */
152 #define ERROR_MESSAGE "Internal error: buffer overrun in gf_vsnprintf()\n"
153 write (STDERR_FILENO, buffer, size - 1);
154 write (STDERR_FILENO, ERROR_MESSAGE, strlen (ERROR_MESSAGE));
155 sys_abort ();
156 #undef ERROR_MESSAGE
157
158 }
159 return written;
160 }
161
162 #define vsnprintf gf_vsnprintf
163 #endif
164
165
166 /* printf() like function for for printing to stderr. Uses a stack
167 allocated buffer and doesn't lock stderr, so it should be safe to
168 use from within a signal handler. */
169
170 #define ST_ERRBUF_SIZE 512
171
172 int
173 st_printf (const char * format, ...)
174 {
175 char buffer[ST_ERRBUF_SIZE];
176 int written;
177 va_list ap;
178 va_start (ap, format);
179 written = vsnprintf (buffer, ST_ERRBUF_SIZE, format, ap);
180 va_end (ap);
181 written = write (STDERR_FILENO, buffer, written);
182 return written;
183 }
184
185
186 /* sys_abort()-- Terminate the program showing backtrace and dumping
187 core. */
188
189 void
190 sys_abort (void)
191 {
192 /* If backtracing is enabled, print backtrace and disable signal
193 handler for ABRT. */
194 if (options.backtrace == 1
195 || (options.backtrace == -1 && compile_options.backtrace == 1))
196 {
197 estr_write ("\nProgram aborted. Backtrace:\n");
198 show_backtrace (false);
199 signal (SIGABRT, SIG_DFL);
200 }
201
202 abort();
203 }
204
205
206 /* Exit in case of error termination. If backtracing is enabled, print
207 backtrace, then exit. */
208
209 void
210 exit_error (int status)
211 {
212 if (options.backtrace == 1
213 || (options.backtrace == -1 && compile_options.backtrace == 1))
214 {
215 estr_write ("\nError termination. Backtrace:\n");
216 show_backtrace (false);
217 }
218 exit (status);
219 }
220
221
222
223 /* gfc_xtoa()-- Integer to hexadecimal conversion. */
224
225 const char *
226 gfc_xtoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
227 {
228 int digit;
229 char *p;
230
231 assert (len >= GFC_XTOA_BUF_SIZE);
232
233 if (n == 0)
234 return "0";
235
236 p = buffer + GFC_XTOA_BUF_SIZE - 1;
237 *p = '\0';
238
239 while (n != 0)
240 {
241 digit = n & 0xF;
242 if (digit > 9)
243 digit += 'A' - '0' - 10;
244
245 *--p = '0' + digit;
246 n >>= 4;
247 }
248
249 return p;
250 }
251
252
253 /* Hopefully thread-safe wrapper for a strerror() style function. */
254
255 char *
256 gf_strerror (int errnum,
257 char * buf __attribute__((unused)),
258 size_t buflen __attribute__((unused)))
259 {
260 #ifdef HAVE_STRERROR_L
261 locale_t myloc = newlocale (LC_CTYPE_MASK | LC_MESSAGES_MASK, "",
262 (locale_t) 0);
263 char *p;
264 if (myloc)
265 {
266 p = strerror_l (errnum, myloc);
267 freelocale (myloc);
268 }
269 else
270 /* newlocale might fail e.g. due to running out of memory, fall
271 back to the simpler strerror. */
272 p = strerror (errnum);
273 return p;
274 #elif defined(HAVE_STRERROR_R)
275 #ifdef HAVE_USELOCALE
276 /* Some targets (Darwin at least) have the POSIX 2008 extended
277 locale functions, but not strerror_l. So reset the per-thread
278 locale here. */
279 uselocale (LC_GLOBAL_LOCALE);
280 #endif
281 /* POSIX returns an "int", GNU a "char*". */
282 return
283 __builtin_choose_expr (__builtin_classify_type (strerror_r (0, buf, 0))
284 == 5,
285 /* GNU strerror_r() */
286 strerror_r (errnum, buf, buflen),
287 /* POSIX strerror_r () */
288 (strerror_r (errnum, buf, buflen), buf));
289 #elif defined(HAVE_STRERROR_R_2ARGS)
290 strerror_r (errnum, buf);
291 return buf;
292 #else
293 /* strerror () is not necessarily thread-safe, but should at least
294 be available everywhere. */
295 return strerror (errnum);
296 #endif
297 }
298
299
300 /* show_locus()-- Print a line number and filename describing where
301 * something went wrong */
302
303 void
304 show_locus (st_parameter_common *cmp)
305 {
306 char *filename;
307
308 if (!options.locus || cmp == NULL || cmp->filename == NULL)
309 return;
310
311 if (cmp->unit > 0)
312 {
313 filename = filename_from_unit (cmp->unit);
314
315 if (filename != NULL)
316 {
317 st_printf ("At line %d of file %s (unit = %d, file = '%s')\n",
318 (int) cmp->line, cmp->filename, (int) cmp->unit, filename);
319 free (filename);
320 }
321 else
322 {
323 st_printf ("At line %d of file %s (unit = %d)\n",
324 (int) cmp->line, cmp->filename, (int) cmp->unit);
325 }
326 return;
327 }
328
329 st_printf ("At line %d of file %s\n", (int) cmp->line, cmp->filename);
330 }
331
332
333 /* recursion_check()-- It's possible for additional errors to occur
334 * during fatal error processing. We detect this condition here and
335 * abort immediately. */
336
337 static __gthread_key_t recursion_key;
338
339 static void
340 recursion_check (void)
341 {
342 if (__gthread_active_p ())
343 {
344 bool* p = __gthread_getspecific (recursion_key);
345 if (!p)
346 {
347 p = xcalloc (1, sizeof (bool));
348 __gthread_setspecific (recursion_key, p);
349 }
350 if (*p)
351 sys_abort ();
352 *p = true;
353 }
354 else
355 {
356 static bool recur;
357 if (recur)
358 sys_abort ();
359 recur = true;
360 }
361 }
362
363 #ifdef __GTHREADS
364 static void __attribute__((constructor))
365 constructor_recursion_check (void)
366 {
367 if (__gthread_active_p ())
368 __gthread_key_create (&recursion_key, &free);
369 }
370
371 static void __attribute__((destructor))
372 destructor_recursion_check (void)
373 {
374 if (__gthread_active_p ())
375 __gthread_key_delete (recursion_key);
376 }
377 #endif
378
379
380
381 #define STRERR_MAXSZ 256
382
383 /* os_error()-- Operating system error. We get a message from the
384 * operating system, show it and leave. Some operating system errors
385 * are caught and processed by the library. If not, we come here. */
386
387 void
388 os_error (const char *message)
389 {
390 char errmsg[STRERR_MAXSZ];
391 struct iovec iov[5];
392 recursion_check ();
393 iov[0].iov_base = (char*) "Operating system error: ";
394 iov[0].iov_len = strlen (iov[0].iov_base);
395 iov[1].iov_base = gf_strerror (errno, errmsg, STRERR_MAXSZ);
396 iov[1].iov_len = strlen (iov[1].iov_base);
397 iov[2].iov_base = (char*) "\n";
398 iov[2].iov_len = 1;
399 iov[3].iov_base = (char*) message;
400 iov[3].iov_len = strlen (message);
401 iov[4].iov_base = (char*) "\n";
402 iov[4].iov_len = 1;
403 estr_writev (iov, 5);
404 exit_error (1);
405 }
406 iexport(os_error);
407
408
409 /* void runtime_error()-- These are errors associated with an
410 * invalid fortran program. */
411
412 void
413 runtime_error (const char *message, ...)
414 {
415 char buffer[ST_ERRBUF_SIZE];
416 struct iovec iov[3];
417 va_list ap;
418 int written;
419
420 recursion_check ();
421 iov[0].iov_base = (char*) "Fortran runtime error: ";
422 iov[0].iov_len = strlen (iov[0].iov_base);
423 va_start (ap, message);
424 written = vsnprintf (buffer, ST_ERRBUF_SIZE, message, ap);
425 va_end (ap);
426 if (written >= 0)
427 {
428 iov[1].iov_base = buffer;
429 iov[1].iov_len = written;
430 iov[2].iov_base = (char*) "\n";
431 iov[2].iov_len = 1;
432 estr_writev (iov, 3);
433 }
434 exit_error (2);
435 }
436 iexport(runtime_error);
437
438 /* void runtime_error_at()-- These are errors associated with a
439 * run time error generated by the front end compiler. */
440
441 void
442 runtime_error_at (const char *where, const char *message, ...)
443 {
444 char buffer[ST_ERRBUF_SIZE];
445 va_list ap;
446 struct iovec iov[4];
447 int written;
448
449 recursion_check ();
450 iov[0].iov_base = (char*) where;
451 iov[0].iov_len = strlen (where);
452 iov[1].iov_base = (char*) "\nFortran runtime error: ";
453 iov[1].iov_len = strlen (iov[1].iov_base);
454 va_start (ap, message);
455 written = vsnprintf (buffer, ST_ERRBUF_SIZE, message, ap);
456 va_end (ap);
457 if (written >= 0)
458 {
459 iov[2].iov_base = buffer;
460 iov[2].iov_len = written;
461 iov[3].iov_base = (char*) "\n";
462 iov[3].iov_len = 1;
463 estr_writev (iov, 4);
464 }
465 exit_error (2);
466 }
467 iexport(runtime_error_at);
468
469
470 void
471 runtime_warning_at (const char *where, const char *message, ...)
472 {
473 char buffer[ST_ERRBUF_SIZE];
474 va_list ap;
475 struct iovec iov[4];
476 int written;
477
478 iov[0].iov_base = (char*) where;
479 iov[0].iov_len = strlen (where);
480 iov[1].iov_base = (char*) "\nFortran runtime warning: ";
481 iov[1].iov_len = strlen (iov[1].iov_base);
482 va_start (ap, message);
483 written = vsnprintf (buffer, ST_ERRBUF_SIZE, message, ap);
484 va_end (ap);
485 if (written >= 0)
486 {
487 iov[2].iov_base = buffer;
488 iov[2].iov_len = written;
489 iov[3].iov_base = (char*) "\n";
490 iov[3].iov_len = 1;
491 estr_writev (iov, 4);
492 }
493 }
494 iexport(runtime_warning_at);
495
496
497 /* void internal_error()-- These are this-can't-happen errors
498 * that indicate something deeply wrong. */
499
500 void
501 internal_error (st_parameter_common *cmp, const char *message)
502 {
503 struct iovec iov[3];
504
505 recursion_check ();
506 show_locus (cmp);
507 iov[0].iov_base = (char*) "Internal Error: ";
508 iov[0].iov_len = strlen (iov[0].iov_base);
509 iov[1].iov_base = (char*) message;
510 iov[1].iov_len = strlen (message);
511 iov[2].iov_base = (char*) "\n";
512 iov[2].iov_len = 1;
513 estr_writev (iov, 3);
514
515 /* This function call is here to get the main.o object file included
516 when linking statically. This works because error.o is supposed to
517 be always linked in (and the function call is in internal_error
518 because hopefully it doesn't happen too often). */
519 stupid_function_name_for_static_linking();
520
521 exit_error (3);
522 }
523
524
525 /* translate_error()-- Given an integer error code, return a string
526 * describing the error. */
527
528 const char *
529 translate_error (int code)
530 {
531 const char *p;
532
533 switch (code)
534 {
535 case LIBERROR_EOR:
536 p = "End of record";
537 break;
538
539 case LIBERROR_END:
540 p = "End of file";
541 break;
542
543 case LIBERROR_OK:
544 p = "Successful return";
545 break;
546
547 case LIBERROR_OS:
548 p = "Operating system error";
549 break;
550
551 case LIBERROR_BAD_OPTION:
552 p = "Bad statement option";
553 break;
554
555 case LIBERROR_MISSING_OPTION:
556 p = "Missing statement option";
557 break;
558
559 case LIBERROR_OPTION_CONFLICT:
560 p = "Conflicting statement options";
561 break;
562
563 case LIBERROR_ALREADY_OPEN:
564 p = "File already opened in another unit";
565 break;
566
567 case LIBERROR_BAD_UNIT:
568 p = "Unattached unit";
569 break;
570
571 case LIBERROR_FORMAT:
572 p = "FORMAT error";
573 break;
574
575 case LIBERROR_BAD_ACTION:
576 p = "Incorrect ACTION specified";
577 break;
578
579 case LIBERROR_ENDFILE:
580 p = "Read past ENDFILE record";
581 break;
582
583 case LIBERROR_BAD_US:
584 p = "Corrupt unformatted sequential file";
585 break;
586
587 case LIBERROR_READ_VALUE:
588 p = "Bad value during read";
589 break;
590
591 case LIBERROR_READ_OVERFLOW:
592 p = "Numeric overflow on read";
593 break;
594
595 case LIBERROR_INTERNAL:
596 p = "Internal error in run-time library";
597 break;
598
599 case LIBERROR_INTERNAL_UNIT:
600 p = "Internal unit I/O error";
601 break;
602
603 case LIBERROR_DIRECT_EOR:
604 p = "Write exceeds length of DIRECT access record";
605 break;
606
607 case LIBERROR_SHORT_RECORD:
608 p = "I/O past end of record on unformatted file";
609 break;
610
611 case LIBERROR_CORRUPT_FILE:
612 p = "Unformatted file structure has been corrupted";
613 break;
614
615 case LIBERROR_INQUIRE_INTERNAL_UNIT:
616 p = "Inquire statement identifies an internal file";
617 break;
618
619 default:
620 p = "Unknown error code";
621 break;
622 }
623
624 return p;
625 }
626
627
628 /* Worker function for generate_error and generate_error_async. Return true
629 if a straight return is to be done, zero if the program should abort. */
630
631 bool
632 generate_error_common (st_parameter_common *cmp, int family, const char *message)
633 {
634 char errmsg[STRERR_MAXSZ];
635
636 #if ASYNC_IO
637 gfc_unit *u;
638
639 NOTE ("Entering generate_error_common");
640
641 u = thread_unit;
642 if (u && u->au)
643 {
644 if (u->au->error.has_error)
645 return true;
646
647 if (__gthread_equal (u->au->thread, __gthread_self ()))
648 {
649 u->au->error.has_error = 1;
650 u->au->error.cmp = cmp;
651 u->au->error.family = family;
652 u->au->error.message = message;
653 return true;
654 }
655 }
656 #endif
657
658 /* If there was a previous error, don't mask it with another
659 error message, EOF or EOR condition. */
660
661 if ((cmp->flags & IOPARM_LIBRETURN_MASK) == IOPARM_LIBRETURN_ERROR)
662 return true;
663
664 /* Set the error status. */
665 if ((cmp->flags & IOPARM_HAS_IOSTAT))
666 *cmp->iostat = (family == LIBERROR_OS) ? errno : family;
667
668 if (message == NULL)
669 message =
670 (family == LIBERROR_OS) ? gf_strerror (errno, errmsg, STRERR_MAXSZ) :
671 translate_error (family);
672
673 if (cmp->flags & IOPARM_HAS_IOMSG)
674 cf_strcpy (cmp->iomsg, cmp->iomsg_len, message);
675
676 /* Report status back to the compiler. */
677 cmp->flags &= ~IOPARM_LIBRETURN_MASK;
678 switch (family)
679 {
680 case LIBERROR_EOR:
681 cmp->flags |= IOPARM_LIBRETURN_EOR; NOTE("EOR");
682 if ((cmp->flags & IOPARM_EOR))
683 return true;
684 break;
685
686 case LIBERROR_END:
687 cmp->flags |= IOPARM_LIBRETURN_END; NOTE("END");
688 if ((cmp->flags & IOPARM_END))
689 return true;
690 break;
691
692 default:
693 cmp->flags |= IOPARM_LIBRETURN_ERROR; NOTE("ERROR");
694 if ((cmp->flags & IOPARM_ERR))
695 return true;
696 break;
697 }
698
699 /* Return if the user supplied an iostat variable. */
700 if ((cmp->flags & IOPARM_HAS_IOSTAT))
701 return true;
702
703 /* Return code, caller is responsible for terminating
704 the program if necessary. */
705
706 recursion_check ();
707 show_locus (cmp);
708 struct iovec iov[3];
709 iov[0].iov_base = (char*) "Fortran runtime error: ";
710 iov[0].iov_len = strlen (iov[0].iov_base);
711 iov[1].iov_base = (char*) message;
712 iov[1].iov_len = strlen (message);
713 iov[2].iov_base = (char*) "\n";
714 iov[2].iov_len = 1;
715 estr_writev (iov, 3);
716 return false;
717 }
718
719 /* generate_error()-- Come here when an error happens. This
720 * subroutine is called if it is possible to continue on after the error.
721 * If an IOSTAT or IOMSG variable exists, we set it. If IOSTAT or
722 * ERR labels are present, we return, otherwise we terminate the program
723 * after printing a message. The error code is always required but the
724 * message parameter can be NULL, in which case a string describing
725 * the most recent operating system error is used.
726 * If the error is for an asynchronous unit and if the program is currently
727 * executing the asynchronous thread, just mark the error and return. */
728
729 void
730 generate_error (st_parameter_common *cmp, int family, const char *message)
731 {
732 if (generate_error_common (cmp, family, message))
733 return;
734
735 exit_error(2);
736 }
737 iexport(generate_error);
738
739
740 /* generate_warning()-- Similar to generate_error but just give a warning. */
741
742 void
743 generate_warning (st_parameter_common *cmp, const char *message)
744 {
745 if (message == NULL)
746 message = " ";
747
748 show_locus (cmp);
749 struct iovec iov[3];
750 iov[0].iov_base = (char*) "Fortran runtime warning: ";
751 iov[0].iov_len = strlen (iov[0].iov_base);
752 iov[1].iov_base = (char*) message;
753 iov[1].iov_len = strlen (message);
754 iov[2].iov_base = (char*) "\n";
755 iov[2].iov_len = 1;
756 estr_writev (iov, 3);
757 }
758
759
760 /* Whether, for a feature included in a given standard set (GFC_STD_*),
761 we should issue an error or a warning, or be quiet. */
762
763 notification
764 notification_std (int std)
765 {
766 int warning;
767
768 if (!compile_options.pedantic)
769 return NOTIFICATION_SILENT;
770
771 warning = compile_options.warn_std & std;
772 if ((compile_options.allow_std & std) != 0 && !warning)
773 return NOTIFICATION_SILENT;
774
775 return warning ? NOTIFICATION_WARNING : NOTIFICATION_ERROR;
776 }
777
778
779 /* Possibly issue a warning/error about use of a nonstandard (or deleted)
780 feature. An error/warning will be issued if the currently selected
781 standard does not contain the requested bits. */
782
783 bool
784 notify_std (st_parameter_common *cmp, int std, const char * message)
785 {
786 int warning;
787 struct iovec iov[3];
788
789 if (!compile_options.pedantic)
790 return true;
791
792 warning = compile_options.warn_std & std;
793 if ((compile_options.allow_std & std) != 0 && !warning)
794 return true;
795
796 if (!warning)
797 {
798 recursion_check ();
799 show_locus (cmp);
800 iov[0].iov_base = (char*) "Fortran runtime error: ";
801 iov[0].iov_len = strlen (iov[0].iov_base);
802 iov[1].iov_base = (char*) message;
803 iov[1].iov_len = strlen (message);
804 iov[2].iov_base = (char*) "\n";
805 iov[2].iov_len = 1;
806 estr_writev (iov, 3);
807 exit_error (2);
808 }
809 else
810 {
811 show_locus (cmp);
812 iov[0].iov_base = (char*) "Fortran runtime warning: ";
813 iov[0].iov_len = strlen (iov[0].iov_base);
814 iov[1].iov_base = (char*) message;
815 iov[1].iov_len = strlen (message);
816 iov[2].iov_base = (char*) "\n";
817 iov[2].iov_len = 1;
818 estr_writev (iov, 3);
819 }
820 return false;
821 }