误将fclose写成pclose引发的惨案
fopen/fclose配对大家都是知道的,popen/pclose可能比较少用。同事写代码时,误写成fopen/pclose,然后在安卓6.0上文件句柄泄露了,然后各种神奇的崩溃。
同时,我很奇怪的发现,我自己的手机一点问题没有,这不科学。那我们就用安卓源码来说话吧。
Android 6.0
int
191 pclose(FILE *iop)
192 {
193 struct pid *cur, *last;
194 int pstat;
195 pid_t pid;
197 _DIAGASSERT(iop != NULL);
199 rwlock_wrlock(&pidlist_lock);
201 /* Find the appropriate file pointer. */
202 for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
203 if (cur->fp == iop)
204 break;
205 if (cur == NULL) {
206 (void)rwlock_unlock(&pidlist_lock);
207 return (-1);
208 }
210 (void)fclose(iop);
212 /* Remove the entry from the linked list. */
213 if (last == NULL)
214 pidlist = cur->next;
215 else
216 last->next = cur->next;
218 (void)rwlock_unlock(&pidlist_lock);
220 do {
221 pid = waitpid(cur->pid, &pstat, 0);
222 } while (pid == -1 && errno == EINTR);
224 free(cur);
226 return (pid == -1 ? -1 : pstat);
227 }
这段代码来自bionic的upstream-netbsd,可见如果在pidlist里找不到的话,就直接返回了,如果找得到就调用fclose+waitpid。
Android master
446 int fclose(FILE* fp) {
447 CHECK_FP(fp);
448 return __FILE_close(fp);
449 }