Exemple #1
0
static void
init(void)
{
    if (ioctl(0, VT_GETACTIVE, &cur_info.active_vty) == -1)
        errc(1, errno, "getting active vty");

    cur_info.console_info.size = sizeof(cur_info.console_info);

    if (ioctl(0, CONS_GETINFO, &cur_info.console_info) == -1)
        errc(1, errno, "getting console information");

    if (ioctl(0, GIO_SCRNMAP, &cur_info.screen_map) == -1)
        errc(1, errno, "getting screen map");

    if (ioctl(0, CONS_GET, &cur_info.video_mode_number) == -1)
        errc(1, errno, "getting video mode number");

    cur_info.video_mode_info.vi_mode = cur_info.video_mode_number;

    if (ioctl(0, CONS_MODEINFO, &cur_info.video_mode_info) == -1)
        errc(1, errno, "getting video mode parameters");

    normal_fore_color = cur_info.console_info.mv_norm.fore;
    normal_back_color = cur_info.console_info.mv_norm.back;
    revers_fore_color = cur_info.console_info.mv_rev.fore;
    revers_back_color = cur_info.console_info.mv_rev.back;
}
Exemple #2
0
void context::authenticate()
{
    _M_code = pam_authenticate(_M_pamh, 0);
    if(errc(_M_code) != errc::success) throw auth_error(_M_pamh, _M_code);

    _M_code = pam_acct_mgmt(_M_pamh, 0);
    if(errc(_M_code) != errc::success) throw account_error(_M_pamh, _M_code);
}
Exemple #3
0
void context::close_session()
{
    _M_code = pam_close_session(_M_pamh, 0);
    if(errc(_M_code) != errc::success)
    {
        rmcred();
        throw session_error(_M_pamh, _M_code);
    }

    _M_code = rmcred();
    if(errc(_M_code) != errc::success) throw cred_error(_M_pamh, _M_code);
}
Exemple #4
0
void context::open_session()
{
    _M_code = setcred();
    if(errc(_M_code) != errc::success) throw cred_error(_M_pamh, _M_code);

    _M_code = pam_open_session(_M_pamh, 0);
    if(errc(_M_code) != errc::success)
    {
        rmcred();
        throw session_error(_M_pamh, _M_code);
    }
}
Exemple #5
0
void context::insert(pam::item item, const std::string& value)
{
    if(item == pam::item::conv || item == pam::item::fail_delay) throw item_error(_M_pamh, errc::bad_item);

    _M_code = pam_set_item(_M_pamh, static_cast<int>(item), value.data());
    if(errc(_M_code) != errc::success) throw item_error(_M_pamh, _M_code);
}
Exemple #6
0
static void
show_adapter_info(void)
{
    struct video_adapter_info ad;

    ad.va_index = 0;

    if (ioctl(0, CONS_ADPINFO, &ad) == -1) {
        revert();
        errc(1, errno, "obtaining adapter information");
    }

    printf("fb%d:\n", ad.va_index);
    printf("    %.*s%d, type:%s%s (%d), flags:0x%x\n",
           (int)sizeof(ad.va_name), ad.va_name, ad.va_unit,
           (ad.va_flags & V_ADP_VESA) ? "VESA " : "",
           adapter_name(ad.va_type), ad.va_type, ad.va_flags);
    printf("    initial mode:%d, current mode:%d, BIOS mode:%d\n",
           ad.va_initial_mode, ad.va_mode, ad.va_initial_bios_mode);
    printf("    frame buffer window:0x%x, buffer size:0x%zx\n",
           ad.va_window, ad.va_buffer_size);
    printf("    window size:0x%zx, origin:0x%x\n",
           ad.va_window_size, ad.va_window_orig);
    printf("    display start address (%d, %d), scan line width:%d\n",
           ad.va_disp_start.x, ad.va_disp_start.y, ad.va_line_width);
    printf("    reserved:0x%x\n", ad.va_unused0);
}
Exemple #7
0
wchar_t *
prepkey(const char *string, wchar_t termchar)
{
	const char *readp;
	wchar_t *key, *writep;
	wchar_t ch;
	size_t clen;

	/*
	 * Reformat search string and convert to wide character representation
	 * to avoid doing it multiple times later.
	 */
	if ((key = malloc(sizeof(wchar_t) * (strlen(string) + 1))) == NULL)
		err(2, NULL);
	readp = string;
	writep = key;
	while ((clen = mbrtowc(&ch, readp, MB_LEN_MAX, NULL)) != 0) {
		if (clen == (size_t)-1 || clen == (size_t)-2)
			errc(2, EILSEQ, NULL);
		if (fflag)
			ch = towlower(ch);
		if (!dflag || iswalnum(ch))
			*writep++ = ch;
		readp += clen;
	}
	*writep = L'\0';
	if (termchar != L'\0' && (writep = wcschr(key, termchar)) != NULL)
		*++writep = L'\0';
	return (key);
}
Exemple #8
0
int
open_score_file(void)
{
	mode_t old_mode;
	char *home;
	char scorefile[PATH_MAX];
	int ret;
	int score_fd;

	home = getenv("HOME");
	if (home == NULL || *home == '\0')
		err(1, "getenv");
	ret = snprintf(scorefile, sizeof(scorefile), "%s/%s", home,
	    ".atc.scores");
	if (ret < 0 || ret >= PATH_MAX)
		errc(1, ENAMETOOLONG, "%s/%s", home, ".atc.scores");

	old_mode = umask(0);
	score_fd = open(scorefile, O_CREAT|O_RDWR, 0644);
	if (score_fd < 0)
		err(1, "open");
	/*
	 * This is done to take advantage of stdio, while still 
	 * allowing a O_CREAT during the open(2) of the log file.
	 */
	score_fp = fdopen(score_fd, "r+");
	if (score_fp == NULL)
		err(1, "fdopen");
	umask(old_mode);
	return (0);
}
Exemple #9
0
int
main(void)
{
	char sfn[24];
	FILE *sfp;
	int fd, i;

	strlcpy(sfn, "/tmp/barnacles.XXXXXXXX", sizeof(sfn));
	if ((fd = mkstemp(sfn)) == -1 ||
	    (sfp = fdopen(fd, "w+")) == NULL) {
		int saved_errno = errno;
		if (fd != -1) {
			unlink(sfn);
			close(fd);
		}
		errc(1, saved_errno, "could not open temporary file");
	}

	for (i = 0; i < 4096 * THREAD_COUNT; i++)
		if (fwrite(TEXT_N, sizeof(char), strlen(TEXT_N), sfp) == 0)
			err(1, "Could not populate test file");

	run_threads(fgetln_thread, sfp);

	unlink(sfn);
	close(fd);

	exit(0);
}
Exemple #10
0
void *work(void *arg)
{
    int count = (int)(intptr_t)arg;
    int i;
    int ret;
    pid_t pid;

    for (i=0; i < count; i++) {
        ret = posix_spawn(&pid, newargv[0], NULL, NULL, newargv, environ);
        if (ret != 0) {
            errc(1, ret, "posix_spawn(%s)", newargv[0]);
        }
        
        while (-1 == waitpid(pid, &ret, 0)) {
            if (errno != EINTR) {
                err(1, "waitpid(%d)", pid);
            }
        }
        
        if (WIFSIGNALED(ret)) {
            errx(1, "process exited with signal %d", WTERMSIG(ret));
        } else if (WIFSTOPPED(ret)) {
            errx(1, "process stopped with signal %d", WSTOPSIG(ret));
        } else if (WIFEXITED(ret)) {
            if (WEXITSTATUS(ret) != 42) {
                errx(1, "process exited with unexpected exit code %d", WEXITSTATUS(ret));
            }
        } else {
            errx(1, "unknown exit condition %x", ret);
        }
    }

    return NULL;
}
Exemple #11
0
static char *
mbssep(char **stringp, const wchar_t *delim)
{
	char *s, *tok;
	const wchar_t *spanp;
	wchar_t c, sc;
	size_t n;

	if ((s = *stringp) == NULL)
		return (NULL);
	for (tok = s;;) {
		n = mbrtowc(&c, s, MB_LEN_MAX, NULL);
		if (n == (size_t)-1 || n == (size_t)-2)
			errc(1, EILSEQ, NULL);	/* XXX */
		s += n;
		spanp = delim;
		do {
			if ((sc = *spanp++) == c) {
				if (c == 0)
					s = NULL;
				else
					s[-n] = '\0';
				*stringp = s;
				return (tok);
			}
		} while (sc != 0);
	}
}
Exemple #12
0
int
main(void)
{
	char sfn[24];
	char buf[sizeof(TEXT)];
	FILE *sfp;
	int fd;

	strlcpy(sfn, "/tmp/barnacles.XXXXXXXX", sizeof(sfn));
	if ((fd = mkstemp(sfn)) == -1 ||
	    (sfp = fdopen(fd, "w+")) == NULL) {
		int saved_errno = errno;
		if (fd != -1) {
			unlink(sfn);
			close(fd);
		}
		errc(1, saved_errno, "could not open temporary file");
	}

	run_threads(fwrite_thread, sfp);

	while (fread(buf, sizeof(char), strlen(TEXT), sfp))	/* verify */
		if (strncmp(buf, TEXT, sizeof(TEXT)))
			err(1, "Thread writes were not atomic!!!");

	unlink(sfn);
	close(fd);

	exit(0);
}
Exemple #13
0
void context::erase(pam::item item)
{
    if(item == pam::item::conv || item == pam::item::fail_delay) throw item_error(_M_pamh, errc::bad_item);

    _M_code = pam_set_item(_M_pamh, static_cast<int>(item), nullptr);
    if(errc(_M_code) != errc::success) throw item_error(_M_pamh, _M_code);
}
Exemple #14
0
int
fcopy(char *src, char *dst, mode_t mode)
{
	int		ifd, ofd;
	u_int8_t	buf[BUFSIZ];
	ssize_t		r;

	if ((ifd = open(src, O_RDONLY)) == -1)
		err(1, "open %s", src);

	if ((ofd = open(dst, O_WRONLY|O_CREAT|O_TRUNC, mode)) == -1) {
		int saved_errno = errno;
		close(ifd);
		errc(1, saved_errno, "open %s", dst);
	}

	while ((r = read(ifd, buf, sizeof(buf))) > 0) {
		write(ofd, buf, r);
	}

	close(ofd);
	close(ifd);

	return (r == -1);
}
Exemple #15
0
context::context(const std::string& service, const std::string& username)
{
    auto s = app::clone(service), u = username.size() ? app::clone(username) : nullptr;
    pam_conv conv = { despatch, this };

    _M_code = pam_start(s.get(), u.get(), &conv, &_M_pamh);
    if(errc(_M_code) != errc::success) throw pam_error(_M_code);
}
Exemple #16
0
static void
clear_history(void)
{
    if (ioctl(0, CONS_CLRHIST) == -1) {
        revert();
        errc(1, errno, "clearing history buffer");
    }
}
Exemple #17
0
static void
load_default_vt4font(void)
{
	if (ioctl(0, PIO_VFONT_DEFAULT) == -1) {
		revert();
		errc(1, errno, "loading default vt font");
	}
}
Exemple #18
0
char ccom(char c){
    if( c == '*' )
        return cBlockComment();
    if( c == '/' )
        return cLineComment();
    else
        errc("not a comment start /", c);
    return c;
}
Exemple #19
0
char cquotes(char q){
    if( q == '\'' )
        return cCharConst();
    if( q == '\"' )
        return cString();
    else
        errc("not a quotes start", q);
    return q;
}
Exemple #20
0
void context::set_conv()
{
    if(_M_pamh)
    {
        pam_conv conv = { despatch, this };

        _M_code = pam_set_item(_M_pamh, static_cast<int>(item::conv), &conv);
        if(errc(_M_code) != errc::success) throw item_error(_M_pamh, _M_code);
    }
}
Exemple #21
0
void
reorder_syms(Elf_Ehdr * ehdr, Elf_Shdr * symsect,
    Elf_Sym * symtab, int symtabsize, int symtabsecnum)
{
	int             i;
	int             nsyms;
	int             cursym;
	Elf_Sym        *tmpsymtab;
	Symmap         *symmap;


	nsyms = symtabsize / sizeof(Elf_Sym);

	tmpsymtab = (Elf_Sym *) calloc(1, symtabsize);
	symmap = (Symmap *) calloc(nsyms, sizeof(Symmap));
	if (!tmpsymtab || !symmap)
		errc(5, ENOMEM, "calloc");

	bcopy(symtab, tmpsymtab, symtabsize);

	cursym = 1;
	for (i = 1; i < nsyms; i++) {
		if ((tmpsymtab[i].st_info & 0xf0) == 0x00) {
#ifdef DEBUG
			printf("copying  l o%d n%d <%s>\n", i, cursym,
			    get_str(tmpsymtab[i].st_name));
#endif
			bcopy(&(tmpsymtab[i]), &(symtab[cursym]),
			    sizeof(Elf_Sym));
			symmap[i] = cursym;
			cursym++;
		}
	}
	symsect->sh_info = cursym;
	for (i = 1; i < nsyms; i++) {
		if ((tmpsymtab[i].st_info & 0xf0) != 0x00) {
#ifdef DEBUG
			printf("copying nl o%d n%d <%s>\n", i, cursym,
			    get_str(tmpsymtab[i].st_name));
#endif
			bcopy(&(tmpsymtab[i]), &(symtab[cursym]),
			    sizeof(Elf_Sym));
			symmap[i] = cursym;
			cursym++;
		}
	}
	if (cursym != nsyms) {
		printf("miscounted symbols somewhere c %d n %d \n",
		    cursym, nsyms);
		exit(5);
	}
	renum_reloc_syms(ehdr, symmap, symtabsecnum);
	free(tmpsymtab);
	free(symmap);
}
Exemple #22
0
char cBlockComment(){
    char e, f;
    e = gc();
    if( e == EOF )
        return e;
    if( e == '*' ){
        f = gc();
        if( f == EOF || f == '/')
            return f;
    }else{
        while ( (f = gc() ) != EOF)
        {
            if ( e == '*' && f == '/'){
                return f;
            }else {
                if( e =='/' && f == '*' )
                    printf("%ld:%ld: warning: /* in block comment\n",
                            crow, ccol );
                e = f;
            }
        }
        return EOF;
    }

    while ( ( e = gc() ) != EOF && e != '*')
        ;

    if ( e == '*'){
        if((f = gc()) != EOF){
            if ( f == '/')
                return '/';
            else
                return cBlockComment();
        }else{
            errc("\tbroken block comment at EOF", ' ');
            return EOF;
        }
    }else{
        errc("\tbroken block comment at EOF", ' ');
        return EOF;
    }
}
Exemple #23
0
std::string context::get(pam::item item, bool* found)
{
    if(item == pam::item::conv || item == pam::item::fail_delay) throw item_error(_M_pamh, errc::bad_item);

    const void* x = nullptr;
    _M_code = pam_get_item(_M_pamh, static_cast<int>(item), &x);
    if(errc(_M_code) != errc::success) throw item_error(_M_pamh, _M_code);

    if(found) *found = x;
    return x ? std::string(static_cast<const char*>(x)) : std::string();
}
Exemple #24
0
int
main()
{
	pthread_t tid;
	pid_t pid, rpid;
	int r, status;

	if (signal(SIGHUP, dohup) == SIG_ERR)
		err(1, "signal");

	/* make sure the thread library is fully active */
	if ((r = pthread_create(&tid, NULL, tmain, NULL)))
		errc(1, r, "pthread_create");
	pthread_join(tid, NULL);

	/* make sure kill() and all the symbols in fork() are bound */
	kill(0, 0);
	if ((pid = fork()) <= 0) {
		if (pid == -1)
			err(1, "fork");
		_exit(0);
	}
	if (waitpid(pid, &status, 0) == -1)
		err(1, "waitpid");


	switch(pid = fork()) {
	case -1:
		err(1, "fork");
		break;
	case 0:
		sleep(2);
		_exit(0);
	default:
		kill(pid, SIGHUP);
		sleep(3);
		if ((rpid = waitpid(pid, &status, WNOHANG)) == -1)
			err(1, "waitpid");
		if (rpid == 0) {
			/* took too long */
			kill(pid, SIGKILL);
			if (waitpid(pid, &status, 0) == -1)
				err(1, "waitpid");
		}
		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
			exit(0);
		else if (WIFEXITED(status))
			errx(1, "child exited with status %d",
			    WEXITSTATUS(status));
		else if (WTERMSIG(status) == SIGKILL)
			errx(1, "failed: child hung");
		errx(1, "child killed by signal %d", WTERMSIG(status));
	}
}
Exemple #25
0
int
main(int argc, char **argv)
{
	char	 line[LINE_LENGTH];
	char	*p;
	int	 i, s, s6;

	s = -1;
	s6 = -1;
#ifdef INET
	s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (s == -1 && errno != EAFNOSUPPORT)
		err(1, "can't open IPv4 socket");
#endif
#ifdef INET6
	s6 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
	if (s6 == -1 && errno != EAFNOSUPPORT)
		err(1, "can't open IPv6 socket");
#endif
	if (s == -1 && s6 == -1)
		errc(1, EPROTONOSUPPORT, "can't open socket");

	if (argc < 2) {
		if (isatty(STDIN_FILENO)) {
			printf("multicast membership test program; "
			    "enter ? for list of commands\n");
		}
		do {
			if (fgets(line, sizeof(line), stdin) != NULL) {
				if (line[0] != 'f')
					process_cmd(line, s, s6, stdin);
				else {
					/* Get the filename */
					for (i = 1; isblank(line[i]); i++);
					if ((p = (char*)strchr(line, '\n'))
					    != NULL)
						*p = '\0';
					process_file(&line[i], s, s6);
				}
			}
		} while (!feof(stdin));
	} else {
		for (i = 1; i < argc; i++) {
			process_file(argv[i], s, s6);
		}
	}

	if (s != -1)
		close(s);
	if (s6 != -1)
		close(s6);

	exit (0);
}
Exemple #26
0
int
main(int argc, char *argv[])
{
	struct stat sb;
	int ch, fd, termchar;
	char *back, *file, *front, *string, *p;

	file = _PATH_WORDS;
	termchar = '\0';
	while ((ch = getopt(argc, argv, "dft:")) != -1)
		switch(ch) {
		case 'd':
			dflag = 1;
			break;
		case 'f':
			fflag = 1;
			break;
		case 't':
			termchar = *optarg;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	switch (argc) {
	case 2:				/* Don't set -df for user. */
		string = *argv++;
		file = *argv;
		break;
	case 1:				/* But set -df by default. */
		dflag = fflag = 1;
		string = *argv;
		break;
	default:
		usage();
	}

	if (termchar != '\0' && (p = strchr(string, termchar)) != NULL)
		*++p = '\0';

	if ((fd = open(file, O_RDONLY, 0)) < 0 || fstat(fd, &sb))
		err(2, "%s", file);
	if (sb.st_size > SIZE_T_MAX)
		errc(2, EFBIG, "%s", file);
	if ((front = mmap(NULL,
	    (size_t)sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t)0)) == MAP_FAILED)
		err(2, "%s", file);
	back = front + sb.st_size;
	exit(look(string, front, back));
}
Exemple #27
0
static int
genrange(STR *s, int was_octal)
{
	int stopval, octal;
	char *savestart;
	int n, cnt, *p;
	size_t clen;
	wchar_t wc;

	octal = 0;
	savestart = s->str;
	if (*++s->str == '\\')
		stopval = backslash(s, &octal);
	else {
		clen = mbrtowc(&wc, s->str, MB_LEN_MAX, NULL);
		if (clen == (size_t)-1 || clen == (size_t)-2)
			errc(1, EILSEQ, NULL);
		stopval = wc;
		s->str += clen;
	}
	/*
	 * XXX Characters are not ordered according to collating sequence in
	 * multibyte locales.
	 */
	if (octal || was_octal || MB_CUR_MAX > 1) {
		if (stopval < s->lastch) {
			s->str = savestart;
			return (0);
		}
		s->cnt = stopval - s->lastch + 1;
		s->state = RANGE;
		--s->lastch;
		return (1);
	}
	if (charcoll((const void *)&stopval, (const void *)&(s->lastch)) < 0) {
		s->str = savestart;
		return (0);
	}
	if ((s->set = p = malloc((NCHARS_SB + 1) * sizeof(int))) == NULL)
		err(1, "genrange() malloc");
	for (cnt = 0; cnt < NCHARS_SB; cnt++)
		if (charcoll((const void *)&cnt, (const void *)&(s->lastch)) >= 0 &&
		    charcoll((const void *)&cnt, (const void *)&stopval) <= 0)
			*p++ = cnt;
	*p = OOBCH;
	n = p - s->set;

	s->cnt = 0;
	s->state = SET;
	if (n > 1)
		mergesort(s->set, n, sizeof(*(s->set)), charcoll);
	return (1);
}
Exemple #28
0
int
readscores(int create)
{
	const char	*home;
	const char	*name;
	const char	*modstr;
	int		 modint;
	int		 ret;

	if (create == 0) {
		modint = O_RDONLY;
		modstr = "r";
	} else {
		modint = O_RDWR | O_CREAT;
		modstr = "r+";
	}

	home = getenv("HOME");
	if (home == NULL || *home == '\0')
		err(1, "getenv");

	ret = snprintf(scorepath, sizeof(scorepath), "%s/%s", home,
	    ".snake.scores");
	if (ret < 0 || ret >= PATH_MAX)
		errc(1, ENAMETOOLONG, "%s/%s", home, ".snake.scores");

	rawscores = open(scorepath, modint, 0666);
	if (rawscores < 0) {
		if (create == 0)
			return 0;
		err(1, "cannot open %s", scorepath);
	}
	if ((sf = fdopen(rawscores, modstr)) == NULL)
		err(1, "cannot fdopen %s", scorepath);
	nscores = fread(scores, sizeof(scores[0]), TOPN, sf);
	if (ferror(sf))
		err(1, "error reading %s", scorepath);

	name = getenv("LOGNAME");
	if (name == NULL || *name == '\0')
		name = getenv("USER");
	if (name == NULL || *name == '\0')
		name = getlogin();
	if (name == NULL || *name == '\0')
		name = "  ???";

	if (nscores > TOPN)
		nscores = TOPN;
	strlcpy(scores[nscores].name, name, sizeof(scores[nscores].name));
	scores[nscores].score = 0;

	return 1;
}
Exemple #29
0
static void
f_count(char *arg)
{
	uintmax_t res;

	res = get_num(arg);
	if (res == UINTMAX_MAX)
		errc(1, ERANGE, "%s", oper);
	if (res == 0)
		cpy_cnt = UINTMAX_MAX;
	else
		cpy_cnt = res;
}
Exemple #30
0
/*
 * Read the score file.  Can be called from savescore (before showscores)
 * or showscores (if savescore will not be called).  If the given pointer
 * is not NULL, sets *fpp to an open file pointer that corresponds to a
 * read/write score file that is locked with LOCK_EX.  Otherwise, the
 * file is locked with LOCK_SH for the read and closed before return.
 *
 * Note, we assume closing the stdio file releases the lock.
 */
static void
getscores(FILE **fpp)
{
	int sd, mint, i, ret;
	char *mstr, *human, *home;
	char scorepath[PATH_MAX];
	FILE *sf;

	if (fpp != NULL) {
		mint = O_RDWR | O_CREAT;
		mstr = "r+";
		human = "read/write";
		*fpp = NULL;
	} else {
		mint = O_RDONLY;
		mstr = "r";
		human = "reading";
	}

	home = getenv("HOME");
	if (home == NULL || *home == '\0')
		err(1, "getenv");

	ret = snprintf(scorepath, sizeof(scorepath), "%s/%s", home, ".tetris.scores");
	if (ret < 0 || ret >= PATH_MAX)
		errc(1, ENAMETOOLONG, "%s/%s", home, ".tetris.scores");

	sd = open(scorepath, mint, 0666);
	if (sd < 0) {
		if (fpp == NULL) {
			nscores = 0;
			return;
		}
		err(1, "cannot open %s for %s", scorepath, human);
	}
	if ((sf = fdopen(sd, mstr)) == NULL)
		err(1, "cannot fdopen %s for %s", scorepath, human);

	nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf);
	if (ferror(sf))
		err(1, "error reading %s", scorepath);
	for (i = 0; i < nscores; i++)
		if (scores[i].hs_level < MINLEVEL ||
		    scores[i].hs_level > MAXLEVEL)
			errx(1, "scorefile %s corrupt", scorepath);

	if (fpp)
		*fpp = sf;
	else
		(void)fclose(sf);
}