*BSD News Article 22688


Return to BSD News archive

Newsgroups: comp.os.386bsd.bugs
Path: sserve!newshost.anu.edu.au!munnari.oz.au!spool.mu.edu!cass.ma02.bull.com!syd.bull.oz.au!melb.bull.oz.au!zen!sjg
From: sjg@zen.void.oz.au (Simon J. Gerraty)
Subject: Re: mktemp() crashes
Organization: Zen programming...
References: <CF7snJ.ID9@dvorak.amd.com> <1993Oct21.093717.2658@zen.void.oz.au>
Message-ID: <1993Oct21.120854.2900@zen.void.oz.au>
Date: Thu, 21 Oct 1993 12:08:54 GMT
Lines: 149


helgren@dvorak.amd.com (Matt Helgren) writes:
>	Im trying to use mkmf to get an application compiled but mkmf keeps
>crashing when envoked.  Using gdb I find that its dying in the routine
>mktemp() which is in one of the system libs.  Is there a known bug with mktemp?

sjg@zen.void.oz.au (Simon J. Gerraty) writes:
>There is an incompatability between mktemp()'s implementation, many
>programs use of mktemp() and ANSI-C. 
>Solutions:
>2/	fix mktemp() to use a private static array.

Here is a patch to implement option 2.

Fix:
	The following patch modifes mktemp() to use a private (static)
	buffer which it can safely modify.  

*** lib/libc/stdio/mktemp.c~	Wed May  8 06:43:49 1991
--- lib/libc/stdio/mktemp.c	Thu Oct 21 21:50:55 1993
***************
*** 40,47 ****
  #include <fcntl.h>
  #include <errno.h>
  #include <stdio.h>
  
! static int _gettemp();
  
  mkstemp(path)
  	char *path;
--- 40,48 ----
  #include <fcntl.h>
  #include <errno.h>
  #include <stdio.h>
+ #include <string.h>
  
! static char * _gettemp();
  
  mkstemp(path)
  	char *path;
***************
*** 55,73 ****
  mktemp(path)
  	char *path;
  {
! 	return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
  }
  
! static
  _gettemp(path, doopen)
  	char *path;
  	register int *doopen;
  {
  	extern int errno;
  	register char *start, *trv;
  	struct stat sbuf;
  	u_int pid;
  
  	pid = getpid();
  	for (trv = path; *trv; ++trv);		/* extra X's get set to 0's */
  	while (*--trv == 'X') {
--- 56,78 ----
  mktemp(path)
  	char *path;
  {
! 	return _gettemp(path, (int *)NULL);
  }
  
! static char *
  _gettemp(path, doopen)
  	char *path;
  	register int *doopen;
  {
  	extern int errno;
+ 	static char temp_path[256];
  	register char *start, *trv;
  	struct stat sbuf;
  	u_int pid;
  
+ 	path = strncpy(temp_path, path, sizeof (temp_path) - 1);
+ 	temp_path[sizeof (temp_path) - 1] = '\0';
+ 	
  	pid = getpid();
  	for (trv = path; *trv; ++trv);		/* extra X's get set to 0's */
  	while (*--trv == 'X') {
***************
*** 85,94 ****
  		if (*trv == '/') {
  			*trv = '\0';
  			if (stat(path, &sbuf))
! 				return(0);
  			if (!S_ISDIR(sbuf.st_mode)) {
  				errno = ENOTDIR;
! 				return(0);
  			}
  			*trv = '/';
  			break;
--- 90,99 ----
  		if (*trv == '/') {
  			*trv = '\0';
  			if (stat(path, &sbuf))
! 				return((char *) 0);
  			if (!S_ISDIR(sbuf.st_mode)) {
  				errno = ENOTDIR;
! 				return((char *) 0);
  			}
  			*trv = '/';
  			break;
***************
*** 99,115 ****
  		if (doopen) {
  			if ((*doopen =
  			    open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
! 				return(1);
  			if (errno != EEXIST)
! 				return(0);
  		}
  		else if (stat(path, &sbuf))
! 			return(errno == ENOENT ? 1 : 0);
  
  		/* tricky little algorithm for backward compatibility */
  		for (trv = start;;) {
  			if (!*trv)
! 				return(0);
  			if (*trv == 'z')
  				*trv++ = 'a';
  			else {
--- 104,120 ----
  		if (doopen) {
  			if ((*doopen =
  			    open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
! 				return(path);
  			if (errno != EEXIST)
! 				return((char *) 0);
  		}
  		else if (stat(path, &sbuf))
! 			return(errno == ENOENT ? path : (char *) 0);
  
  		/* tricky little algorithm for backward compatibility */
  		for (trv = start;;) {
  			if (!*trv)
! 				return((char *) 0);
  			if (*trv == 'z')
  				*trv++ = 'a';
  			else {
-- 
Simon J. Gerraty        <sjg@zen.void.oz.au>

#include <disclaimer>   /* imagine something _very_ witty here */