diff options
author | Lukas Larsson <[email protected]> | 2014-12-12 15:29:10 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2014-12-12 15:29:10 +0100 |
commit | 1b6f362e555e508d3d40d907b10061e457deafb5 (patch) | |
tree | 2e1295acd8cc1b1e76f8b121e06c346d547ffdf4 /erts/lib_src/common | |
parent | d7893598224d7c4d576953265154e5b2ee4426f8 (diff) | |
parent | fb064173870a75d80402c3ad1e48dbaf59f086fb (diff) | |
download | otp-1b6f362e555e508d3d40d907b10061e457deafb5.tar.gz otp-1b6f362e555e508d3d40d907b10061e457deafb5.tar.bz2 otp-1b6f362e555e508d3d40d907b10061e457deafb5.zip |
Merge branch 'lukas/erts/non-blocking-shell'
* lukas/erts/non-blocking-shell:
erts: Make sure IOV_MAX is enforced for writev
erts: Make erts_printf work with non-blocking
Diffstat (limited to 'erts/lib_src/common')
-rw-r--r-- | erts/lib_src/common/erl_printf.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/erts/lib_src/common/erl_printf.c b/erts/lib_src/common/erl_printf.c index 2c177ee5ac..0a0346ac2d 100644 --- a/erts/lib_src/common/erl_printf.c +++ b/erts/lib_src/common/erl_printf.c @@ -87,6 +87,39 @@ void (*erts_printf_unblock_fpe)(int) = NULL; # define FWRITE fwrite #endif +/* We use write for stdout and stderr as they could be + set to non-blocking by shell drivers, and non-blocking + FILE * functions work unpredictably as best */ +static int +printf_putc(int c, FILE *stream) { + if ((FILE*)stream == stdout || (FILE*)stream == stderr) { + int fd = stream == stdout ? fileno(stdout) : fileno(stdin); + int res; + do { + res = write(fd,&c,1); + } while (res == -1 && (errno == EAGAIN || errno == EINTR)); + if (res == -1) return EOF; + return res; + } + + return PUTC(c, stream); +} + +static size_t +printf_fwrite(const void *ptr, size_t size, size_t nitems, + FILE *stream) { + if ((FILE*)stream == stdout || (FILE*)stream == stderr) { + int fd = stream == stdout ? fileno(stdout) : fileno(stdin); + int res; + do { + res = write(fd, ptr, size*nitems); + } while (res == -1 && (errno == EAGAIN || errno == EINTR)); + if (res == -1) return 0; + return res; + } + return FWRITE(ptr, size, nitems, stream); +} + static int get_error_result(void) { @@ -103,10 +136,10 @@ write_f_add_cr(void *vfp, char* buf, size_t len) size_t i; ASSERT(vfp); for (i = 0; i < len; i++) { - if (buf[i] == '\n' && PUTC('\r', (FILE *) vfp) == EOF) - return get_error_result(); - if (PUTC(buf[i], (FILE *) vfp) == EOF) - return get_error_result(); + if (buf[i] == '\n' && printf_putc('\r', (FILE *) vfp) == EOF) + return get_error_result(); + if (printf_putc(buf[i], (FILE *) vfp) == EOF) + return get_error_result(); } return len; } @@ -119,12 +152,12 @@ write_f(void *vfp, char* buf, size_t len) if (len <= 64) { /* Try to optimize writes of small bufs. */ int i; for (i = 0; i < len; i++) - if (PUTC(buf[i], (FILE *) vfp) == EOF) + if (printf_putc(buf[i], (FILE *) vfp) == EOF) return get_error_result(); } else #endif - if (FWRITE((void *) buf, sizeof(char), len, (FILE *) vfp) != len) + if (printf_fwrite((void *) buf, sizeof(char), len, (FILE *) vfp) != len) return get_error_result(); return len; } |