1 |
vapier 11/03/01 04:20:19 |
2 |
|
3 |
Modified: q.c |
4 |
Log: |
5 |
rewrite `q -i` to delay its execution after parsing all opts, respect --quiet, and avoid using chdir() to allow execution from other applets |
6 |
|
7 |
Revision Changes Path |
8 |
1.51 portage-utils/q.c |
9 |
|
10 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/q.c?rev=1.51&view=markup |
11 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/q.c?rev=1.51&content-type=text/plain |
12 |
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/q.c?r1=1.50&r2=1.51 |
13 |
|
14 |
Index: q.c |
15 |
=================================================================== |
16 |
RCS file: /var/cvsroot/gentoo-projects/portage-utils/q.c,v |
17 |
retrieving revision 1.50 |
18 |
retrieving revision 1.51 |
19 |
diff -u -r1.50 -r1.51 |
20 |
--- q.c 28 Feb 2011 18:15:32 -0000 1.50 |
21 |
+++ q.c 1 Mar 2011 04:20:19 -0000 1.51 |
22 |
@@ -1,7 +1,7 @@ |
23 |
/* |
24 |
* Copyright 2005-2010 Gentoo Foundation |
25 |
* Distributed under the terms of the GNU General Public License v2 |
26 |
- * $Header: /var/cvsroot/gentoo-projects/portage-utils/q.c,v 1.50 2011/02/28 18:15:32 vapier Exp $ |
27 |
+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/q.c,v 1.51 2011/03/01 04:20:19 vapier Exp $ |
28 |
* |
29 |
* Copyright 2005-2010 Ned Ludd - <solar@g.o> |
30 |
* Copyright 2005-2010 Mike Frysinger - <vapier@g.o> |
31 |
@@ -22,7 +22,7 @@ |
32 |
"Module path", |
33 |
COMMON_OPTS_HELP |
34 |
}; |
35 |
-static const char q_rcsid[] = "$Id: q.c,v 1.50 2011/02/28 18:15:32 vapier Exp $"; |
36 |
+static const char q_rcsid[] = "$Id: q.c,v 1.51 2011/03/01 04:20:19 vapier Exp $"; |
37 |
#define q_usage(ret) usage(ret, Q_FLAGS, q_long_opts, q_opts_help, lookup_applet_idx("q")) |
38 |
|
39 |
static APPLET lookup_applet(const char *applet) |
40 |
@@ -66,7 +66,7 @@ |
41 |
|
42 |
int q_main(int argc, char **argv) |
43 |
{ |
44 |
- int i; |
45 |
+ int i, install; |
46 |
const char *p; |
47 |
APPLET func; |
48 |
|
49 |
@@ -83,38 +83,58 @@ |
50 |
if (argc == 1) |
51 |
q_usage(EXIT_FAILURE); |
52 |
|
53 |
+ install = 0; |
54 |
+ |
55 |
while ((i = GETOPT_LONG(Q, q, "+")) != -1) { |
56 |
switch (i) { |
57 |
COMMON_GETOPTS_CASES(q) |
58 |
case 'M': modpath = optarg; break; |
59 |
case 'm': reinitialize_metacache = 1; break; |
60 |
case 'r': reinitialize = 1; break; |
61 |
- case 'i': { |
62 |
- char buf[_Q_PATH_MAX]; |
63 |
- /* always bzero a buffer before using readlink() */ |
64 |
- memset(buf, 0x00, sizeof(buf)); |
65 |
+ case 'i': install = 1; break; |
66 |
+ } |
67 |
+ } |
68 |
+ |
69 |
+ if (install) { |
70 |
+ char buf[_Q_PATH_MAX]; |
71 |
+ ssize_t rret; |
72 |
+ int fd, ret; |
73 |
+ |
74 |
+ if (!quiet) |
75 |
printf("Installing symlinks:\n"); |
76 |
- /* solaris: /proc/self/object/a.out bsd: /proc/self/exe or /proc/curproc/file with linuxfs/procfs respectively */ |
77 |
- if (readlink("/proc/self/exe", buf, sizeof(buf) - 1) == -1) { |
78 |
- char *ptr = which("q"); |
79 |
- if (ptr == NULL) { |
80 |
- warnfp("haha no symlink love for you"); |
81 |
- return 1; |
82 |
- } |
83 |
- strncpy(buf, ptr, sizeof(buf)); |
84 |
- } |
85 |
- if (chdir(dirname(buf)) != 0) { |
86 |
- warnfp("could not chdir to '%s'", buf); |
87 |
+ |
88 |
+ rret = readlink("/proc/self/exe", buf, sizeof(buf) - 1); |
89 |
+ if (rret == -1) { |
90 |
+ char *ptr = which("q"); |
91 |
+ if (ptr == NULL) { |
92 |
+ warnfp("haha no symlink love for you"); |
93 |
return 1; |
94 |
} |
95 |
- for (i = 1; applets[i].desc != NULL; ++i) { |
96 |
- printf(" %s ...\t[%s]\n", applets[i].name, |
97 |
- symlink("q", applets[i].name) ? strerror(errno) : "OK"); |
98 |
- } |
99 |
- return 0; |
100 |
+ strncpy(buf, ptr, sizeof(buf)); |
101 |
+ buf[sizeof(buf) - 1] = '\0'; |
102 |
+ } else |
103 |
+ buf[rret] = '\0'; |
104 |
+ |
105 |
+ fd = open(dirname(buf), O_RDONLY|O_CLOEXEC); |
106 |
+ if (fd < 0) { |
107 |
+ warnfp("chdir(%s) failed", buf); |
108 |
+ return 1; |
109 |
} |
110 |
+ |
111 |
+ ret = 0; |
112 |
+ for (i = 1; applets[i].desc; ++i) { |
113 |
+ int r = symlinkat(buf, fd, applets[i].name); |
114 |
+ if (!quiet) |
115 |
+ printf(" %s ...\t[%s]\n", applets[i].name, r ? strerror(errno) : "OK"); |
116 |
+ if (r && errno != EEXIST) |
117 |
+ ret = 1; |
118 |
} |
119 |
+ |
120 |
+ close(fd); |
121 |
+ |
122 |
+ return ret; |
123 |
} |
124 |
+ |
125 |
if (reinitialize || reinitialize_metacache) |
126 |
return 0; |
127 |
if (argc == optind) |