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 do
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` 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 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@ -18093,6 +18094,107 @@ fi
done 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" OLDLIBS="$LIBS"
LIBS="$LIBM $LIBS" LIBS="$LIBM $LIBS"

View File

@ -88,7 +88,7 @@ AC_SUBST(LIBM, $LIBM)
dnl check header files. dnl check header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h]) 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 dnl check data types
AC_CHECK_TYPE([wchar_t], 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([lseek64 stat64 fstat64 ftruncate64])
AC_CHECK_FUNCS([timegm timelocal]) AC_CHECK_FUNCS([timegm timelocal])
AC_CHECK_FUNCS([utime utimes]) AC_CHECK_FUNCS([utime utimes])
AC_CHECK_FUNCS([sysconf])
OLDLIBS="$LIBS" OLDLIBS="$LIBS"
LIBS="$LIBM $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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -37,13 +37,13 @@
* stated in the array fnc. If no errors occur, it should print 24. * 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 * The qse_awk_t type defines an AWK interpreter. The details are hidden as
* it is a complex type susceptible to misuse. * it is a complex type susceptible to misuse.
*/ */
typedef struct qse_awk_t qse_awk_t; 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 * The qse_awk_rtx_t type defines a runtime context. The details are hidden
* as it is a complex type susceptible to misuse. * 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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -23,12 +23,13 @@
/** @file /** @file
* Standard AWK Interpreter * 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 * The qse_awk_parsestd_type_t type defines a source script type
* qse_awk_parsestd_type_t - define a source type
* SYNOPSIS
*/ */
enum qse_awk_parsestd_type_t enum qse_awk_parsestd_type_t
{ {
@ -38,13 +39,9 @@ enum qse_awk_parsestd_type_t
QSE_AWK_PARSESTD_STDIO = 3 /* standard input/output */ QSE_AWK_PARSESTD_STDIO = 3 /* standard input/output */
}; };
typedef enum qse_awk_parsestd_type_t qse_awk_parsestd_type_t; typedef enum qse_awk_parsestd_type_t qse_awk_parsestd_type_t;
/******/
/**
/****s* AWK/qse_awk_parsestd_in_t * The qse_awk_parsestd_in_t type defines a source input.
* NAME
* qse_awk_parsestd_in_t - define source input
* SYNOPSIS
*/ */
struct qse_awk_parsestd_in_t struct qse_awk_parsestd_in_t
{ {
@ -58,12 +55,9 @@ struct qse_awk_parsestd_in_t
} u; } u;
}; };
typedef struct qse_awk_parsestd_in_t qse_awk_parsestd_in_t; typedef struct qse_awk_parsestd_in_t qse_awk_parsestd_in_t;
/******/
/****s* AWK/qse_awk_parsestd_out_t /**
* NAME * The qse_awk_parsestd_out_t type defines a source output.
* qse_awk_parsestd_out_t - define source output
* SYNOPSIS
*/ */
struct qse_awk_parsestd_out_t struct qse_awk_parsestd_out_t
{ {
@ -77,52 +71,46 @@ struct qse_awk_parsestd_out_t
} u; } u;
}; };
typedef struct qse_awk_parsestd_out_t qse_awk_parsestd_out_t; typedef struct qse_awk_parsestd_out_t qse_awk_parsestd_out_t;
/******/
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/****f* AWK/qse_awk_openstd /**
* NAME * The qse_awk_openstd() function creates an awk object.
* qse_awk_openstd - create an awk object
* SYNOPSIS
*/ */
qse_awk_t* qse_awk_openstd ( 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 * The qse_awk_getxtnstd() gets the pointer to extension space.
* qse_awk_getxtnstd - get the pointer to extension space * Note that you must not call qse_awk_getxtn() for an awk object
* SYNOPSIS * created with qse_awk_openstd().
*/ */
void* qse_awk_getxtnstd ( void* qse_awk_getxtnstd (
qse_awk_t* awk qse_awk_t* awk
); );
/******/
/****f* AWK/qse_awk_parsestd /**
* NAME * The qse_awk_parsestd() functions parses source script.
* qse_awk_parsestd - parse source code * The code below shows how to parse a literal string 'BEGIN { print 10; }'
* EXAMPLE * and deparses it out to a buffer 'buf'.
* The following example parses the literal string 'BEGIN { print 10; }' and * @code
* deparses it out to a buffer 'buf'. * int n;
* int n; * qse_awk_parsestd_in_t in;
* qse_awk_parsestd_in_t in; * qse_awk_parsestd_out_t out;
* qse_awk_parsestd_out_t out; * qse_char_t buf[1000];
* qse_char_t buf[1000];
* *
* qse_memset (buf, QSE_T(' '), QSE_COUNTOF(buf)); * qse_memset (buf, QSE_T(' '), QSE_COUNTOF(buf));
* buf[QSE_COUNTOF(buf)-1] = QSE_T('\0'); * buf[QSE_COUNTOF(buf)-1] = QSE_T('\0');
* in.type = QSE_AWK_PARSESTD_CP; * in.type = QSE_AWK_PARSESTD_CP;
* in.u.cp = QSE_T("BEGIN { print 10; }"); * in.u.cp = QSE_T("BEGIN { print 10; }");
* out.type = QSE_AWK_PARSESTD_CP; * out.type = QSE_AWK_PARSESTD_CP;
* out.u.cp = buf; * out.u.cp = buf;
* *
* n = qse_awk_parsestd (awk, &in, &out); * n = qse_awk_parsestd (awk, &in, &out);
* SYNOPSIS * @endcode
*/ */
int qse_awk_parsestd ( int qse_awk_parsestd (
qse_awk_t* awk, 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 qse_awk_rtx_openstd() function creates a standard runtime context.
* The caller should keep the contents of icf and ocf valid throughout * The caller should keep the contents of icf and ocf valid throughout
* the lifetime of the runtime context created. The runtime context * 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. */ /* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H #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. */ /* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H #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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -41,7 +41,7 @@
* @todo enhance execution of the l command. * @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 * 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 * hidden as it is a relatively complex data type and fragile to external
* changes. To use a stream editor, you typically can: * 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 * 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) ( typedef qse_ssize_t (*qse_sed_io_fun_t) (
qse_sed_t* sed, 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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -44,12 +44,7 @@ int qse_awk_rtx_nextio_read (
int qse_awk_rtx_nextio_write ( int qse_awk_rtx_nextio_write (
qse_awk_rtx_t* run, int out_type, const qse_char_t* name); 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); 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); void qse_awk_rtx_cleario (qse_awk_rtx_t* run);
#ifdef __cplusplus #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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -68,6 +68,18 @@ void qse_pio_close (qse_pio_t* pio)
QSE_MMGR_FREE (pio->mmgr, 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* qse_pio_init (
qse_pio_t* pio, qse_mmgr_t* mmgr, const qse_char_t* cmd, int flags) 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) if (pid == 0)
{ {
/* child */ /* child */
qse_pio_hnd_t devnull; qse_pio_hnd_t devnull;
qse_mchar_t* mcmd; qse_mchar_t* mcmd;
extern char** environ; extern char** environ;
@ -182,18 +195,48 @@ qse_pio_t* qse_pio_init (
qse_mchar_t buf[64]; qse_mchar_t buf[64];
#endif #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) if (flags & QSE_PIO_WRITEIN)
{ {
/* child should read */ /* child should read */
QSE_CLOSE (handle[1]); QSE_CLOSE (handle[1]);
handle[1] = QSE_PIO_HND_NIL;
if (QSE_DUP2 (handle[0], 0) == -1) goto child_oops; if (QSE_DUP2 (handle[0], 0) == -1) goto child_oops;
QSE_CLOSE (handle[0]); QSE_CLOSE (handle[0]);
handle[0] = QSE_PIO_HND_NIL;
} }
if (flags & QSE_PIO_READOUT) if (flags & QSE_PIO_READOUT)
{ {
/* child should write */ /* child should write */
QSE_CLOSE (handle[2]); QSE_CLOSE (handle[2]);
handle[2] = QSE_PIO_HND_NIL;
if (QSE_DUP2 (handle[3], 1) == -1) goto child_oops; if (QSE_DUP2 (handle[3], 1) == -1) goto child_oops;
if (flags & QSE_PIO_ERRTOOUT) if (flags & QSE_PIO_ERRTOOUT)
@ -201,13 +244,15 @@ qse_pio_t* qse_pio_init (
if (QSE_DUP2 (handle[3], 2) == -1) goto child_oops; if (QSE_DUP2 (handle[3], 2) == -1) goto child_oops;
} }
QSE_CLOSE (handle[3]); QSE_CLOSE (handle[3]);
handle[3] = QSE_PIO_HND_NIL;
} }
if (flags & QSE_PIO_READERR) if (flags & QSE_PIO_READERR)
{ {
/* child should write */ /* child should write */
QSE_CLOSE (handle[4]); QSE_CLOSE (handle[4]);
handle[4] = QSE_PIO_HND_NIL;
if (QSE_DUP2 (handle[5], 2) == -1) goto child_oops; if (QSE_DUP2 (handle[5], 2) == -1) goto child_oops;
if (flags & QSE_PIO_OUTTOERR) if (flags & QSE_PIO_OUTTOERR)
@ -216,6 +261,7 @@ qse_pio_t* qse_pio_init (
} }
QSE_CLOSE (handle[5]); QSE_CLOSE (handle[5]);
handle[5] = QSE_PIO_HND_NIL;
} }
if ((flags & QSE_PIO_INTONUL) || if ((flags & QSE_PIO_INTONUL) ||
@ -440,9 +486,9 @@ oops:
void qse_pio_fini (qse_pio_t* pio) 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_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_setflags (pio, QSE_PIO_WAIT_NOBLOCK|QSE_PIO_WAIT_NORETRY, -1);
qse_pio_wait (pio); 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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -45,6 +45,9 @@
#ifdef HAVE_UTIME_H #ifdef HAVE_UTIME_H
# include <utime.h> # include <utime.h>
#endif #endif
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif
#if defined(QSE_USE_SYSCALL) && defined(HAVE_SYS_SYSCALL_H) #if defined(QSE_USE_SYSCALL) && defined(HAVE_SYS_SYSCALL_H)
# include <sys/syscall.h> # include <sys/syscall.h>
@ -222,5 +225,16 @@
# define QSE_UTIMES(file,t) utimes(file,t) # define QSE_UTIMES(file,t) utimes(file,t)
#endif #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 #endif