home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sys / next / programm / 5711 < prev    next >
Encoding:
Text File  |  1992-08-20  |  3.9 KB  |  121 lines

  1. Newsgroups: comp.sys.next.programmer
  2. Path: sparky!uunet!usc!sol.ctr.columbia.edu!ira.uka.de!math.fu-berlin.de!news.th-darmstadt.de!alexlehm
  3. From: alexlehm@iti.informatik.th-darmstadt.de (Alexander Lehmann)
  4. Subject: bug in tmpnam fixed
  5. Sender: news@news.th-darmstadt.de (The Usenet-News System)
  6. Message-ID: <1992Aug20.154544.18702@news.th-darmstadt.de>
  7. Date: Thu, 20 Aug 1992 15:45:44 GMT
  8. Nntp-Posting-Host: sun1.iti.informatik.th-darmstadt.de
  9. Organization: TH Darmstadt
  10. Lines: 109
  11.  
  12. I'm new monitoring this group, maybe this has been solved before:
  13.  
  14. There is a bug in the shared system library (Software Release 2.1) that
  15. prevents the tmpnam function from working. It returns only one name for each
  16. process.
  17.  
  18. The correct code should be as follows:
  19.  
  20. -------------------------------------------------------------------------------
  21. #include <string.h>
  22. #include <sys/file.h>
  23. #include <errno.h>
  24.  
  25. #define TMPLATE "/tmp/t.XXXXXX"
  26.  
  27. static char tmpfilename[sizeof(TMPLATE)];
  28.  
  29. char *tmpnam( char *buffer )
  30. {
  31.   int pid=getpid();
  32.   char *p;
  33.   char c;
  34.  
  35.   strcpy(tmpfilename,TMPLATE);
  36.   p=tmpfilename+sizeof(TMPLATE)-1; /* point to NUL char */
  37.   while( *--p=='X' ) {
  38.     *p='0'+pid%10;
  39.     pid /= 10;
  40.   }
  41.  
  42.   p++; /* point to 1st pid digit */
  43.  
  44.   for( c='a' ; !(access(tmpfilename,F_OK)==-1 && errno==ENOENT) ; c++ ) {
  45.     if( c=='z' ) return NULL;
  46.     *p=c;
  47.   }
  48.  
  49.   return buffer ? strcpy( buffer, tmpfilename ) : tmpfilename;
  50. }
  51. -------------------------------------------------------------------------------
  52.  
  53. For some reason the orginal code probably used the following condition:
  54.  
  55. for( c='a' ; access(tmpfilename,F_OK)==-1 && errno!=ENOENT; c++ ) {
  56.  
  57. This condition is false if the file does exist, because access returns 0 and if
  58. the file doesn't exist, since errno is 2.
  59.  
  60. I figured out a small fix in the libaray to change the condition to work, which
  61. can be patched into the shared libaray using the following perl script:
  62.  
  63. -------------------------------------------------------------------------------
  64. #! /usr/local/bin/perl
  65.  
  66. die "libsys_s.B.shlib doesn't exist\n" if( ! -r "libsys_s.B.shlib" );
  67. open(LIB,"+>>libsys_s.B.shlib") || die "Can't access libsys_s.B.shlib\n";
  68.  
  69. seek(LIB,0x4930c,0) || die "Can't seek to patch position\n";
  70.  
  71. ord(getc(LIB))==0x78 &&
  72. ord(getc(LIB))==0xff &&
  73. ord(getc(LIB))==0xb8 &&
  74. ord(getc(LIB))==0x80 &&
  75. ord(getc(LIB))==0x67 &&
  76. ord(getc(LIB))==0xd2 || die "File differs from original version\n";
  77.  
  78. seek(LIB,0x4930c,0) || die "Can't seek to patch position\n";
  79.  
  80. printf LIB "%c%c%c%c%c%c", 0x4a, 0x80, 0x67, 0xde, 0x60, 0xd2;
  81.  
  82. close LIB;
  83. -------------------------------------------------------------------------------
  84.  
  85. to apply this patch, use the following procedure:
  86.  
  87. - copy libsys_s.B.shlib to some working directory
  88. - turn the write permission on
  89. - execute fixtmpnam.pl (it will complain, if something goes wrong)
  90. - remove write permission again
  91. - become root
  92. - cp /usr/shlib/libsys_s.B.shlib to libsys_s.B.shlib.old
  93. - turn write permission on for /usr/shlib/libsys_s.B.shlib
  94. >>> danger here
  95. - move (_don't copy_) libsys_s.B.shlib to /usr/shlib
  96. >>>
  97. - reboot the system
  98.  
  99. after that, programs using tmpnam should work correctly (e.g. cvs rdiff).
  100.  
  101. If you apply this patch, you'll have to be extremely carefull, since, if the
  102. shared library gets broken, the computer won't start.
  103.  
  104. DON'T TRY THIS PATCH, IF YOU DON'T HAVE A 2ND DRIVE TO BOOT FROM.
  105.  
  106. I crashed my system once during this procedure and was only able to recover,
  107. since I had a full os on my 2nd hard drive.
  108.  
  109. If you don't have a 2nd drive to boot from, you are well advised to replace the
  110. linker library with function above. This means that you'll have to relink
  111. programs that use tmpnam, but the procedure is less risky.
  112. You can, of course, break the linker library with this procedure, so be just as
  113. carefull.
  114.  
  115. O.K. I warned you, you're on your own now. Don't come back to me whining.
  116.  
  117.                     bye ... Alexander Lehmann
  118. -- 
  119. Alexander Lehmann                      | "Wopp"
  120. alexlehm@iti.informatik.th-darmstadt.de|         -  ( THHGTTG Pt.3 )
  121.