home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / unix / programm / 4033 < prev    next >
Encoding:
Text File  |  1992-07-31  |  5.1 KB  |  198 lines

  1. Newsgroups: comp.unix.programmer
  2. Path: sparky!uunet!uunet.ca!geac!r-node!pseudo!mjn
  3. From: mjn@pseudo.uucp (Murray Nesbitt)
  4. Subject: Re: I am stumped on this one!!!
  5. Organization: Private system in Toronto, ON
  6. Date: Fri, 31 Jul 1992 12:19:58 GMT
  7. Message-ID: <MJN.92Jul31041958@pseudo.uucp>
  8. In-Reply-To: rajeev@cbnewsf.cb.att.com's message of Fri, 24 Jul 1992 20:49:44 GMT
  9. References: <1992Jul24.204944.18516@cbfsb.cb.att.com>
  10. Sender: mjn@pseudo.uucp (Murray Nesbitt)
  11. Lines: 185
  12.  
  13.  
  14. In article <1992Jul24.204944.18516@cbfsb.cb.att.com> rajeev@cbnewsf.cb.att.com (rajeev.dolas) writes:
  15.  
  16. >    I have included a function from my code which doesn't work on a Sun
  17. >    (690 w/ 4.1.2) but works on an Amdahl and I can't figure out why. 
  18.  
  19. I can't figure out why it works on the Amdahl either. :-)
  20.  
  21. >#include <stdio.h>
  22.  
  23. You should also #include <string.h> and <stdlib.h> for the string and
  24. memory functions you call below.
  25.  
  26. >
  27. >/* I have deleted lots of stuff to keep it simple for netters */
  28. >parse_conf(f2)
  29. >int f2;
  30. >{
  31. >
  32. >    char fname[80], ch, cmp[80];
  33. >    char pars_wbuf[128];
  34. >    char *pbuf;
  35. >    char *cp_line;
  36. >    char *tmp_line;
  37. >    char *var, *getenv();
  38. >    int comp, he;
  39. >    int parse_ret;
  40. >    int fd;
  41. >    FILE *fp1, *fp2;
  42. >
  43. >    strcpy(fname, "/qsun/h5/raj/progs/acs/config/Star3/072392");
  44.  
  45. You should probably just
  46.  
  47.     #define FNAME "/qsun/h5/raj/progs/acs/config/Star3/072392"
  48.  
  49. then your compiler would have prevented you from making the horrific
  50. mistake you make below (and it's much cheaper than calling strcpy()
  51. each time).
  52.  
  53. >
  54. >    umask(0);
  55. >    umask(066);
  56.  
  57. Just out of curiosity, why two calls to umask()?  You should also
  58. provide a declaration for umask().
  59.  
  60. >    if((fp1 = fopen(fname, "w")) == NULL) 
  61. >    {
  62. >        if((fp1 = fopen(fname, "w+")) == NULL)
  63.  
  64. If fopen() fails with mode "w", why would you think it might be
  65. successful with mode "w+"?
  66.  
  67. >        printf("Cannot open fp1 in parse_conf()\n");
  68. >        return(-78);
  69. >    }
  70. >
  71. >    /** f2 was opened in another function with "w" and data was written */
  72. >    if((fp2 = fdopen(f2, "r")) == NULL)
  73. >    {
  74. >        printf("Cannot open fp2 in parse_conf()\n");
  75. >        return(-78);
  76. >    }
  77. >
  78. >    /* As data was written to this file before, I must do a fseek */
  79. >    if((he = fseek(fp2, 0L, 0)) < 0)
  80.  
  81. fseek() can return a *positive* value on failure so the comparison
  82. should be against zero.  Also, the mode argument to fseek() should be
  83. SEEK_SET.  Personally, I'd use rewind() if you actually *needed* to
  84. position the file pointer here, which you don't.
  85.  
  86. >    {
  87. >        printf("fseek error in parse_conf()\n");
  88. >        return(-78);
  89. >    }
  90. >
  91. >    /* str_comp is my function which returns -1 if match is not found */
  92. >    while((fgets(pars_wbuf, 80, fp2) != NULL) &&
  93.  
  94. Rather than hard-coding the value 80 into fgets(), use sizeof() unless
  95. you actually *want* fewer characters than your array can hold.
  96.  
  97. >        ((parse_ret = str_comp(cmp, pars_wbuf)) != 0))
  98. >    {
  99. >        pars_wbuf[strlen(pars_wbuf)] = '\0';
  100.  
  101. Rather than having multiple calls to strlen(), call it once and store
  102. its return value in a variable of type size_t for later use.
  103.  
  104. >        pbuf = pars_wbuf;
  105. >        cp_line = (char *)malloc(sizeof(strlen(pars_wbuf)));
  106.  
  107. Check for failure of the malloc(), and replace
  108. ``sizeof(strlen(pars_wbuf))'' (which is not what you want anyways)
  109. with (the size_t you saved above + 1).
  110.  
  111. >        strcpy(cp_line, "\0");
  112.  
  113. Use *cp_line = '\0' to achieve the same effect more efficiently.
  114.  
  115. >        tmp_line = cp_line;
  116. >
  117. >        if((comp = line_comp(pars_wbuf)) == 0)
  118. >            ;
  119. >        else 
  120. >        {
  121. >            /* Traverse thru pbuf, skip "
  122. >            while(*pbuf != '\0')
  123. >            {
  124. >                if(*pbuf != 0x0D)
  125. >                {
  126. >                    /* I was writing a char at a time to
  127. >                       the file before. This part works
  128. >                       on Amdahl but not on a sun.    */
  129. >
  130. >                    /**
  131. >                    ch = *pbuf;
  132. >                    fprintf(stdout, "%c", ch); 
  133. >                    if((he = putc(ch, fp1)) < 0)
  134. >                    {
  135. >                         printf("pars_conf: Write error\n");
  136. >                        return(-13);
  137. >                    }
  138. >                    **/
  139. >
  140. >                    /* Now I save it to a buffer */
  141. >                    *cp_line++ = *pbuf;
  142. >                }
  143. >                *pbuf++;
  144.  
  145. I doubt that *pbuf++ is what you intended - it should be pbuf++;
  146.  
  147. >            }
  148. >            /* If I do a fputs to stdout, it works fine */
  149. >            /**
  150. >            fputs(tmp_line, stdout);
  151. >            fflush(stdout);
  152. >            **/
  153. >
  154. >            /* dbxtool shows the following error on this instr -
  155. >             signal SEGV in malloc at 0xf773634
  156. >             malloc+0x150:    st    %o0, [%15]
  157. >             */
  158. >            fputs(tmp_line, fp1);
  159. >        }
  160. >        free(cp_line);
  161.  
  162. Rather than calling malloc() and free() every time you read a line,
  163. you should just declare another array of char and have cp_line
  164. manipulate it.
  165.  
  166. >    }
  167. >    
  168. >    fclose(fp1);
  169. >
  170. >    
  171. >    if(fname)
  172. >        free(*fname);
  173.  
  174. Ouch!  Trying to free a local array will always get you bitten in the
  175. arse.  And even if it pointed to a free()able area, you definitely
  176. would not want to free *fname.
  177.  
  178. >    if(parse_ret != 0)
  179. >        return(-89);
  180. >
  181.  
  182. Finally, if you're going to return all those wacky values on failure,
  183. you should at least return something meaningful (probably 0) on
  184. success.
  185.  
  186. >}
  187.  
  188. I wouldn't be surprised if your code worked after taking care of these
  189. problems and potential problems, but no guarantees.  The most likely
  190. culprits are 1) the incorrect malloc() of cp_line (which probably
  191. resulted in the corruption of the file pointer fp1, a hypothesis that
  192. is backed up by your ability to fputs() to stderr), and/or 2) the
  193. incorrect free()ing of fname.
  194.  
  195. Murray
  196. -- 
  197. Until my site's in the maps, please reply to "druid!pseudo!mjn".
  198.