View | Details | Raw Unified | Return to bug 248250 | Differences between
and this patch

Collapse All | Expand All

(-)sys/kern/kern_environment.c (-57 / +67 lines)
Lines 59-64 Link Here
59
static char *_getenv_dynamic_locked(const char *name, int *idx);
59
static char *_getenv_dynamic_locked(const char *name, int *idx);
60
static char *_getenv_dynamic(const char *name, int *idx);
60
static char *_getenv_dynamic(const char *name, int *idx);
61
61
62
static char *kenv_acquire(const char *name);
63
static void kenv_release(const char *buf);
64
62
static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment");
65
static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment");
63
66
64
#define KENV_SIZE	512	/* Maximum number of environment strings */
67
#define KENV_SIZE	512	/* Maximum number of environment strings */
Lines 88-95 Link Here
88
#define KENV_CHECK	if (!dynamic_kenv) \
91
#define KENV_CHECK	if (!dynamic_kenv) \
89
			    panic("%s: called before SI_SUB_KMEM", __func__)
92
			    panic("%s: called before SI_SUB_KMEM", __func__)
90
93
91
static char	*getenv_string_buffer(const char *);
92
93
int
94
int
94
sys_kenv(td, uap)
95
sys_kenv(td, uap)
95
	struct thread *td;
96
	struct thread *td;
Lines 482-497 Link Here
482
char *
483
char *
483
kern_getenv(const char *name)
484
kern_getenv(const char *name)
484
{
485
{
485
	char *ret;
486
	char *cp, *ret;
487
	int len;
486
488
487
	if (dynamic_kenv) {
489
	if (dynamic_kenv) {
488
		ret = getenv_string_buffer(name);
490
		len = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
489
		if (ret == NULL) {
491
		ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO);
490
			WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
492
		mtx_lock(&kenv_lock);
491
			    "getenv");
493
		cp = _getenv_dynamic(name, NULL);
494
		if (cp != NULL)
495
			strlcpy(ret, cp, len);
496
		mtx_unlock(&kenv_lock);
497
		if (cp == NULL) {
498
			uma_zfree(kenv_zone, ret);
499
			ret = NULL;
492
		}
500
		}
493
	} else
501
	} else
494
		ret = _getenv_static(name);
502
		ret = _getenv_static(name);
503
495
	return (ret);
504
	return (ret);
496
}
505
}
497
506
Lines 503-514 Link Here
503
{
512
{
504
	char *cp;
513
	char *cp;
505
514
506
	if (dynamic_kenv) {
515
	cp = kenv_acquire(name);
507
		mtx_lock(&kenv_lock);
516
	kenv_release(cp);
508
		cp = _getenv_dynamic(name, NULL);
517
509
		mtx_unlock(&kenv_lock);
510
	} else
511
		cp = _getenv_static(name);
512
	if (cp != NULL)
518
	if (cp != NULL)
513
		return (1);
519
		return (1);
514
	return (0);
520
	return (0);
Lines 615-644 Link Here
615
}
621
}
616
622
617
/*
623
/*
618
 * Return a buffer containing the string value from an environment variable
624
 * Return the internal kenv buffer for the variable name, if it exists.
625
 * If the dynamic kenv is initialized and the name is present, return
626
 * with kenv_lock held.
619
 */
627
 */
620
static char *
628
static char *
621
getenv_string_buffer(const char *name)
629
kenv_acquire(const char *name)
622
{
630
{
623
	char *cp, *ret;
631
	char *value;
624
	int len;
625
632
626
	if (dynamic_kenv) {
633
	if (dynamic_kenv) {
627
		len = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
628
		ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO);
629
		mtx_lock(&kenv_lock);
634
		mtx_lock(&kenv_lock);
630
		cp = _getenv_dynamic(name, NULL);
635
		value = _getenv_dynamic(name, NULL);
631
		if (cp != NULL)
636
		if (value == NULL)
632
			strlcpy(ret, cp, len);
637
			mtx_unlock(&kenv_lock);
633
		mtx_unlock(&kenv_lock);
638
		return (value);
634
		if (cp == NULL) {
635
			uma_zfree(kenv_zone, ret);
636
			ret = NULL;
637
		}
638
	} else
639
	} else
639
		ret = _getenv_static(name);
640
		return (_getenv_static(name));
641
}
640
642
641
	return (ret);
643
/*
644
 * Undo a previous kenv_acquire() operation
645
 */
646
static void
647
kenv_release(const char *buf)
648
{
649
	if ((buf != NULL) && dynamic_kenv)
650
		mtx_unlock(&kenv_lock);
642
}
651
}
643
652
644
/*
653
/*
Lines 649-665 Link Here
649
{
658
{
650
	char *cp;
659
	char *cp;
651
660
652
	if (dynamic_kenv) {
661
	cp = kenv_acquire(name);
653
		mtx_lock(&kenv_lock);
662
654
		cp = _getenv_dynamic(name, NULL);
663
	if (cp != NULL)
655
		if (cp != NULL)
664
		strlcpy(data, cp, size);
656
			strlcpy(data, cp, size);
665
657
		mtx_unlock(&kenv_lock);
666
	kenv_release(cp);
658
	} else {
667
659
		cp = _getenv_static(name);
660
		if (cp != NULL)
661
			strlcpy(data, cp, size);
662
	}
663
	return (cp != NULL);
668
	return (cp != NULL);
664
}
669
}
665
670
Lines 673-688 Link Here
673
	uint8_t shift;
678
	uint8_t shift;
674
	int64_t value;
679
	int64_t value;
675
	int64_t old;
680
	int64_t old;
676
	char *buf;
681
	const char *buf;
677
	char *end;
682
	char *end;
678
	char *ptr;
683
	const char *ptr;
679
	int n;
684
	int n;
680
	int rc;
685
	int rc;
681
686
682
	if ((buf = getenv_string_buffer(name)) == NULL)
687
	rc = 0;			  /* assume failure */
683
		return (0);
684
688
685
	rc = 0;			  /* assume failure */
689
	buf = kenv_acquire(name);
690
	if (buf == NULL)
691
		goto error;
692
686
	/* get maximum number of elements */
693
	/* get maximum number of elements */
687
	size /= type_size;
694
	size /= type_size;
688
695
Lines 797-804 Link Here
797
	if (n != 0)
804
	if (n != 0)
798
		rc = 1;	/* success */
805
		rc = 1;	/* success */
799
error:
806
error:
800
	if (dynamic_kenv)
807
	kenv_release(buf);
801
		uma_zfree(kenv_zone, buf);
802
	return (rc);
808
	return (rc);
803
}
809
}
804
810
Lines 898-915 Link Here
898
int
904
int
899
getenv_quad(const char *name, quad_t *data)
905
getenv_quad(const char *name, quad_t *data)
900
{
906
{
901
	char	*value, *vtp;
907
	const char	*value;
902
	quad_t	iv;
908
	char		suffix, *vtp;
909
	quad_t		iv;
903
910
904
	value = getenv_string_buffer(name);
911
	value = kenv_acquire(name);
905
	if (value == NULL)
912
	if (value == NULL) {
906
		return (0);
913
		goto error;
914
	}
907
	iv = strtoq(value, &vtp, 0);
915
	iv = strtoq(value, &vtp, 0);
908
	if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
916
	if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
909
		freeenv(value);
917
		goto error;
910
		return (0);
911
	}
918
	}
912
	switch (vtp[0]) {
919
	suffix = vtp[0];
920
	kenv_release(value);
921
	switch (suffix) {
913
	case 't': case 'T':
922
	case 't': case 'T':
914
		iv *= 1024;
923
		iv *= 1024;
915
		/* FALLTHROUGH */
924
		/* FALLTHROUGH */
Lines 924-935 Link Here
924
	case '\0':
933
	case '\0':
925
		break;
934
		break;
926
	default:
935
	default:
927
		freeenv(value);
928
		return (0);
936
		return (0);
929
	}
937
	}
930
	freeenv(value);
931
	*data = iv;
938
	*data = iv;
932
	return (1);
939
	return (1);
940
error:
941
	kenv_release(value);
942
	return (0);
933
}
943
}
934
944
935
/*
945
/*

Return to bug 248250