improved error number handling.

handled a broken pipe condition from an anonymous pipe in awk
This commit is contained in:
2012-12-27 14:40:58 +00:00
parent b8c66b5b8d
commit eb28009952
14 changed files with 204 additions and 127 deletions

View File

@ -1728,6 +1728,16 @@ static qse_ssize_t awk_rio_console (
if (sio) qse_sio_close (sio);
}
#if defined(_WIN32)
/* DIRTY HACK FOR WIN32.
* ReadFile returns failure with ERROR_BROKEN_PIPE
* when an anonymous pipe is closed. it doesn't return EOF.
* Let me handle that specially here for console only.
*/
if (nn <= -1 &&
qse_sio_geterrnum ((qse_sio_t*)riod->handle) == QSE_SIO_EPIPE) return 0;
#endif
return nn;
}

View File

@ -110,6 +110,7 @@ int qse_mux_init (qse_mux_t* mux, qse_mmgr_t* mmgr, qse_mux_evtfun_t evtfun, qse
void qse_mux_fini (qse_mux_t* mux);
#if defined(_WIN32)
/* TODO: change the error code handling. this is wrong... use WSA error codes .... */
static qse_mux_errnum_t syserr_to_errnum (DWORD e)
{
@ -136,6 +137,9 @@ static qse_mux_errnum_t syserr_to_errnum (DWORD e)
case ERROR_FILE_EXISTS:
return QSE_MUX_EEXIST;
case ERROR_BROKEN_PIPE:
return QSE_MUX_EPIPE;
default:
return QSE_MUX_ESYSERR;
}
@ -221,6 +225,12 @@ static qse_mux_errnum_t syserr_to_errnum (int e)
case EINTR:
return QSE_MUX_EINTR;
case EPIPE:
return QSE_MUX_EPIPE;
case EAGAIN:
return QSE_MUX_EAGAIN;
default:
return QSE_MUX_ESYSERR;
}

View File

@ -31,7 +31,6 @@
# include "syscall.h"
#endif
/* internal status codes */
enum
{
@ -60,6 +59,10 @@ static qse_sio_errnum_t fio_errnum_to_sio_errnum (qse_fio_t* fio)
return QSE_SIO_EEXIST;
case QSE_FIO_EINTR:
return QSE_SIO_EINTR;
case QSE_FIO_EPIPE:
return QSE_SIO_EPIPE;
case QSE_FIO_EAGAIN:
return QSE_SIO_EAGAIN;
case QSE_FIO_ESYSERR:
return QSE_SIO_ESYSERR;
case QSE_FIO_ENOIMPL:

View File

@ -23,29 +23,49 @@
#include <qse/cmn/mbwc.h>
#include "mem.h"
#include <stdio.h>
#if defined(__GLIBC__)
/* for vswprintf */
# define __USE_UNIX98
#endif
#include <wchar.h>
#include <stdlib.h>
#include <limits.h>
#ifndef PATH_MAX
# define PATH_MAX 2048
#if defined(_WIN32) && !defined(__WATCOMC__)
# include <tchar.h>
# define FGETC(x) _fgettc(x)
#elif defined(QSE_CHAR_IS_MCHAR)
# define FGETC(x) fgetc(x)
#else
# define FGETC(x) fgetwc(x)
#endif
#define STREAM_TO_FILE(stream) \
((stream == QSE_STDOUT)? stdout: \
(stream == QSE_STDERR)? stderr: \
(stream == QSE_STDIN)? stdin: (FILE*)stream)
static qse_char_t* __adjust_format (const qse_char_t* format);
int qse_vfprintf (QSE_FILE *stream, const qse_char_t* fmt, va_list ap)
{
int n;
qse_char_t* nf;
FILE* fp;
nf = __adjust_format (fmt);
if (nf == NULL) return -1;
#if defined(QSE_CHAR_IS_MCHAR)
n = vfprintf (stream, nf, ap);
#else
n = vfwprintf (stream, nf, ap);
#endif
fp = STREAM_TO_FILE (stream);
#if defined(QSE_CHAR_IS_MCHAR)
n = vfprintf (fp, nf, ap);
#else
n = vfwprintf (fp, nf, ap);
#endif
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), nf);
return n;
}
@ -59,29 +79,32 @@ int qse_vprintf (const qse_char_t* fmt, va_list ap)
if (nf == NULL) return -1;
#if defined(QSE_CHAR_IS_MCHAR)
n = vfprintf (QSE_STDOUT, nf, ap);
n = vfprintf (stdout, nf, ap);
#else
n = vfwprintf (QSE_STDOUT, nf, ap);
n = vfwprintf (stdout, nf, ap);
#endif
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), nf);
return n;
}
int qse_fprintf (QSE_FILE* file, const qse_char_t* fmt, ...)
int qse_fprintf (QSE_FILE* stream, const qse_char_t* fmt, ...)
{
int n;
va_list ap;
qse_char_t* nf;
FILE* fp;
nf = __adjust_format (fmt);
if (nf == NULL) return -1;
fp = STREAM_TO_FILE (stream);
va_start (ap, fmt);
#if defined(QSE_CHAR_IS_MCHAR)
n = vfprintf (file, nf, ap);
n = vfprintf (fp, nf, ap);
#else
n = vfwprintf (file, nf, ap);
n = vfwprintf (fp, nf, ap);
#endif
va_end (ap);
@ -100,9 +123,9 @@ int qse_printf (const qse_char_t* fmt, ...)
va_start (ap, fmt);
#if defined(QSE_CHAR_IS_MCHAR)
n = vfprintf (QSE_STDOUT, nf, ap);
n = vfprintf (stdout, nf, ap);
#else
n = vfwprintf (QSE_STDOUT, nf, ap);
n = vfwprintf (stdout, nf, ap);
#endif
va_end (ap);
@ -121,9 +144,9 @@ int qse_dprintf (const qse_char_t* fmt, ...)
va_start (ap, fmt);
#if defined(QSE_CHAR_IS_MCHAR)
n = vfprintf (QSE_STDERR, nf, ap);
n = vfprintf (stderr, nf, ap);
#else
n = vfwprintf (QSE_STDOUT, nf, ap);
n = vfwprintf (stderr, nf, ap);
#endif
va_end (ap);
@ -426,12 +449,12 @@ done:
QSE_FILE* qse_fopen (const qse_char_t* path, const qse_char_t* mode)
{
#if defined(QSE_CHAR_IS_MCHAR)
return fopen (path, mode);
return (QSE_FILE*)fopen (path, mode);
#elif defined(_WIN32) || defined(__OS2__)
return _wfopen (path, mode);
return (QSE_FILE*)_wfopen (path, mode);
#else
QSE_FILE* fp = QSE_NULL;
FILE* fp = QSE_NULL;
qse_mchar_t* path_mb;
qse_mchar_t* mode_mb;
@ -446,33 +469,43 @@ QSE_FILE* qse_fopen (const qse_char_t* path, const qse_char_t* mode)
if (mode_mb) QSE_MMGR_FREE (QSE_MMGR_GETDFL(), mode_mb);
if (path_mb) QSE_MMGR_FREE (QSE_MMGR_GETDFL(), path_mb);
return fp;
return (QSE_FILE*)fp;
#endif
}
void qse_fclose (QSE_FILE* fp)
void qse_fclose (QSE_FILE* stream)
{
FILE* fp;
fp = STREAM_TO_FILE (stream);
fclose (fp);
}
int qse_fflush (QSE_FILE* fp)
int qse_fflush (QSE_FILE* stream)
{
FILE* fp;
fp = STREAM_TO_FILE (stream);
return fflush (fp);
}
void qse_clearerr (QSE_FILE* fp)
void qse_clearerr (QSE_FILE* stream)
{
FILE* fp;
fp = STREAM_TO_FILE (stream);
clearerr (fp);
}
int qse_feof (QSE_FILE* fp)
int qse_feof (QSE_FILE* stream)
{
FILE* fp;
fp = STREAM_TO_FILE (stream);
return feof (fp);
}
int qse_ferror (QSE_FILE* fp)
int qse_ferror (QSE_FILE* stream)
{
FILE* fp;
fp = STREAM_TO_FILE (stream);
return ferror (fp);
}
@ -481,24 +514,27 @@ static int isnl (const qse_char_t* ptr, qse_size_t len, void* delim)
return (ptr[len-1] == *(qse_char_t*)delim)? 1: 0;
}
qse_ssize_t qse_getline (qse_char_t **buf, qse_size_t *n, QSE_FILE *fp)
qse_ssize_t qse_getline (qse_char_t **buf, qse_size_t *n, QSE_FILE *stream)
{
qse_char_t nl = QSE_T('\n');
return qse_getdelim (buf, n, isnl, &nl, fp);
return qse_getdelim (buf, n, isnl, &nl, stream);
}
qse_ssize_t qse_getdelim (
qse_char_t **buf, qse_size_t *n,
qse_getdelim_t fn, void* fnarg, QSE_FILE *fp)
qse_getdelim_t fn, void* fnarg, QSE_FILE *stream)
{
qse_char_t* b;
qse_size_t capa;
qse_size_t len = 0;
int x;
FILE* fp;
QSE_ASSERT (buf != QSE_NULL);
QSE_ASSERT (n != QSE_NULL);
fp = STREAM_TO_FILE (stream);
b = *buf;
capa = *n;
@ -510,7 +546,7 @@ qse_ssize_t qse_getdelim (
if (b == QSE_NULL) return -2;
}
if (qse_feof(fp))
if (feof(fp))
{
len = (qse_size_t)-1;
goto exit_task;
@ -518,10 +554,10 @@ qse_ssize_t qse_getdelim (
while (1)
{
qse_cint_t c = qse_fgetc(fp);
qse_cint_t c = FGETC (fp);
if (c == QSE_CHAR_EOF)
{
if (qse_ferror(fp))
if (ferror(fp))
{
len = (qse_size_t)-2;
goto exit_task;

View File

@ -108,6 +108,7 @@
#elif defined(vms) || defined(__vms)
/* TODO: */
#define IMPLEMENT_SYSERR_TO_ERRNUM(obj1,obj2) \
static __SYSERRTYPE__(obj1) syserr_to_errnum (unsigned long e) \
{ \
@ -128,10 +129,12 @@
case ENOMEM: return __SYSERRNUM__ (obj2, ENOMEM); \
case EINVAL: return __SYSERRNUM__ (obj2, EINVAL); \
case EACCES: return __SYSERRNUM__ (obj2, EACCES); \
case ENOTDIR: \
case ENOENT: return __SYSERRNUM__ (obj2, ENOENT); \
case EEXIST: return __SYSERRNUM__ (obj2, EEXIST); \
case EINTR: return __SYSERRNUM__ (obj2, EINTR); \
case EPIPE: return __SYSERRNUM__ (obj2, EPIPE); \
case EAGAIN: return __SYSERRNUM__ (obj2, EAGAIN); \
default: return __SYSERRNUM__ (obj2, ESYSERR); \
} \
}

View File

@ -123,6 +123,8 @@ struct server_xtn_t
/* ------------------------------------------------------------------- */
#if defined(_WIN32)
/* TODO: change the error code handling. this is wrong... use WSA error codes .... */
/* sockerr_to_errnum??? */
static qse_httpd_errnum_t syserr_to_errnum (DWORD e)
{
@ -149,33 +151,41 @@ static qse_httpd_errnum_t syserr_to_errnum (DWORD e)
case ERROR_FILE_EXISTS:
return QSE_HTTPD_EEXIST;
case ERROR_BROKEN_PIPE:
return QSE_HTTPD_EPIPE;
default:
return QSE_HTTPD_ESYSERR;
}
}
#elif defined(__OS2__)
static qse_httpd_errnum_t syserr_to_errnum (APIRET e)
static qse_httpd_errnum_t syserr_to_errnum (int e)
{
switch (e)
{
case ERROR_NOT_ENOUGH_MEMORY:
#if defined(SOCENOMEM)
case SOCENOMEM:
return QSE_HTTPD_ENOMEM;
#endif
case ERROR_INVALID_PARAMETER:
case ERROR_INVALID_HANDLE:
case ERROR_INVALID_NAME:
case SOCEINVAL:
return QSE_HTTPD_EINVAL;
case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
case SOCEACCES:
return QSE_HTTPD_EACCES;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
#if defined(SOCENOENT)
case SOCENOENT:
return QSE_HTTPD_ENOENT;
#endif
case ERROR_ALREADY_EXISTS:
#if defined(SOCEEXIST)
case SOCEEXIST:
return QSE_HTTPD_EEXIST;
#endif
case SOCEINTR:
return QSE_HTTPD_EINTR;
default:
return QSE_HTTPD_ESYSERR;
@ -270,6 +280,12 @@ static qse_httpd_errnum_t muxerr_to_errnum (qse_mux_errnum_t e)
case QSE_MUX_EINTR:
return QSE_HTTPD_EINTR;
case QSE_MUX_EPIPE:
return QSE_HTTPD_EPIPE;
case QSE_MUX_EAGAIN:
return QSE_HTTPD_EAGAIN;
default:
return QSE_HTTPD_ESYSERR;
}
@ -297,6 +313,45 @@ static qse_httpd_errnum_t fioerr_to_errnum (qse_fio_errnum_t e)
case QSE_FIO_EINTR:
return QSE_HTTPD_EINTR;
case QSE_FIO_EPIPE:
return QSE_HTTPD_EPIPE;
case QSE_FIO_EAGAIN:
return QSE_HTTPD_EAGAIN;
default:
return QSE_HTTPD_ESYSERR;
}
}
static qse_httpd_errnum_t direrr_to_errnum (qse_dir_errnum_t e)
{
switch (e)
{
case QSE_DIR_ENOMEM:
return QSE_HTTPD_ENOMEM;
case QSE_DIR_EINVAL:
return QSE_HTTPD_EINVAL;
case QSE_DIR_EACCES:
return QSE_HTTPD_EACCES;
case QSE_DIR_ENOENT:
return QSE_HTTPD_ENOENT;
case QSE_DIR_EEXIST:
return QSE_HTTPD_EEXIST;
case QSE_DIR_EINTR:
return QSE_HTTPD_EINTR;
case QSE_DIR_EPIPE:
return QSE_HTTPD_EPIPE;
case QSE_DIR_EAGAIN:
return QSE_HTTPD_EAGAIN;
default:
return QSE_HTTPD_ESYSERR;
}
@ -1312,6 +1367,7 @@ struct dir_t
static int dir_open (qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* handle)
{
dir_t* d;
qse_dir_errnum_t direrrnum;
d = QSE_MMGR_ALLOC (httpd->mmgr, QSE_SIZEOF(*d));
if (d == QSE_NULL)
@ -1328,11 +1384,15 @@ static int dir_open (qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* han
return -1;
}
d->dp = qse_dir_open (httpd->mmgr, 0,
(const qse_char_t*)d->path, QSE_DIR_MBSPATH | QSE_DIR_SORT);
d->dp = qse_dir_open (
httpd->mmgr, 0,
(const qse_char_t*)d->path,
QSE_DIR_MBSPATH | QSE_DIR_SORT,
&direrrnum
);
if (d->dp == QSE_NULL)
{
qse_httpd_seterrnum (httpd, syserr_to_errnum(errno));
qse_httpd_seterrnum (httpd, direrr_to_errnum(direrrnum));
QSE_MMGR_FREE (httpd->mmgr, d->path);
QSE_MMGR_FREE (httpd->mmgr, d);
return -1;