summaryrefslogtreecommitdiff
path: root/libutil
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-05-08 19:58:20 +0000
committerEric Andersen <andersen@codepoet.org>2001-05-08 19:58:20 +0000
commita3e03be058a9b9a2caf36c5b18f66c0fc3df3bf0 (patch)
tree2ad333bd1e56590e981eba3c54f6057cbf5758bb /libutil
parent6c0899094d50e0d35d699594bfcd9cae4164abe2 (diff)
Add in libutil, based on Cory Visi's variant of Michael Shmulevich's libutil
port. I have reworked the code quite a bit so that the stuff that is supposed to be in libc is in libc, and I added a bunch of missing stuff so the libutil interface matches that of glibc's libutil. The only caveat is that libutil/login.c is currently a stub. -Erik
Diffstat (limited to 'libutil')
-rw-r--r--libutil/Makefile61
-rw-r--r--libutil/forkpty.c52
-rw-r--r--libutil/login.c14
-rw-r--r--libutil/login_tty.c69
-rw-r--r--libutil/logout.c69
-rw-r--r--libutil/logwtmp.c73
-rw-r--r--libutil/openpty.c142
7 files changed, 480 insertions, 0 deletions
diff --git a/libutil/Makefile b/libutil/Makefile
new file mode 100644
index 000000000..b5a458c30
--- /dev/null
+++ b/libutil/Makefile
@@ -0,0 +1,61 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000 by Lineo, inc.
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Library General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Derived in part from the Linux-8086 C library, the GNU C Library, and several
+# other sundry sources. Files within this library are copyright by their
+# respective copyright holders.
+
+TOPDIR=../
+include $(TOPDIR)Rules.mak
+LIBC=$(TOPDIR)libc.a
+
+LIBUTIL=libutil.a
+LIBUTIL_SHARED=libutil.so
+TARGET_CC= ../extra/gcc-uClibc/$(TARGET_ARCH)-uclibc-gcc
+
+CSRC=forkpty.c login.c login_tty.c logout.c logwtmp.c openpty.c
+COBJS=$(patsubst %.c,%.o, $(CSRC))
+
+OBJS=$(COBJS)
+
+all: $(OBJS) $(LIBC)
+
+$(LIBC): ar-target
+
+ar-target: $(OBJS)
+ $(AR) $(ARFLAGS) $(LIBUTIL) $(OBJS)
+
+$(COBJS): %.o : %.c
+ $(TARGET_CC) $(CFLAGS) -c $< -o $@
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
+shared: $(LIBUTIL)
+ $(TARGET_CC) $(LDFLAGS) -shared -o $(LIBUTIL_SHARED).$(MAJOR_VERSION) \
+ -Wl,-soname,$(LIBUTIL_SHARED).$(MAJOR_VERSION) $(COBJS) $(TOPDIR)$(SHARED_FULLNAME)
+
+install: all
+ install -d $(INSTALL_DIR)/lib
+ install -m 644 $(LIBUTIL) $(INSTALL_DIR)/lib/
+ @if [ -f $(LIBUTIL_SHARED).$(MAJOR_VERSION) ] ; then \
+ install -m 644 $(LIBUTIL_SHARED).$(MAJOR_VERSION) $(INSTALL_DIR)/lib/; \
+ (cd $(INSTALL_DIR)/lib/;ln -sf $(LIBUTIL_SHARED).$(MAJOR_VERSION) $(LIBUTIL_SHARED)); \
+ fi;
+
+clean:
+ rm -f *.[oa] *~ core $(LIBUTIL_SHARED).$(MAJOR_VERSION)
+
diff --git a/libutil/forkpty.c b/libutil/forkpty.c
new file mode 100644
index 000000000..af1d4becc
--- /dev/null
+++ b/libutil/forkpty.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <sys/types.h>
+#include <termios.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <pty.h>
+
+int forkpty (int *amaster, char *name,
+ struct termios *termp, struct winsize *winp)
+{
+ int master, slave, pid;
+
+ if (openpty (&master, &slave, name, termp, winp) == -1)
+ return -1;
+
+ switch (pid = fork ())
+ {
+ case -1:
+ return -1;
+ case 0:
+ /* Child. */
+ close (master);
+ if (login_tty (slave))
+ _exit (1);
+
+ return 0;
+ default:
+ /* Parent. */
+ *amaster = master;
+ close (slave);
+
+ return pid;
+ }
+}
diff --git a/libutil/login.c b/libutil/login.c
new file mode 100644
index 000000000..636ce9608
--- /dev/null
+++ b/libutil/login.c
@@ -0,0 +1,14 @@
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <utmp.h>
+
+/* Write the given entry into utmp and wtmp. */
+void login (const struct utmp *entry)
+{
+ return;
+}
+link_warning (login, "the `login' function is stubbed out and will not write utmp or wtmp.")
+
diff --git a/libutil/login_tty.c b/libutil/login_tty.c
new file mode 100644
index 000000000..d354407f2
--- /dev/null
+++ b/libutil/login_tty.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Make FD be the controlling terminal, stdin, stdout, and stderr;
+ then close FD. Returns 0 on success, nonzero on error. */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <utmp.h>
+
+int login_tty(int fd)
+{
+ (void) setsid();
+#ifdef TIOCSCTTY
+ if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1)
+ return (-1);
+#else
+ {
+ /* This might work. */
+ char *fdname = ttyname (fd);
+ int newfd;
+ if (fdname)
+ {
+ if (fd != 0)
+ (void) close (0);
+ if (fd != 1)
+ (void) close (1);
+ if (fd != 2)
+ (void) close (2);
+ newfd = open (fdname, O_RDWR);
+ (void) close (newfd);
+ }
+ }
+#endif
+ (void) dup2(fd, 0);
+ (void) dup2(fd, 1);
+ (void) dup2(fd, 2);
+ if (fd > 2)
+ (void) close(fd);
+ return (0);
+}
diff --git a/libutil/logout.c b/libutil/logout.c
new file mode 100644
index 000000000..082579b8f
--- /dev/null
+++ b/libutil/logout.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <utmp.h>
+#include <sys/time.h>
+
+int
+logout (const char *line)
+{
+ struct utmp tmp;
+ struct utmp *ut;
+ int result = 0;
+
+ /* Tell that we want to use the UTMP file. */
+ utmpname (_PATH_UTMP);
+
+ /* Open UTMP file. */
+ setutent ();
+
+ /* Fill in search information. */
+#if _HAVE_UT_TYPE - 0
+ tmp.ut_type = USER_PROCESS;
+#endif
+ strncpy (tmp.ut_line, line, sizeof tmp.ut_line);
+
+ /* Read the record. */
+ if( (ut = getutline(&tmp)) )
+ {
+ /* Clear information about who & from where. */
+ bzero (ut->ut_name, sizeof ut->ut_name);
+#if _HAVE_UT_HOST - 0
+ bzero (ut->ut_host, sizeof ut->ut_host);
+#endif
+#if _HAVE_UT_TV - 0
+ gettimeofday (&ut->ut_tv, NULL);
+#else
+ time (&ut->ut_time);
+#endif
+#if _HAVE_UT_TYPE - 0
+ ut->ut_type = DEAD_PROCESS;
+#endif
+
+ if (pututline (ut) != NULL)
+ result = 1;
+ }
+
+ /* Close UTMP file. */
+ endutent ();
+
+ return result;
+}
diff --git a/libutil/logwtmp.c b/libutil/logwtmp.c
new file mode 100644
index 000000000..d8ee3da05
--- /dev/null
+++ b/libutil/logwtmp.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <utmp.h>
+
+
+void logwtmp (const char *line, const char *name, const char *host)
+{
+ struct utmp ut;
+ struct flock lock;
+ int ut_fd;
+
+
+ /* Set information in new entry. */
+ memset (&ut, 0, sizeof (ut));
+#if _HAVE_UT_PID - 0
+ ut.ut_pid = getpid ();
+#endif
+#if _HAVE_UT_TYPE - 0
+ ut.ut_type = name[0] ? USER_PROCESS : DEAD_PROCESS;
+#endif
+ strncpy (ut.ut_line, line, sizeof ut.ut_line);
+ strncpy (ut.ut_name, name, sizeof ut.ut_name);
+#if _HAVE_UT_HOST - 0
+ strncpy (ut.ut_host, host, sizeof ut.ut_host);
+#endif
+
+#if _HAVE_UT_TV - 0
+ __gettimeofday (&ut.ut_tv, NULL);
+#else
+ time (&ut.ut_time);
+#endif
+
+/* updwtmp (_PATH_WTMP, &ut); */
+/* from tinylogin */
+
+ if ((ut_fd = open(_PATH_WTMP, O_APPEND | O_WRONLY)) >= 0) {
+ /* Lock the utmp file before updating */
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 0;
+ if (fcntl(ut_fd, F_SETLK, &lock) >= 0) {
+ write(ut_fd, (void *) &ut, sizeof(ut));
+ /* Now unlock the utmp file */
+ lock.l_type = F_UNLCK;
+ }
+ close(ut_fd);
+ }
+
+
+}
diff --git a/libutil/openpty.c b/libutil/openpty.c
new file mode 100644
index 000000000..1c2adbf6a
--- /dev/null
+++ b/libutil/openpty.c
@@ -0,0 +1,142 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pty.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+extern int getpt (void);
+extern int grantpt (int fd);
+extern int ptsname_r (int fd, char *buf, size_t buflen);
+extern int unlockpt (int fd);
+
+/* Return the result of ptsname_r in the buffer pointed to by PTS,
+ which should be of length BUF_LEN. If it is too long to fit in
+ this buffer, a sufficiently long buffer is allocated using malloc,
+ and returned in PTS. 0 is returned upon success, -1 otherwise. */
+static int
+pts_name (int fd, char **pts, size_t buf_len)
+{
+ int rv;
+ char *buf = *pts;
+
+ for (;;)
+ {
+ char *new_buf;
+
+ if (buf_len)
+ {
+ rv = ptsname_r (fd, buf, buf_len);
+
+ if (rv != 0 || memchr (buf, '\0', buf_len))
+ /* We either got an error, or we succeeded and the
+ returned name fit in the buffer. */
+ break;
+
+ /* Try again with a longer buffer. */
+ buf_len += buf_len; /* Double it */
+ }
+ else
+ /* No initial buffer; start out by mallocing one. */
+ buf_len = 128; /* First time guess. */
+
+ if (buf != *pts)
+ /* We've already malloced another buffer at least once. */
+ new_buf = realloc (buf, buf_len);
+ else
+ new_buf = malloc (buf_len);
+ if (! new_buf)
+ {
+ rv = -1;
+ errno = ENOMEM;
+ break;
+ }
+ buf = new_buf;
+ }
+
+ if (rv == 0)
+ *pts = buf; /* Return buffer to the user. */
+ else if (buf != *pts)
+ free (buf); /* Free what we malloced when returning an error. */
+
+ return rv;
+}
+
+/* Create pseudo tty master slave pair and set terminal attributes
+ according to TERMP and WINP. Return handles for both ends in
+ AMASTER and ASLAVE, and return the name of the slave end in NAME. */
+int
+openpty (int *amaster, int *aslave, char *name, struct termios *termp,
+ struct winsize *winp)
+{
+#ifdef PATH_MAX
+ char _buf[PATH_MAX];
+#else
+ char _buf[512];
+#endif
+ char *buf = _buf;
+ int master, slave;
+
+ master = getpt ();
+ if (master == -1)
+ return -1;
+
+ if (grantpt (master))
+ goto fail;
+
+ if (unlockpt (master))
+ goto fail;
+
+ if (pts_name (master, &buf, sizeof (_buf)))
+ goto fail;
+
+ slave = open (buf, O_RDWR | O_NOCTTY);
+ if (slave == -1)
+ {
+ if (buf != _buf)
+ free (buf);
+
+ goto fail;
+ }
+
+ /* XXX Should we ignore errors here? */
+ if(termp)
+ tcsetattr (slave, TCSAFLUSH, termp);
+ if (winp)
+ ioctl (slave, TIOCSWINSZ, winp);
+
+ *amaster = master;
+ *aslave = slave;
+ if (name != NULL)
+ strcpy (name, buf);
+
+ if (buf != _buf)
+ free (buf);
+ return 0;
+
+ fail:
+ close (master);
+ return -1;
+}