2004-11-03 13:51:07 +00:00
|
|
|
.\" peter memishian -- meem@gnu.ai.mit.edu
|
|
|
|
.\" $Id: insque.3,v 1.2 1996/10/30 21:03:39 meem Exp meem $
|
2010-09-09 07:44:31 +00:00
|
|
|
.\" and Copyright (c) 2010, Michael Kerrisk <mtk.manpages@gmail.com>
|
2004-11-03 13:51:07 +00:00
|
|
|
.\"
|
|
|
|
.\" Permission is granted to make and distribute verbatim copies of this
|
|
|
|
.\" manual provided the copyright notice and this permission notice are
|
|
|
|
.\" preserved on all copies.
|
|
|
|
.\"
|
|
|
|
.\" Permission is granted to copy and distribute modified versions of this
|
|
|
|
.\" manual under the conditions for verbatim copying, provided that the
|
|
|
|
.\" entire resulting derived work is distributed under the terms of a
|
|
|
|
.\" permission notice identical to this one.
|
2007-04-12 22:42:49 +00:00
|
|
|
.\"
|
2004-11-03 13:51:07 +00:00
|
|
|
.\" Since the Linux kernel and libraries are constantly changing, this
|
|
|
|
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
|
|
|
.\" responsibility for errors or omissions, or for damages resulting from
|
|
|
|
.\" the use of the information contained herein. The author(s) may not
|
|
|
|
.\" have taken the same level of care in the production of this manual,
|
|
|
|
.\" which is licensed free of charge, as they might when working
|
|
|
|
.\" professionally.
|
2007-04-12 22:42:49 +00:00
|
|
|
.\"
|
2004-11-03 13:51:07 +00:00
|
|
|
.\" Formatted or processed versions of this manual, if unaccompanied by
|
|
|
|
.\" the source, must acknowledge the copyright and authors of this work.
|
|
|
|
.\"
|
|
|
|
.\" References consulted:
|
|
|
|
.\" Linux libc source code (5.4.7)
|
|
|
|
.\" Solaris 2.x, OSF/1, and HP-UX manpages
|
|
|
|
.\" Curry's "UNIX Systems Programming for SVR4" (O'Reilly & Associates 1996)
|
|
|
|
.\"
|
|
|
|
.\" Changed to POSIX, 2003-08-11, aeb+wh
|
2010-09-09 07:46:29 +00:00
|
|
|
.\" mtk, 2010-09-09: Noted glibc 2.4 bug, added info on circular
|
|
|
|
.\" lists, added example program
|
2004-11-03 13:51:07 +00:00
|
|
|
.\"
|
2010-09-09 07:44:31 +00:00
|
|
|
.TH INSQUE 3 2010-09-09 "" "Linux Programmer's Manual"
|
2004-11-03 13:51:07 +00:00
|
|
|
.SH NAME
|
|
|
|
insque, remque \- insert/remove an item from a queue
|
|
|
|
.SH SYNOPSIS
|
|
|
|
.nf
|
|
|
|
.B #include <search.h>
|
|
|
|
.sp
|
|
|
|
.BI "void insque(void *" elem ", void *" prev );
|
2007-12-23 13:45:24 +00:00
|
|
|
|
2004-11-03 13:51:07 +00:00
|
|
|
.BI "void remque(void *" elem );
|
2007-07-08 12:11:40 +00:00
|
|
|
.fi
|
|
|
|
.sp
|
|
|
|
.in -4n
|
|
|
|
Feature Test Macro Requirements for glibc (see
|
|
|
|
.BR feature_test_macros (7)):
|
|
|
|
.in
|
|
|
|
.sp
|
|
|
|
.BR insque (),
|
|
|
|
.BR remque ():
|
|
|
|
_SVID_SOURCE || _XOPEN_SOURCE\ >=\ 500
|
2004-11-03 13:51:07 +00:00
|
|
|
.SH DESCRIPTION
|
2010-09-09 07:44:31 +00:00
|
|
|
The
|
2007-05-12 09:06:04 +00:00
|
|
|
.BR insque ()
|
|
|
|
and
|
|
|
|
.BR remque ()
|
2010-09-09 07:44:31 +00:00
|
|
|
functions manipulate doubly-linked lists.
|
2007-04-12 22:42:49 +00:00
|
|
|
Each element in the list is a structure of
|
2010-09-09 07:44:31 +00:00
|
|
|
which the first two elements are a forward and a
|
2004-11-03 13:51:07 +00:00
|
|
|
backward pointer.
|
2010-09-09 07:44:31 +00:00
|
|
|
The linked list may be linear (i.e., NULL forward pointer at
|
|
|
|
the end of the list and NULL backward pointer at the start of the list)
|
|
|
|
or circular.
|
2004-11-03 13:51:07 +00:00
|
|
|
|
2010-09-09 07:44:31 +00:00
|
|
|
The
|
2007-05-12 09:06:04 +00:00
|
|
|
.BR insque ()
|
2010-09-09 07:44:31 +00:00
|
|
|
function inserts the element pointed to by \fIelem\fP
|
|
|
|
immediately after the element pointed to by \fIprev\fP.
|
2004-11-03 13:51:07 +00:00
|
|
|
|
2010-09-09 07:44:31 +00:00
|
|
|
If the list is linear, then the call
|
|
|
|
.I "insque(elem, NULL)"
|
|
|
|
can be used to insert the initial list element,
|
|
|
|
and the call sets the forward and backward pointers of
|
|
|
|
.I elem
|
|
|
|
to NULL.
|
|
|
|
|
|
|
|
If the list is circular,
|
|
|
|
the caller should ensure that the forward and backward pointers of the
|
|
|
|
first element are initialized to point to that element,
|
|
|
|
and the
|
|
|
|
.I prev
|
|
|
|
argument of the
|
|
|
|
.BR insque ()
|
|
|
|
call should also point to the element.
|
|
|
|
|
|
|
|
The
|
2007-05-12 09:06:04 +00:00
|
|
|
.BR remque ()
|
2010-09-09 07:44:31 +00:00
|
|
|
function removes the element pointed to by \fIelem\fP from the
|
2004-11-03 13:51:07 +00:00
|
|
|
doubly-linked list.
|
|
|
|
.SH "CONFORMING TO"
|
2008-07-15 13:39:17 +00:00
|
|
|
POSIX.1-2001.
|
2007-05-16 17:35:34 +00:00
|
|
|
.SH "NOTES"
|
2008-07-11 11:30:26 +00:00
|
|
|
Traditionally (e.g., SunOS, Linux libc 4 and libc 5),
|
|
|
|
the arguments of these functions were of type \fIstruct qelem *\fP,
|
2008-07-10 20:35:13 +00:00
|
|
|
defined as:
|
2004-11-03 13:51:07 +00:00
|
|
|
|
2007-12-19 06:16:04 +00:00
|
|
|
.in +4n
|
2004-11-03 13:51:07 +00:00
|
|
|
.nf
|
|
|
|
struct qelem {
|
2007-07-08 12:11:40 +00:00
|
|
|
struct qelem *q_forw;
|
|
|
|
struct qelem *q_back;
|
|
|
|
char q_data[1];
|
2004-11-03 13:51:07 +00:00
|
|
|
};
|
|
|
|
.fi
|
2007-12-19 06:16:04 +00:00
|
|
|
.in
|
2004-11-03 13:51:07 +00:00
|
|
|
|
2007-06-22 17:42:06 +00:00
|
|
|
This is still what you will get if
|
|
|
|
.B _GNU_SOURCE
|
|
|
|
is defined before
|
2007-06-20 21:53:34 +00:00
|
|
|
including \fI<search.h>\fP.
|
2004-11-03 13:51:07 +00:00
|
|
|
|
|
|
|
The location of the prototypes for these functions differs among several
|
2008-07-09 14:17:06 +00:00
|
|
|
versions of Unix.
|
2007-04-12 22:42:49 +00:00
|
|
|
The above is the POSIX version.
|
2007-06-20 21:53:34 +00:00
|
|
|
Some systems place them in \fI<string.h>\fP.
|
2008-07-11 11:30:26 +00:00
|
|
|
Linux libc4 and libc 5 placed them
|
2007-06-20 21:53:34 +00:00
|
|
|
in \fI<stdlib.h>\fP.
|
2010-09-09 07:46:29 +00:00
|
|
|
.SH BUGS
|
|
|
|
In glibc 2.4 and earlier, it was not possible to specify
|
|
|
|
.I prev
|
|
|
|
as NULL.
|
|
|
|
Consequently, to build a linear list, the caller had to build a list
|
|
|
|
using an initial call that contained the first two elements of the list,
|
|
|
|
with the forward and backward pointers in each element suitably initialized.
|
2010-09-09 07:46:10 +00:00
|
|
|
.SH EXAMPLE
|
|
|
|
The program below demonstrates the use of
|
|
|
|
.BR insque ().
|
|
|
|
Here is an example run of the program:
|
2010-09-09 07:54:35 +00:00
|
|
|
.in +4n
|
2010-09-09 07:46:10 +00:00
|
|
|
.nf
|
2010-09-09 07:54:35 +00:00
|
|
|
|
|
|
|
.RB "$ " "./a.out -c a b c"
|
2010-09-09 07:46:10 +00:00
|
|
|
Traversing completed list:
|
|
|
|
a
|
|
|
|
b
|
|
|
|
c
|
|
|
|
That was a circular list
|
|
|
|
.fi
|
2010-09-09 07:54:35 +00:00
|
|
|
.in
|
2010-09-09 07:46:10 +00:00
|
|
|
.SS Program source
|
|
|
|
\&
|
|
|
|
.nf
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <search.h>
|
|
|
|
|
|
|
|
struct element {
|
|
|
|
struct element *forward;
|
|
|
|
struct element *backward;
|
|
|
|
char *name;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct element *
|
|
|
|
new_element(void)
|
|
|
|
{
|
|
|
|
struct element *e;
|
|
|
|
|
|
|
|
e = malloc(sizeof(struct element));
|
|
|
|
if (e == NULL) {
|
|
|
|
fprintf(stderr, "malloc() failed\\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
struct element *first, *elem, *prev;
|
|
|
|
int circular, opt, errfnd;
|
|
|
|
|
|
|
|
/* The "\-c" command\-line option can be used to specify that the
|
|
|
|
list is circular */
|
|
|
|
|
|
|
|
errfnd = 0;
|
|
|
|
circular = 0;
|
|
|
|
while ((opt = getopt(argc, argv, "c")) != \-1) {
|
|
|
|
switch (opt) {
|
|
|
|
case 'c':
|
|
|
|
circular = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
errfnd = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (errfnd || optind >= argc) {
|
|
|
|
fprintf(stderr, "Usage: %s [\-c] string...\\n", argv[0]);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create first element and place it in the linked list */
|
|
|
|
|
|
|
|
elem = new_element();
|
|
|
|
first = elem;
|
|
|
|
|
|
|
|
elem\->name = argv[optind];
|
|
|
|
|
|
|
|
if (circular) {
|
|
|
|
elem\->forward = elem;
|
|
|
|
elem\->backward = elem;
|
|
|
|
insque(elem, elem);
|
|
|
|
} else {
|
|
|
|
insque(elem, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add remaining command\-line arguments as list elements */
|
|
|
|
|
|
|
|
while (++optind < argc) {
|
|
|
|
prev = elem;
|
|
|
|
|
|
|
|
elem = new_element();
|
|
|
|
elem\->name = argv[optind];
|
|
|
|
insque(elem, prev);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Traverse the list from the start, printing element names */
|
|
|
|
|
|
|
|
printf("Traversing completed list:\\n");
|
|
|
|
elem = first;
|
|
|
|
do {
|
|
|
|
printf(" %s\\n", elem\->name);
|
|
|
|
elem = elem\->forward;
|
|
|
|
} while (elem != NULL && elem != first);
|
|
|
|
|
|
|
|
if (elem == first)
|
|
|
|
printf("That was a circular list\\n");
|
|
|
|
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
}
|
|
|
|
.fi
|