From okimoto@mrit.mei.co.jp  Thu Jul 30 03:57:15 1998
Received: from mie.mrit.co.jp (mie.mrit.co.jp [210.128.138.3])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id DAA17472
          for <FreeBSD-gnats-submit@freebsd.org>; Thu, 30 Jul 1998 03:57:14 -0700 (PDT)
          (envelope-from okimoto@mrit.mei.co.jp)
Received: by mie.mrit.co.jp (8.8.4/mrit980615) from mrit [133.185.23.3] with ESMTP
	id TAA01747 for <FreeBSD-gnats-submit@freebsd.org>; Thu, 30 Jul 1998 19:57:06 +0900 (JST)
Received: by mrit.mei.co.jp (8.8.4/mrit980615) with ESMTP
	id TAA07108; Thu, 30 Jul 1998 19:57:06 +0900 from [133.185.25.170];
Received: by sango.mrit.mei.co.jp (8.8.8/FreeBSD)
	id TAA01164; Thu, 30 Jul 1998 19:57:05 +0900 (JST)
Message-Id: <199807301057.TAA01164@sango.mrit.mei.co.jp>
Date: Thu, 30 Jul 1998 19:57:05 +0900 (JST)
From: okimoto@mrit.mei.co.jp
Reply-To: okimoto@mrit.mei.co.jp
To: FreeBSD-gnats-submit@freebsd.org
Subject: fclose() locks after over reading by using fread() in pthread
X-Send-Pr-Version: 3.2

>Number:         7443
>Category:       misc
>Synopsis:       fclose() locks after over reading by using fread() in pthread
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 30 04:00:00 PDT 1998
>Closed-Date:    Fri Jul 31 02:05:09 PDT 1998
>Last-Modified:  Fri Jul 31 02:05:21 PDT 1998
>Originator:     Yoshiyuki OKIMOTO
>Release:        FreeBSD 2.2.7-RELEASE i386
>Organization:
Matsushita Research Institute Tokyo, Inc.
>Environment:

FreeBSD 2.2.7-RELEASE #0: Mon Jul 27 09:45:20 JST 1998


>Description:

Using fread() in pthread (-lc_r), if fread() is passwd
too many "size" (bigger than the rest byte of file) in 
2nd, 3rd argument, then fclose() locks.

>How-To-Repeat:

Save below to a file, eg, check.c.
Then comile it like this,

    % cc check.c -lc_r -o check

And execute it.

    % ./check check.c

This will lock at point fclose().


  -- "check.c" -- CUT HERE --

#include <stdio.h>
#include <pthread.h>

void *output_text(void *fp)
{
    int  chk;
    char buff[128];

    while (chk = fread(buff, sizeof (char), 127, fp)) {
	buff[chk] = '\0';
	printf("%s", buff);
    }

}

int main(int argc, char **argv)
{
    FILE	    *fp;		
    pthread_attr_t  attr;		
    pthread_t	    th_num;

    /* open file  */
    if ((fp = fopen(argv[1], "r")) == NULL) {
	perror(argv[1]);
	exit(1);
    }

    /* create thread attribution */
    if (pthread_attr_init(&attr)) {
	fprintf(stderr, "Error in pthread_attr_init \n");
	exit(1);
    }

    /* create new thread */
    if (pthread_create(&th_num, &attr, output_text, (void *)fp)) {
	fprintf(stderr, "Write number thread can't execute. \n");
	exit(1);
    }

    /* wait for thread termination */
    if ( pthread_join(th_num, NULL) ) {
	fprintf(stderr, "Some threads have trouble \n");
	exit(1);
    }

    /*  destroy thread attribution */
    if (pthread_attr_destroy(&attr)) {
	fprintf(stderr, "Error in pthread_attr_destroy \n");
	exit(1);
    }

    fclose(fp);

    return (0);
}

  -- "check.c" -- CUT HERE --



>Fix:
	
This patch will fix the problem.

*** lib/libc/stdio/fread.c.orig	Thu Jul 30 14:35:00 1998
--- lib/libc/stdio/fread.c	Thu Jul 30 14:35:22 1998
***************
*** 83,88 ****
--- 83,91 ----
  		resid -= r;
  		if (__srefill(fp)) {
  			/* no more input: return partial result */
+ #ifdef _THREAD_SAFE
+ 			_thread_funlockfile(fp);
+ #endif
  			return ((total - resid) / size);
  		}
  	}

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: phk 
State-Changed-When: Fri Jul 31 02:05:09 PDT 1998 
State-Changed-Why:  
already fixed in -current 
>Unformatted:
