linux-0.01-distro/binutils-1.9/ranlib.c

242 lines
5.2 KiB
C
Raw Permalink Normal View History

2021-08-15 00:16:45 -04:00
/* Dummy ranlib program for GNU.
All it does is `ar rs LIBRARY' for each library specified.
Copyright (C) 1989, 1990 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <ar.h>
#include <sys/types.h>
#include <sys/file.h>
#include <stdio.h>
#include <fcntl.h>
#include "getopt.h"
#include "signame.h"
#ifndef L_SET
#define L_SET 0
#define L_INCR 1
#endif
#ifndef X_OK
#define X_OK 1
#endif
#ifdef USG
#define bzero(s, n) (memset ((s), 0, (n)))
#define gettimeofday(TV,TZ) (time (TV))
#define seconds(TV) TV
long time();
#else
#define seconds(TV) TV.tv_sec
#include <sys/time.h>
#endif
#ifdef USG
#define vfork fork
#endif
void touch_symdefs ();
void usage ();
/* The makefile generates a -D switch to define AR_PROG
as the location of the GNU `ar' program. */
char *prog = AR_PROG;
/* The first place we look for `ar', before trying `prog'. */
char *prog_pref = "/usr/local/gnubin/ar";
/* The name this program was run with. */
char *program_name;
void
main (argc, argv)
int argc;
char **argv;
{
static int touch = 0, verbose = 0;
static char short_opts[] = "tv";
static struct option long_opts[] =
{
{ "touch", 0, &touch, 0 },
{ "verbose", 0, &verbose, 0 },
{ 0, 0, 0, 0 }
};
register int c;
char *args;
int longind;
char *ar_program;
program_name = argv[0];
while ((c = getopt_long (argc, argv, short_opts, long_opts, &longind))
!= EOF)
switch (c)
{
case 't':
touch = 1;
break;
case 'v':
verbose = 1;
break;
default:
usage ();
}
if (optind == argc)
usage ();
if (access (prog_pref, X_OK) == 0)
ar_program = prog_pref;
else
ar_program = prog;
args = verbose ? "rsv" : "rs";
if (touch)
touch_symdefs (argc - optind, argv + optind);
else
{
register int i;
for (i = optind; i < argc; ++i)
{
int pid;
if (verbose)
printf ("%s %s %s\n", ar_program, args, argv[i]);
fflush (stdout);
fflush (stderr);
pid = vfork ();
if (pid < 0)
{
fprintf (stderr, "%s: can not ", program_name);
perror ("vfork");
}
else if (pid == 0)
{
/* Child side. */
execl (ar_program, ar_program, args, argv[i], 0);
fprintf (stderr, "%s: can not run ", program_name);
perror (ar_program);
exit (1);
}
else
{
/* Parent side. */
int status;
if (wait (&status) != pid)
{
fprintf (stderr, "%s: interrupted during ", program_name);
perror ("wait");
}
if ((status & 0x7f) != 0)
{
psignal (status & 0x7f, ar_program);
exit (1);
}
else if (((status & 0xff00) >> 8) != 0)
exit ((status & 0xff00) >> 8);
}
}
}
exit (0);
}
/* "touch" the archive files listed in LARGV, containing LARGC elements.
Find the first symdef member in them and update the date to the
current one. */
void
touch_symdefs (largc, largv)
int largc;
char **largv;
{
#ifdef USG
long tv;
#else
struct timeval tv;
struct timezone tz;
#endif
struct ar_hdr archive_header;
int i, rr;
gettimeofday (&tv, &tz);
while (largc--)
{
int fd = open (*largv, O_RDWR);
if (fd < 0)
{
fprintf (stderr, "%s: can not open `%s' for ", program_name, *largv);
perror ("read/write");
largv++;
continue;
}
lseek (fd, SARMAG, L_SET);
rr = read (fd, &archive_header, sizeof (archive_header));
/* In the general case this loop would be sped up by buffering,
but in almost all cases the symdef will be the first member, so
I'm not going to bother. */
while (rr == sizeof (archive_header))
{
if (!strncmp ("__.SYMDEF", archive_header.ar_name,
sizeof ("__.SYMDEF") - 1))
{
bzero ((char *) archive_header.ar_date,
sizeof (archive_header.ar_date));
sprintf (archive_header.ar_date, "%d", seconds (tv));
for (i = 0; i < sizeof archive_header.ar_date; i++)
if (archive_header.ar_date[i] == '\0')
archive_header.ar_date[i] = ' ';
lseek (fd, - rr, L_INCR);
write (fd, &archive_header, sizeof (archive_header));
close (fd);
break;
}
lseek (fd, atoi (archive_header.ar_size), L_INCR);
rr = read (fd, &archive_header, sizeof (archive_header));
}
if (rr != sizeof (archive_header))
/* We reached the end of the file. */
fprintf (stderr, "%s: can not find `__.SYMDEF' member in `%s'\n",
program_name, *largv);
largv++;
}
}
void
usage ()
{
fprintf (stderr, "Usage: %s [-tv] [+touch] [+verbose] archive...\n",
program_name);
exit (1);
}