Merge "Representation of channel masks for position assignment and index assignment"
diff --git a/include/cutils/atomic.h b/include/cutils/atomic.h
index 1787e34..b9b18c4 100644
--- a/include/cutils/atomic.h
+++ b/include/cutils/atomic.h
@@ -25,8 +25,20 @@
 #endif
 
 /*
- * A handful of basic atomic operations.  The appropriate pthread
- * functions should be used instead of these whenever possible.
+ * A handful of basic atomic operations.
+ * THESE ARE HERE FOR LEGACY REASONS ONLY.  AVOID.
+ *
+ * PREFERRED ALTERNATIVES:
+ * - Use C++/C/pthread locks/mutexes whenever there is not a
+ *   convincing reason to do otherwise.  Note that very clever and
+ *   complicated, but correct, lock-free code is often slower than
+ *   using locks, especially where nontrivial data structures
+ *   are involved.
+ * - C11 stdatomic.h.
+ * - Where supported, C++11 std::atomic<T> .
+ *
+ * PLEASE STOP READING HERE UNLESS YOU ARE TRYING TO UNDERSTAND
+ * OR UPDATE OLD CODE.
  *
  * The "acquire" and "release" terms can be defined intuitively in terms
  * of the placement of memory barriers in a simple lock implementation:
@@ -74,6 +86,17 @@
 /*
  * Perform an atomic load with "acquire" or "release" ordering.
  *
+ * Note that the notion of a "release" ordering for a load does not
+ * really fit into the C11 or C++11 memory model.  The extra ordering
+ * is normally observable only by code using memory_order_relaxed
+ * atomics, or data races.  In the rare cases in which such ordering
+ * is called for, use memory_order_relaxed atomics and a leading
+ * atomic_thread_fence (typically with memory_order_acquire,
+ * not memory_order_release!) instead.  If you do not understand
+ * this comment, you are in the vast majority, and should not be
+ * using release loads or replacing them with anything other than
+ * locks or default sequentially consistent atomics.
+ *
  * This is only necessary if you need the memory barrier.  A 32-bit read
  * from a 32-bit aligned address is atomic on all supported platforms.
  */
@@ -88,6 +111,14 @@
 /*
  * Perform an atomic store with "acquire" or "release" ordering.
  *
+ * Note that the notion of a "acquire" ordering for a store does not
+ * really fit into the C11 or C++11 memory model.  The extra ordering
+ * is normally observable only by code using memory_order_relaxed
+ * atomics, or data races.  In the rare cases in which such ordering
+ * is called for, use memory_order_relaxed atomics and a trailing
+ * atomic_thread_fence (typically with memory_order_release,
+ * not memory_order_acquire!) instead.
+ *
  * This is only necessary if you need the memory barrier.  A 32-bit write
  * to a 32-bit aligned address is atomic on all supported platforms.
  */
diff --git a/init/builtins.c b/init/builtins.c
index f7bd8a9..6032184 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -48,7 +48,7 @@
 
 #include <private/android_filesystem_config.h>
 
-void add_environment(const char *name, const char *value);
+int add_environment(const char *name, const char *value);
 
 extern int init_module(void *, unsigned long, const char *);
 
@@ -261,8 +261,7 @@
 
 int do_export(int nargs, char **args)
 {
-    add_environment(args[1], args[2]);
-    return 0;
+    return add_environment(args[1], args[2]);
 }
 
 int do_hostname(int nargs, char **args)
diff --git a/init/init.c b/init/init.c
index e4ac1cf..74c0308 100644
--- a/init/init.c
+++ b/init/init.c
@@ -96,11 +96,24 @@
 /* add_environment - add "key=value" to the current environment */
 int add_environment(const char *key, const char *val)
 {
-    int n;
+    size_t n;
+    size_t key_len = strlen(key);
 
-    for (n = 0; n < 31; n++) {
-        if (!ENV[n]) {
-            size_t len = strlen(key) + strlen(val) + 2;
+    /* The last environment entry is reserved to terminate the list */
+    for (n = 0; n < (ARRAY_SIZE(ENV) - 1); n++) {
+
+        /* Delete any existing entry for this key */
+        if (ENV[n] != NULL) {
+            size_t entry_key_len = strcspn(ENV[n], "=");
+            if ((entry_key_len == key_len) && (strncmp(ENV[n], key, entry_key_len) == 0)) {
+                free((char*)ENV[n]);
+                ENV[n] = NULL;
+            }
+        }
+
+        /* Add entry if a free slot is available */
+        if (ENV[n] == NULL) {
+            size_t len = key_len + strlen(val) + 2;
             char *entry = malloc(len);
             snprintf(entry, len, "%s=%s", key, val);
             ENV[n] = entry;
@@ -108,7 +121,9 @@
         }
     }
 
-    return 1;
+    ERROR("No env. room to store: '%s':'%s'\n", key, val);
+
+    return -1;
 }
 
 static void zap_stdio(void)
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 957fdb5..4bea4be 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -503,13 +503,11 @@
             (user_logger_content)     ? yes : no,
             (kernel_logger_available) ? yes : no,
             (kernel_logger_content)   ? yes : no,
-            (user_logger_available && kernel_logger_available) ? "WARNING" : "ok",
+            (user_logger_available && kernel_logger_available) ? "ERROR" : "ok",
             (user_logger_content && kernel_logger_content) ? "ERROR" : "ok");
 
-    if (user_logger_available && kernel_logger_available) {
-        printf("WARNING: kernel & user logger; both consuming resources!!!\n");
-    }
-
+    EXPECT_EQ(0, user_logger_available && kernel_logger_available);
+    EXPECT_EQ(0, !user_logger_available && !kernel_logger_available);
     EXPECT_EQ(0, user_logger_content && kernel_logger_content);
     EXPECT_EQ(0, !user_logger_content && !kernel_logger_content);
 }
diff --git a/toolbox/bsd-compatibility.h b/toolbox/bsd-compatibility.h
index a304631..abc3064 100644
--- a/toolbox/bsd-compatibility.h
+++ b/toolbox/bsd-compatibility.h
@@ -31,6 +31,9 @@
 /* We want chown to support user.group as well as user:group. */
 #define SUPPORT_DOT
 
+/* We don't localize /system/bin! */
+#define WITHOUT_NLS
+
 __BEGIN_DECLS
 
 extern int uid_from_user(const char* name, uid_t* uid);
diff --git a/toolbox/grep/grep.c b/toolbox/grep/grep.c
index 7b2c487..7314e13 100644
--- a/toolbox/grep/grep.c
+++ b/toolbox/grep/grep.c
@@ -159,7 +159,6 @@
 {
 	fprintf(stderr, getstr(4), __progname);
 	fprintf(stderr, "%s", getstr(5));
-	fprintf(stderr, "%s", getstr(5));
 	fprintf(stderr, "%s", getstr(6));
 	fprintf(stderr, "%s", getstr(7));
 	exit(2);
@@ -403,7 +402,7 @@
 				Aflag = 0;
 			else if (Aflag > LLONG_MAX / 10) {
 				errno = ERANGE;
-				err(2, "%llu", Aflag);
+				err(2, NULL);
 			}
 			Aflag = Bflag = (Aflag * 10) + (c - '0');
 			break;
@@ -420,10 +419,10 @@
 			l = strtoull(optarg, &ep, 10);
 			if (((errno == ERANGE) && (l == ULLONG_MAX)) ||
 			    ((errno == EINVAL) && (l == 0)))
-				err(2, "strtoull");
+				err(2, NULL);
 			else if (ep[0] != '\0') {
 				errno = EINVAL;
-				err(2, "empty");
+				err(2, NULL);
 			}
 			if (c == 'A')
 				Aflag = l;
@@ -509,10 +508,10 @@
 			mcount = strtoull(optarg, &ep, 10);
 			if (((errno == ERANGE) && (mcount == ULLONG_MAX)) ||
 			    ((errno == EINVAL) && (mcount == 0)))
-				err(2, "strtoull");
+				err(2, NULL);
 			else if (ep[0] != '\0') {
 				errno = EINVAL;
-				err(2, "empty");
+				err(2, NULL);
 			}
 			break;
 		case 'n':
diff --git a/toolbox/grep/grep.h b/toolbox/grep/grep.h
index 6454f93..eafb00e 100644
--- a/toolbox/grep/grep.h
+++ b/toolbox/grep/grep.h
@@ -29,10 +29,6 @@
  * SUCH DAMAGE.
  */
 
-#ifdef ANDROID
-#define WITHOUT_NLS
-#endif
-
 #ifndef ANDROID
 #include <bzlib.h>
 #endif
diff --git a/toolbox/grep/util.c b/toolbox/grep/util.c
index 5712fee..ecd948d 100644
--- a/toolbox/grep/util.c
+++ b/toolbox/grep/util.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: util.c,v 1.16 2012/05/06 22:32:05 joerg Exp $	*/
+/*	$NetBSD: util.c,v 1.17 2013/01/21 03:24:43 msaitoh Exp $	*/
 /*	$FreeBSD: head/usr.bin/grep/util.c 211496 2010-08-19 09:28:59Z des $	*/
 /*	$OpenBSD: util.c,v 1.39 2010/07/02 22:18:03 tedu Exp $	*/
 
@@ -34,7 +34,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: util.c,v 1.16 2012/05/06 22:32:05 joerg Exp $");
+__RCSID("$NetBSD: util.c,v 1.17 2013/01/21 03:24:43 msaitoh Exp $");
 
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -74,9 +74,10 @@
 	for (i = 0; i < fpatterns; ++i) {
 		if (fnmatch(fpattern[i].pat, fname, 0) == 0 ||
 		    fnmatch(fpattern[i].pat, fname_base, 0) == 0) {
-			if (fpattern[i].mode == EXCL_PAT)
+			if (fpattern[i].mode == EXCL_PAT) {
+				free(fname_copy);
 				return (false);
-			else
+			} else
 				ret = true;
 		}
 	}
@@ -128,7 +129,7 @@
 		break;
 	default:
 		fts_flags = FTS_LOGICAL;
-
+			
 	}
 
 	fts_flags |= FTS_NOSTAT | FTS_NOCHDIR;
@@ -273,7 +274,7 @@
 	return (c);
 }
 
-#define iswword(x)	(iswalnum((wint_t)(x)) || (x) == L'_')
+#define iswword(x)	(iswalnum((x)) || (x) == L'_')
 
 /*
  * Processes a line comparing it with the specified patterns.  Each pattern
@@ -474,13 +475,13 @@
 			if (!oflag)
 				fwrite(line->dat + a, matches[i].rm_so - a, 1,
 				    stdout);
-			if (color)
+			if (color) 
 				fprintf(stdout, "\33[%sm\33[K", color);
 
-				fwrite(line->dat + matches[i].rm_so,
+				fwrite(line->dat + matches[i].rm_so, 
 				    matches[i].rm_eo - matches[i].rm_so, 1,
 				    stdout);
-			if (color)
+			if (color) 
 				fprintf(stdout, "\33[m\33[K");
 			a = matches[i].rm_eo;
 			if (oflag)