dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / tools / ctf / ctfstrip / ctfstrip.c
blob60180c6921022ecba679f99a04c0c48805b76cf9
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2011 Jason King. All rights reserved.
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/wait.h>
23 #include <fcntl.h>
24 #include <err.h>
25 #include <spawn.h>
27 #define MCS "/usr/bin/mcs"
29 #define ELFLEN 4
30 static const char elf_signature[] = "\177ELF";
31 static posix_spawnattr_t attr;
32 static const char *cmd[] = { MCS, "-d", "-n", ".SUNW_ctf", NULL, NULL };
34 extern char **environ;
36 static boolean_t check_file(const char *, mode_t *);
37 static boolean_t fix_file(const char *, mode_t);
38 static void usage(const char *);
40 int
41 main(int argc, const char **argv)
43 const char **p;
44 int rc = 0;
45 mode_t mode;
47 if (argc < 2)
48 usage(argv[0]);
50 rc = posix_spawnattr_init(&attr);
51 if (rc != 0) {
52 errx(EXIT_FAILURE, "Spawn attribute initialization failed: %s",
53 strerror(rc));
56 for (p = argv + 1; *p != NULL; p++) {
57 if (!check_file(*p, &mode))
58 continue;
59 if (!fix_file(*p, mode))
60 rc = 1;
63 return (rc);
66 static boolean_t
67 check_file(const char *filename, mode_t *mode)
69 char elfbuf[4];
70 struct stat sb;
71 int fd;
73 fd = open(filename, O_RDONLY);
74 if (fd == -1) {
75 warn("Unable to open %s", filename);
76 return (B_FALSE);
79 if (fstat(fd, &sb) == -1) {
80 warn("stat(2) failed on %s", filename);
81 (void) close(fd);
82 return (B_FALSE);
85 if (!S_ISREG(sb.st_mode)) {
86 warnx("%s is not a regular file", filename);
87 (void) close(fd);
88 return (B_FALSE);
91 if (sb.st_size < ELFLEN) {
92 warnx("%s is not an ELF file", filename);
93 (void) close(fd);
94 return (B_FALSE);
97 if (read(fd, elfbuf, ELFLEN) != ELFLEN) {
98 warn("Error reading %s", filename);
99 (void) close(fd);
100 return (B_FALSE);
103 if (strncmp(elfbuf, elf_signature, ELFLEN) != 0) {
104 warnx("%s is not an ELF file", filename);
105 (void) close(fd);
106 return (B_FALSE);
109 *mode = sb.st_mode & S_IAMB;
110 (void) close(fd);
111 return (B_TRUE);
114 static boolean_t
115 fix_file(const char *filename, mode_t mode)
117 pid_t pid;
118 int i, rc;
119 int stat = 0;
121 if ((mode & S_IWUSR) == 0) {
122 if (chmod(filename, mode | S_IWUSR) == -1) {
123 warn("failed to make %s writable", filename);
124 return (B_FALSE);
128 cmd[4] = filename;
129 if ((rc = posix_spawn(&pid, MCS, NULL, &attr,
130 (char *const *)cmd, environ)) != 0) {
131 warnx("could not exec mcs: %s", strerror(rc));
132 return (B_FALSE);
135 waitpid(pid, &stat, 0);
136 if (!WIFEXITED(stat) || WEXITSTATUS(stat) != 0) {
137 warnx("Removing CTF information from %s failed", filename);
138 return (B_FALSE);
141 if ((mode & S_IWUSR) == 0) {
142 if (chmod(filename, mode) == -1) {
143 warn("could not reset permissions of %s", filename);
144 return (B_FALSE);
148 return (B_TRUE);
151 static void
152 usage(const char *name)
154 (void) fprintf(stderr, "Usage: %s file...\n", name);
155 exit(EXIT_FAILURE);