/* read a single line from stdin, replace the '\n' with '\0' */ char * gets(char *buf) { char *ptr = buf; ssize_t n; char *p; Uchar *bufend; rmutex_t *lk; FLOCKFILE(lk, stdin); _SET_ORIENTATION_BYTE(stdin); if (!(stdin->_flag & (_IOREAD | _IORW))) { errno = EBADF; FUNLOCKFILE(lk); return (0); } if (stdin->_base == NULL) { if ((bufend = _findbuf(stdin)) == 0) { FUNLOCKFILE(lk); return (0); } } else bufend = _bufend(stdin); for (;;) /* until get a '\n' */ { if (stdin->_cnt <= 0) /* empty buffer */ { if (__filbuf(stdin) != EOF) { stdin->_ptr--; /* put back the character */ stdin->_cnt++; } else if (ptr == buf) { /* never read anything */ FUNLOCKFILE(lk); return (0); } else break; /* nothing left to read */ } n = stdin->_cnt; if ((p = (char *)memccpy(ptr, (char *)stdin->_ptr, '\n', (size_t)n)) != 0) n = p - ptr; ptr += n; stdin->_cnt -= n; stdin->_ptr += n; if (_needsync(stdin, bufend)) _bufsync(stdin, bufend); if (p != 0) /* found a '\n' */ { ptr--; /* step back over the '\n' */ break; } } *ptr = '\0'; FUNLOCKFILE(lk); return (buf); }
/* * Since we cannot call malloc() or lock any of the ordinary mutexes * while we hold an lmutex_lock(), we open the file outside the lock * and disable locking on the file; the latter is fine because we're * reading the fp only from a single thread. */ static FILE * open_conf(void) { FILE *fp = fopen(__NSW_CONFIG_FILE, "rF"); if (fp != NULL) { if (_findbuf(fp) == NULL) { (void) fclose(fp); return (NULL); } SET_IONOLOCK(fp); } return (fp); }
int _filbuf(FILE *iop) { if ( !(iop->_flag & _IOREAD) ) if (iop->_flag & _IORW) iop->_flag |= _IOREAD; else return(EOF); if (iop->_flag&_IOSTRG) return(EOF); if (iop->_base == NULL) /* get buffer if we don't have one */ _findbuf(iop); /* if this device is a terminal (line-buffered) or unbuffered, then */ /* flush buffers of all line-buffered devices currently writing */ if (iop->_flag & (_IOLBF | _IONBF)) _fwalk(lbfflush); iop->_ptr = iop->_base; iop->_cnt = read(fileno(iop), (char *)iop->_base, (unsigned)((iop->_flag & _IONBF) ? 1 : iop->_bufsiz )); if (--iop->_cnt >= 0) /* success */ return (*iop->_ptr++); if (iop->_cnt != -1) /* error */ iop->_flag |= _IOERR; else { /* end-of-file */ iop->_flag |= _IOEOF; if (iop->_flag & _IORW) iop->_flag &= ~_IOREAD; } iop->_cnt = 0; return (EOF); }
/* fill buffer, return first character or EOF */ int _filbuf(FILE *iop) { ssize_t res; size_t nbyte; Uchar *endbuf; #ifdef _LP64 unsigned int flag; #else unsigned char flag; #endif if (!(iop->_flag & _IOREAD)) /* check, correct permissions */ { if (iop->_flag & _IORW) iop->_flag |= _IOREAD; /* change direction */ /* to read - fseek */ else { errno = EBADF; return (EOF); } } if (iop->_base == 0) { if ((endbuf = _findbuf(iop)) == 0) /* get buffer and */ /* end_of_buffer */ return (EOF); } else endbuf = _bufend(iop); /* * Flush all line-buffered streams before we * read no-buffered or line-buffered input. */ if (iop->_flag & (_IONBF | _IOLBF)) _flushlbf(); /* * Changed the get family fns in Solaris 10 to comply with the * 1990 C Standard and standards based upon it. If the * end-of-file indicator for the stream is set, or if the stream * is at end-of-file, the function will return EOF, and the file * position indicator for the stream will not be advanced. * Additional bytes appended to the file do not clear the EOF * indicator. */ if ((flag = iop->_flag) & _IOEOF) { if (_xpg4_check()) { /* * A previous read() has returned 0 (below), * therefore iop->_cnt was set to 0, and the EOF * indicator was set before returning EOF. Reset * iop->_cnt to 0; it has likely been changed by * a function such as getc(). */ iop->_cnt = 0; return (EOF); } } /* * Fill buffer or read 1 byte for unbuffered, handling any errors. */ iop->_ptr = iop->_base; if (flag & _IONBF) nbyte = 1; else nbyte = endbuf - iop->_base; if ((res = read(GET_FD(iop), (char *)iop->_base, nbyte)) > 0) { iop->_cnt = res - 1; return (*iop->_ptr++); } iop->_cnt = 0; if (res == 0) iop->_flag |= _IOEOF; else if (!cancel_active()) iop->_flag |= _IOERR; return (EOF); }