fixed a bug of not closing inherited file handles in qse_pio_open().

This commit is contained in:
hyung-hwan 2009-06-12 01:44:44 +00:00
parent fd1c529c46
commit 9ee15f2e0a
9 changed files with 218 additions and 67 deletions

104
qse/configure vendored
View File

@ -17220,7 +17220,8 @@ done
for ac_header in time.h sys/time.h utime.h sys/syscall.h
for ac_header in time.h sys/time.h utime.h sys/resource.h sys/syscall.h
do
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@ -18093,6 +18094,107 @@ fi
done
for ac_func in sysconf
do
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
$as_echo_n "checking for $ac_func... " >&6; }
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
$as_echo_n "(cached) " >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $ac_func
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_$ac_func || defined __stub___$ac_func
choke me
#endif
int
main ()
{
return $ac_func ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext
}; then
eval "$as_ac_var=yes"
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -rf conftest.dSYM
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
ac_res=`eval 'as_val=${'$as_ac_var'}
$as_echo "$as_val"'`
{ $as_echo "$as_me:$LINENO: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
as_val=`eval 'as_val=${'$as_ac_var'}
$as_echo "$as_val"'`
if test "x$as_val" = x""yes; then
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
OLDLIBS="$LIBS"
LIBS="$LIBM $LIBS"

View File

@ -88,7 +88,7 @@ AC_SUBST(LIBM, $LIBM)
dnl check header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h])
AC_CHECK_HEADERS([time.h sys/time.h utime.h sys/syscall.h])
AC_CHECK_HEADERS([time.h sys/time.h utime.h sys/resource.h sys/syscall.h])
dnl check data types
AC_CHECK_TYPE([wchar_t],
@ -104,6 +104,7 @@ AC_CHECK_FUNCS([mbsnrtowcs mbsrtowcs wcsnrtombs wcsrtombs])
AC_CHECK_FUNCS([lseek64 stat64 fstat64 ftruncate64])
AC_CHECK_FUNCS([timegm timelocal])
AC_CHECK_FUNCS([utime utimes])
AC_CHECK_FUNCS([sysconf])
OLDLIBS="$LIBS"
LIBS="$LIBM $LIBS"

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h 195 2009-06-10 13:18:25Z hyunghwan.chung $
* $Id: awk.h 196 2009-06-11 07:44:44Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -37,13 +37,13 @@
* stated in the array fnc. If no errors occur, it should print 24.
*/
/** @class qse_awk_t
/** @struct qse_awk_t
* The qse_awk_t type defines an AWK interpreter. The details are hidden as
* it is a complex type susceptible to misuse.
*/
typedef struct qse_awk_t qse_awk_t;
/** @class qse_awk_rtx_t
/** @struct qse_awk_rtx_t
* The qse_awk_rtx_t type defines a runtime context. The details are hidden
* as it is a complex type susceptible to misuse.
*/

View File

@ -1,5 +1,5 @@
/*
* $Id: std.h 195 2009-06-10 13:18:25Z hyunghwan.chung $
* $Id: std.h 196 2009-06-11 07:44:44Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -23,12 +23,13 @@
/** @file
* Standard AWK Interpreter
* @todo
* - console name handling an empty string("") and assignment (v=yyyy)
* - StdAwk ARGV and console name handling
*/
/****e* AWK/qse_awk_parsestd_type_t
* NAME
* qse_awk_parsestd_type_t - define a source type
* SYNOPSIS
/**
* The qse_awk_parsestd_type_t type defines a source script type
*/
enum qse_awk_parsestd_type_t
{
@ -38,13 +39,9 @@ enum qse_awk_parsestd_type_t
QSE_AWK_PARSESTD_STDIO = 3 /* standard input/output */
};
typedef enum qse_awk_parsestd_type_t qse_awk_parsestd_type_t;
/******/
/****s* AWK/qse_awk_parsestd_in_t
* NAME
* qse_awk_parsestd_in_t - define source input
* SYNOPSIS
/**
* The qse_awk_parsestd_in_t type defines a source input.
*/
struct qse_awk_parsestd_in_t
{
@ -58,12 +55,9 @@ struct qse_awk_parsestd_in_t
} u;
};
typedef struct qse_awk_parsestd_in_t qse_awk_parsestd_in_t;
/******/
/****s* AWK/qse_awk_parsestd_out_t
* NAME
* qse_awk_parsestd_out_t - define source output
* SYNOPSIS
/**
* The qse_awk_parsestd_out_t type defines a source output.
*/
struct qse_awk_parsestd_out_t
{
@ -77,38 +71,32 @@ struct qse_awk_parsestd_out_t
} u;
};
typedef struct qse_awk_parsestd_out_t qse_awk_parsestd_out_t;
/******/
#ifdef __cplusplus
extern "C" {
#endif
/****f* AWK/qse_awk_openstd
* NAME
* qse_awk_openstd - create an awk object
* SYNOPSIS
/**
* The qse_awk_openstd() function creates an awk object.
*/
qse_awk_t* qse_awk_openstd (
qse_size_t xtnsize
qse_size_t xtnsize /**< size of extension in bytes */
);
/******/
/****f* AWK/qse_awk_getxtnstd
* NAME
* qse_awk_getxtnstd - get the pointer to extension space
* SYNOPSIS
/**
* The qse_awk_getxtnstd() gets the pointer to extension space.
* Note that you must not call qse_awk_getxtn() for an awk object
* created with qse_awk_openstd().
*/
void* qse_awk_getxtnstd (
qse_awk_t* awk
);
/******/
/****f* AWK/qse_awk_parsestd
* NAME
* qse_awk_parsestd - parse source code
* EXAMPLE
* The following example parses the literal string 'BEGIN { print 10; }' and
* deparses it out to a buffer 'buf'.
/**
* The qse_awk_parsestd() functions parses source script.
* The code below shows how to parse a literal string 'BEGIN { print 10; }'
* and deparses it out to a buffer 'buf'.
* @code
* int n;
* qse_awk_parsestd_in_t in;
* qse_awk_parsestd_out_t out;
@ -122,7 +110,7 @@ void* qse_awk_getxtnstd (
* out.u.cp = buf;
*
* n = qse_awk_parsestd (awk, &in, &out);
* SYNOPSIS
* @endcode
*/
int qse_awk_parsestd (
qse_awk_t* awk,
@ -132,7 +120,6 @@ int qse_awk_parsestd (
/******/
/**
* DESCRIPTION
* The qse_awk_rtx_openstd() function creates a standard runtime context.
* The caller should keep the contents of icf and ocf valid throughout
* the lifetime of the runtime context created. The runtime context

View File

@ -129,6 +129,12 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `sysconf' function. */
#undef HAVE_SYSCONF
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H

View File

@ -1,5 +1,5 @@
/*
* $Id: sed.h 195 2009-06-10 13:18:25Z hyunghwan.chung $
* $Id: sed.h 196 2009-06-11 07:44:44Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -41,7 +41,7 @@
* @todo enhance execution of the l command.
*/
/** @class qse_sed_t
/** @struct qse_sed_t
* The qse_sed_t type defines a stream editor. The structural details are
* hidden as it is a relatively complex data type and fragile to external
* changes. To use a stream editor, you typically can:
@ -177,7 +177,7 @@ typedef struct qse_sed_io_arg_t qse_sed_io_arg_t;
/**
* The qse_sed_io_fun_t type defines an IO handler. An IO handler is called by
* qse_sed_execute().
* qse_sed_exec().
*/
typedef qse_ssize_t (*qse_sed_io_fun_t) (
qse_sed_t* sed,

View File

@ -1,5 +1,5 @@
/*
* $Id: rio.h 75 2009-02-22 14:10:34Z hyunghwan.chung $
* $Id: rio.h 196 2009-06-11 07:44:44Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -44,12 +44,7 @@ int qse_awk_rtx_nextio_read (
int qse_awk_rtx_nextio_write (
qse_awk_rtx_t* run, int out_type, const qse_char_t* name);
int qse_awk_rtx_closeio_read (
qse_awk_rtx_t* run, int in_type, const qse_char_t* name);
int qse_awk_rtx_closeio_write (
qse_awk_rtx_t* run, int out_type, const qse_char_t* name);
int qse_awk_rtx_closeio (qse_awk_rtx_t* run, const qse_char_t* name);
void qse_awk_rtx_cleario (qse_awk_rtx_t* run);
#ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/*
* $Id: pio.c 193 2009-06-08 13:09:01Z hyunghwan.chung $
* $Id: pio.c 196 2009-06-11 07:44:44Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -68,6 +68,18 @@ void qse_pio_close (qse_pio_t* pio)
QSE_MMGR_FREE (pio->mmgr, pio);
}
static int closefile (void* arg, int fd)
{
qse_pio_hnd_t* handle = (qse_pio_hnd_t*)arg;
if (fd != 0 && fd != 1 && fd != 2 &&
fd != handle[0] && fd != handle[1] && fd != handle[2] &&
fd != handle[3] && fd != handle[4] && fd != handle[5])
{
QSE_CLOSE (fd);
}
return 0;
}
qse_pio_t* qse_pio_init (
qse_pio_t* pio, qse_mmgr_t* mmgr, const qse_char_t* cmd, int flags)
{
@ -172,6 +184,7 @@ qse_pio_t* qse_pio_init (
if (pid == 0)
{
/* child */
qse_pio_hnd_t devnull;
qse_mchar_t* mcmd;
extern char** environ;
@ -182,18 +195,48 @@ qse_pio_t* qse_pio_init (
qse_mchar_t buf[64];
#endif
/* TODO: consider if reading from /proc/self/fd is
* a better idea. */
struct rlimit rlim;
int fd;
if (QSE_GETRLIMIT (RLIMIT_NOFILE, &rlim) == -1 ||
rlim.rlim_max == RLIM_INFINITY)
{
#ifdef HAVE_SYSCONF
fd = sysconf (_SC_OPEN_MAX);
if (fd <= 0)
#endif
fd = 1024;
}
else fd = rlim.rlim_max;
while (--fd > 2)
{
if (fd != handle[0] &&
fd != handle[1] &&
fd != handle[2] &&
fd != handle[3] &&
fd != handle[4] &&
fd != handle[5]) QSE_CLOSE (fd);
}
if (flags & QSE_PIO_WRITEIN)
{
/* child should read */
QSE_CLOSE (handle[1]);
handle[1] = QSE_PIO_HND_NIL;
if (QSE_DUP2 (handle[0], 0) == -1) goto child_oops;
QSE_CLOSE (handle[0]);
handle[0] = QSE_PIO_HND_NIL;
}
if (flags & QSE_PIO_READOUT)
{
/* child should write */
QSE_CLOSE (handle[2]);
handle[2] = QSE_PIO_HND_NIL;
if (QSE_DUP2 (handle[3], 1) == -1) goto child_oops;
if (flags & QSE_PIO_ERRTOOUT)
@ -202,12 +245,14 @@ qse_pio_t* qse_pio_init (
}
QSE_CLOSE (handle[3]);
handle[3] = QSE_PIO_HND_NIL;
}
if (flags & QSE_PIO_READERR)
{
/* child should write */
QSE_CLOSE (handle[4]);
handle[4] = QSE_PIO_HND_NIL;
if (QSE_DUP2 (handle[5], 2) == -1) goto child_oops;
if (flags & QSE_PIO_OUTTOERR)
@ -216,6 +261,7 @@ qse_pio_t* qse_pio_init (
}
QSE_CLOSE (handle[5]);
handle[5] = QSE_PIO_HND_NIL;
}
if ((flags & QSE_PIO_INTONUL) ||
@ -440,9 +486,9 @@ oops:
void qse_pio_fini (qse_pio_t* pio)
{
qse_pio_end (pio, QSE_PIO_IN);
qse_pio_end (pio, QSE_PIO_OUT);
qse_pio_end (pio, QSE_PIO_ERR);
qse_pio_end (pio, QSE_PIO_OUT);
qse_pio_end (pio, QSE_PIO_IN);
qse_pio_setflags (pio, QSE_PIO_WAIT_NOBLOCK|QSE_PIO_WAIT_NORETRY, -1);
qse_pio_wait (pio);

View File

@ -1,5 +1,5 @@
/*
* $Id: syscall.h 193 2009-06-08 13:09:01Z hyunghwan.chung $
* $Id: syscall.h 196 2009-06-11 07:44:44Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -45,6 +45,9 @@
#ifdef HAVE_UTIME_H
# include <utime.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif
#if defined(QSE_USE_SYSCALL) && defined(HAVE_SYS_SYSCALL_H)
# include <sys/syscall.h>
@ -222,5 +225,16 @@
# define QSE_UTIMES(file,t) utimes(file,t)
#endif
#ifdef SYS_getrlimit
# define QSE_GETRLIMIT(res,lim) syscall(SYS_getrlimit,res,lim)
#else
# define QSE_GETRLIMIT(res,lim) getrlimit(res,lim)
#endif
#ifdef SYS_setrlimit
# define QSE_SETRLIMIT(res,lim) syscall(SYS_setrlimit,res,lim)
#else
# define QSE_SETRLIMIT(res,lim) setrlimit(res,lim)
#endif
#endif