Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e237d50

Browse files
committed
Add a workaround for file.ftell() to raise IOError for ttys.
ftell(3) on BSD doesn't set errno even for ttys and returns useless values.
1 parent 50f8169 commit e237d50

5 files changed

Lines changed: 97 additions & 1 deletion

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.5 alpha 1?
1212
Core and builtins
1313
-----------------
1414

15+
- Added a workaround for file.tell() to raise IOError when the file
16+
is a tty on every platforms as documented in our library reference.
17+
1518
- Patch #1350409: Work around signal handling bug in Visual Studio 2005.
1619

1720
- Bug #1281408: Py_BuildValue now works correct even with unsigned longs

Objects/fileobject.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,13 @@ _portable_fseek(FILE *fp, Py_off_t offset, int whence)
482482
static Py_off_t
483483
_portable_ftell(FILE* fp)
484484
{
485+
#ifdef HAVE_BROKEN_FTELL
486+
/* ftell doesn't fail for tty fds on FreeBSD and some others */
487+
if (isatty(fileno(fp))) {
488+
errno = ESPIPE;
489+
return -1;
490+
}
491+
#endif
485492
#if !defined(HAVE_LARGEFILE_SUPPORT)
486493
return ftell(fp);
487494
#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8

configure

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#! /bin/sh
2-
# From configure.in Revision: 39267 .
2+
# From configure.in Revision: 41662 .
33
# Guess values for system-dependent variables and create Makefiles.
44
# Generated by GNU Autoconf 2.59 for python 2.5.
55
#
@@ -20118,6 +20118,67 @@ _ACEOF
2011820118

2011920119
fi
2012020120

20121+
echo "$as_me:$LINENO: checking for broken ftell()" >&5
20122+
echo $ECHO_N "checking for broken ftell()... $ECHO_C" >&6
20123+
if test "${ac_cv_broken_ftell+set}" = set; then
20124+
echo $ECHO_N "(cached) $ECHO_C" >&6
20125+
else
20126+
20127+
if test "$cross_compiling" = yes; then
20128+
ac_cv_broken_ftell=no
20129+
else
20130+
cat >conftest.$ac_ext <<_ACEOF
20131+
/* confdefs.h. */
20132+
_ACEOF
20133+
cat confdefs.h >>conftest.$ac_ext
20134+
cat >>conftest.$ac_ext <<_ACEOF
20135+
/* end confdefs.h. */
20136+
20137+
#include <stdio.h>
20138+
int main()
20139+
{
20140+
long val = ftell(stdin);
20141+
if (val != -1)
20142+
exit(0);
20143+
exit(1);
20144+
}
20145+
20146+
_ACEOF
20147+
rm -f conftest$ac_exeext
20148+
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
20149+
(eval $ac_link) 2>&5
20150+
ac_status=$?
20151+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
20152+
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
20153+
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
20154+
(eval $ac_try) 2>&5
20155+
ac_status=$?
20156+
echo "$as_me:$LINENO: \$? = $ac_status" >&5
20157+
(exit $ac_status); }; }; then
20158+
ac_cv_broken_ftell=yes
20159+
else
20160+
echo "$as_me: program exited with status $ac_status" >&5
20161+
echo "$as_me: failed program was:" >&5
20162+
sed 's/^/| /' conftest.$ac_ext >&5
20163+
20164+
( exit $ac_status )
20165+
ac_cv_broken_ftell=no
20166+
fi
20167+
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
20168+
fi
20169+
fi
20170+
20171+
echo "$as_me:$LINENO: result: $ac_cv_broken_ftell" >&5
20172+
echo "${ECHO_T}$ac_cv_broken_ftell" >&6
20173+
if test "$ac_cv_broken_ftell" = yes
20174+
then
20175+
20176+
cat >>confdefs.h <<\_ACEOF
20177+
#define HAVE_BROKEN_FTELL 1
20178+
_ACEOF
20179+
20180+
fi
20181+
2012120182
# Before we can test tzset, we need to check if struct tm has a tm_zone
2012220183
# (which is not required by ISO C or UNIX spec) and/or if we support
2012320184
# tzname[]

configure.in

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,6 +2955,28 @@ then
29552955
[Define if poll() sets errno on invalid file descriptors.])
29562956
fi
29572957

2958+
AC_MSG_CHECKING(for broken ftell())
2959+
AC_CACHE_VAL(ac_cv_broken_ftell, [
2960+
AC_TRY_RUN([
2961+
#include <stdio.h>
2962+
int main()
2963+
{
2964+
long val = ftell(stdin);
2965+
if (val != -1)
2966+
exit(0);
2967+
exit(1);
2968+
}
2969+
],
2970+
ac_cv_broken_ftell=yes,
2971+
ac_cv_broken_ftell=no,
2972+
ac_cv_broken_ftell=no)])
2973+
AC_MSG_RESULT($ac_cv_broken_ftell)
2974+
if test "$ac_cv_broken_ftell" = yes
2975+
then
2976+
AC_DEFINE(HAVE_BROKEN_FTELL, 1,
2977+
[Define if ftell() set errno on tty files.])
2978+
fi
2979+
29582980
# Before we can test tzset, we need to check if struct tm has a tm_zone
29592981
# (which is not required by ISO C or UNIX spec) and/or if we support
29602982
# tzname[]

pyconfig.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
/* Define to 1 if you have the <bluetooth.h> header file. */
4747
#undef HAVE_BLUETOOTH_H
4848

49+
/* Define if ftell() set errno on tty files. */
50+
#undef HAVE_BROKEN_FTELL
51+
4952
/* Define if nice() returns success/failure instead of the new priority. */
5053
#undef HAVE_BROKEN_NICE
5154

0 commit comments

Comments
 (0)