[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/build/uClibc/libc/misc/utmp/utent.c b/ap/build/uClibc/libc/misc/utmp/utent.c
new file mode 100644
index 0000000..f97cad3
--- /dev/null
+++ b/ap/build/uClibc/libc/misc/utmp/utent.c
@@ -0,0 +1,208 @@
+/* utent.c <ndf@linux.mit.edu> */
+/* Let it be known that this is very possibly the worst standard ever. HP-UX
+ does one thing, someone else does another, linux another... If anyone
+ actually has the standard, please send it to me.
+
+ Note that because of the way this stupid stupid standard works, you
+ have to call endutent() to close the file even if you've not called
+ setutent -- getutid and family use the same file descriptor.
+
+ Modified by Erik Andersen for uClibc...
+*/
+
+#include <features.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <errno.h>
+#include <string.h>
+#include <utmp.h>
+#include <not-cancel.h>
+
+#include <bits/uClibc_mutex.h>
+__UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER);
+
+
+/* Do not create extra unlocked functions if no locking is needed */
+#if defined __UCLIBC_HAS_THREADS__
+# define static_if_threaded static
+#else
+# define static_if_threaded /* nothing */
+# define __setutent setutent
+# define __getutent getutent
+# define __getutid getutid
+#endif
+
+
+/* Some global crap */
+static int static_fd = -1;
+static struct utmp static_utmp;
+static const char default_file_name[] = _PATH_UTMP;
+static const char *static_ut_name = default_file_name;
+
+
+/* This function must be called with the LOCK held */
+static_if_threaded void __setutent(void)
+{
+ if (static_fd < 0) {
+ static_fd = open_not_cancel_2(static_ut_name, O_RDWR | O_CLOEXEC);
+ if (static_fd < 0) {
+ static_fd = open_not_cancel_2(static_ut_name, O_RDONLY | O_CLOEXEC);
+ if (static_fd < 0) {
+ return; /* static_fd remains < 0 */
+ }
+ }
+#ifndef __ASSUME_O_CLOEXEC
+ /* Make sure the file will be closed on exec() */
+ fcntl_not_cancel(static_fd, F_SETFD, FD_CLOEXEC);
+#endif
+ return;
+ }
+ lseek(static_fd, 0, SEEK_SET);
+}
+#if defined __UCLIBC_HAS_THREADS__
+void setutent(void)
+{
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ __setutent();
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+}
+#endif
+libc_hidden_def(setutent)
+
+/* This function must be called with the LOCK held */
+static_if_threaded struct utmp *__getutent(void)
+{
+ if (static_fd < 0) {
+ __setutent();
+ if (static_fd < 0) {
+ return NULL;
+ }
+ }
+
+ if (read_not_cancel(static_fd, &static_utmp, sizeof(static_utmp)) == sizeof(static_utmp)) {
+ return &static_utmp;
+ }
+
+ return NULL;
+}
+#if defined __UCLIBC_HAS_THREADS__
+struct utmp *getutent(void)
+{
+ struct utmp *ret;
+
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ ret = __getutent();
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return ret;
+}
+#endif
+libc_hidden_def(getutent)
+
+void endutent(void)
+{
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ if (static_fd >= 0)
+ close_not_cancel_no_status(static_fd);
+ static_fd = -1;
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+}
+libc_hidden_def(endutent)
+
+/* This function must be called with the LOCK held */
+static_if_threaded struct utmp *__getutid(const struct utmp *utmp_entry)
+{
+ struct utmp *lutmp;
+ unsigned type;
+
+ /* We use the fact that constants we are interested in are: */
+ /* RUN_LVL=1, ... OLD_TIME=4; INIT_PROCESS=5, ... USER_PROCESS=8 */
+ type = utmp_entry->ut_type - 1;
+ type /= 4;
+
+ while ((lutmp = __getutent()) != NULL) {
+ if (type == 0 && lutmp->ut_type == utmp_entry->ut_type) {
+ /* one of RUN_LVL, BOOT_TIME, NEW_TIME, OLD_TIME */
+ return lutmp;
+ }
+ if (type == 1 && strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id)) == 0) {
+ /* INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, DEAD_PROCESS */
+ return lutmp;
+ }
+ }
+
+ return NULL;
+}
+#if defined __UCLIBC_HAS_THREADS__
+struct utmp *getutid(const struct utmp *utmp_entry)
+{
+ struct utmp *ret;
+
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ ret = __getutid(utmp_entry);
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return ret;
+}
+#endif
+libc_hidden_def(getutid)
+
+struct utmp *getutline(const struct utmp *utmp_entry)
+{
+ struct utmp *lutmp;
+
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ while ((lutmp = __getutent()) != NULL) {
+ if (lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) {
+ if (strncmp(lutmp->ut_line, utmp_entry->ut_line, sizeof(lutmp->ut_line)) == 0) {
+ break;
+ }
+ }
+ }
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return lutmp;
+}
+libc_hidden_def(getutline)
+
+struct utmp *pututline(const struct utmp *utmp_entry)
+{
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ /* Ignore the return value. That way, if they've already positioned
+ the file pointer where they want it, everything will work out. */
+ lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
+
+ if (__getutid(utmp_entry) != NULL)
+ lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
+ else
+ lseek(static_fd, (off_t) 0, SEEK_END);
+ if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
+ utmp_entry = NULL;
+
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return (struct utmp *)utmp_entry;
+}
+libc_hidden_def(pututline)
+
+int utmpname(const char *new_ut_name)
+{
+ __UCLIBC_MUTEX_LOCK(utmplock);
+ if (new_ut_name != NULL) {
+ if (static_ut_name != default_file_name)
+ free((char *)static_ut_name);
+ static_ut_name = strdup(new_ut_name);
+ if (static_ut_name == NULL) {
+ /* We should probably whine about out-of-memory
+ * errors here... Instead just reset to the default */
+ static_ut_name = default_file_name;
+ }
+ }
+
+ if (static_fd >= 0) {
+ close_not_cancel_no_status(static_fd);
+ static_fd = -1;
+ }
+ __UCLIBC_MUTEX_UNLOCK(utmplock);
+ return 0; /* or maybe return -(static_ut_name != new_ut_name)? */
+}
+libc_hidden_def(utmpname)