* makeint.h: Change OUT_OF_MEM() macro to out_of_memory() function.
* output.h, job.h: Move FD_* macros from job.h to output.h.
* output.c (output_write): Write a buffer to an FD directly.
(out_of_memory): Use output_write() to avoid allocating more
memory while writing the error, and call exit() instead of die().
This does mean we can't translate the error string, though.
* misc.c (xmalloc, xcalloc, xrealloc, xstrdup, xstrndup): Call new
out_of_memory() rather than OUT_OF_MEM().
* read.c (parse_file_seq): Ditto.
#ifndef AR_HDR_SIZE
# define AR_HDR_SIZE (sizeof (struct ar_hdr))
#endif
+
+#include "output.h"
\f
/* Takes three arguments ARCHIVE, FUNCTION and ARG.
EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose;
- EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
+ r = output_write (fd, &ar_hdr, AR_HDR_SIZE);
if (r != AR_HDR_SIZE)
goto lose;
/* The file's mtime is the time we we want. */
EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose;
- EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
+ r = output_write (fd, &ar_hdr, AR_HDR_SIZE);
if (r != AR_HDR_SIZE)
goto lose;
close (fd);
/* Build host information. */
#define MAKE_HOST "Amiga"
+
+/* Define to `int' if <sys/types.h> does not define. */
+#define ssize_t int
#endif
#endif
+/* Define to `int' if <sys/types.h> does not define. */
+#define ssize_t int
+
/* Define to 'int' if <sys/types.h> doesn't define. */
#define uid_t int
/* Grok DOS paths (drive specs and backslash path element separators) */
#define HAVE_DOS_PATHS
+
+/* Define to `int' if <sys/types.h> does not define. */
+#define ssize_t int
#ifdef VMS
int child_execute_job (struct child *child, char *argv);
#else
-# define FD_STDIN (fileno (stdin))
-# define FD_STDOUT (fileno (stdout))
-# define FD_STDERR (fileno (stderr))
int child_execute_job (struct output *out, int good_stdin, char **argv, char **envp);
#endif
__attribute__ ((__format__ (__printf__, 3, 4)));
void fatal (const floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((noreturn, __format__ (__printf__, 3, 4)));
+void out_of_memory () __attribute__((noreturn));
/* When adding macros to this list be sure to update the value of
XGETTEXT_OPTIONS in the po/Makevars file. */
#define ONS(_t,_a,_f,_n,_s) _t((_a), INTSTR_LENGTH + strlen (_s), \
(_f), (_n), (_s))
-#define OUT_OF_MEM() O (fatal, NILF, _("virtual memory exhausted"))
-
void die (int) __attribute__ ((noreturn));
void pfatal_with_name (const char *) __attribute__ ((noreturn));
void perror_with_name (const char *, const char *);
/* Make sure we don't allocate 0, for pre-ISO implementations. */
void *result = malloc (size ? size : 1);
if (result == 0)
- OUT_OF_MEM();
+ out_of_memory ();
return result;
}
/* Make sure we don't allocate 0, for pre-ISO implementations. */
void *result = calloc (size ? size : 1, 1);
if (result == 0)
- OUT_OF_MEM();
+ out_of_memory ();
return result;
}
size = 1;
result = ptr ? realloc (ptr, size) : malloc (size);
if (result == 0)
- OUT_OF_MEM();
+ out_of_memory ();
return result;
}
#endif
if (result == 0)
- OUT_OF_MEM();
+ out_of_memory ();
#ifdef HAVE_STRDUP
return result;
#ifdef HAVE_STRNDUP
result = strndup (str, length);
if (result == 0)
- OUT_OF_MEM();
+ out_of_memory ();
#else
result = xmalloc (length + 1);
if (length > 0)
# define MODE_T int
#endif
+/* Write a BUFFER of size LEN to file descriptor FD.
+ Handle EINTR and other short writes. If we get an error, ignore it. */
+int
+output_write (int fd, const void *buffer, size_t len)
+{
+ const char *msg = buffer;
+ while (1)
+ {
+ ssize_t r;
+
+ EINTRLOOP (r, write (fd, msg, len));
+
+ if (r < 0 || (size_t)r == len)
+ return r;
+
+ len -= r;
+ msg += r;
+ }
+}
+
/* Write a string to the current STDOUT or STDERR. */
static void
_outputs (struct output *out, int is_err, const char *msg)
int fd = is_err ? out->err : out->out;
int len = strlen (msg);
int r;
-
EINTRLOOP (r, lseek (fd, 0, SEEK_END));
- while (1)
- {
- EINTRLOOP (r, write (fd, msg, len));
- if (r == len || r <= 0)
- break;
- len -= r;
- msg += r;
- }
+ output_write (fd, msg, len);
}
}
\f
/* NOTREACHED */
}
+
+/* Print a message about out of memory (not using more heap) and exit.
+ Our goal here is to be sure we don't try to allocate more memory, which
+ means we don't want to use string translations or normal cleanup. */
+
+void
+out_of_memory ()
+{
+ output_write (FD_STDOUT, program, strlen (program));
+ output_write (FD_STDOUT, STRING_SIZE_TUPLE (": *** virtual memory exhausted\n"));
+ exit (MAKE_FAILURE);
+}
extern struct output *output_context;
extern unsigned int stdio_traced;
+#define FD_STDIN (fileno (stdin))
+#define FD_STDOUT (fileno (stdout))
+#define FD_STDERR (fileno (stderr))
+
#define OUTPUT_SET(_new) do{ output_context = (_new)->syncout ? (_new) : NULL; }while(0)
#define OUTPUT_UNSET() do{ output_context = NULL; }while(0)
FILE *output_tmpfile (char **, const char *);
+/* Write a buffer directly to the given file descriptor.
+ This handles errors etc. */
+int output_write (int fd, const void *buffer, size_t len);
+
/* Initialize and close a child output structure: if NULL do this program's
output (this should only be done once). */
void output_init (struct output *out);
switch (glob (name, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl))
{
case GLOB_NOSPACE:
- OUT_OF_MEM();
+ out_of_memory ();
case 0:
/* Success. */