40 # include <avo/strings.h> /* AVO_STRDUP() */
41 #if defined(DISTRIBUTED)
42 # include <dm/Avo_CmdOutput.h>
43 # include <rw/xdrstrea.h>
44 #endif
45 #endif
46
47 #include <stdio.h> /* errno */
48 #include <errno.h> /* errno */
49 #include <fcntl.h> /* open() */
50 #include <mksh/dosys.h>
51 #include <mksh/macro.h> /* getvar() */
52 #include <mksh/misc.h> /* getmem(), fatal_mksh(), errmsg() */
53 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
54 #include <sys/signal.h> /* SIG_DFL */
55 #include <sys/stat.h> /* open() */
56 #include <sys/wait.h> /* wait() */
57 #include <ulimit.h> /* ulimit() */
58 #include <unistd.h> /* close(), dup2() */
59
60 #if defined (HP_UX) || defined (linux)
61 # include <sys/param.h>
62 # include <wctype.h>
63 # include <wchar.h>
64 #endif
65
66 #if defined (linux)
67 # define wslen(x) wcslen(x)
68 # define wscpy(x,y) wcscpy(x,y)
69 #endif
70
71 /*
72 * Defined macros
73 */
74 #if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
75 #define SEND_MTOOL_MSG(cmds) \
76 if (send_mtool_msgs) { \
77 cmds \
78 }
79 #else
80 #define SEND_MTOOL_MSG(cmds)
81 #endif
82
83 /*
84 * typedefs & structs
85 */
86
87 /*
88 * Static variables
89 */
90
91 /*
92 * File table of contents
93 */
94 static Boolean exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path);
95
96 /*
97 * Workaround for NFS bug. Sometimes, when running 'open' on a remote
98 * dmake server, it fails with "Stale NFS file handle" error.
99 * The second attempt seems to work.
100 */
101 int
102 my_open(const char *path, int oflag, mode_t mode) {
103 int res = open(path, oflag, mode);
104 #ifdef linux
105 // Workaround for NFS problem: even when all directories in 'path'
106 // exist, 'open' (file creation) fails with ENOENT.
107 int nattempt = 0;
108 while (res < 0 && (errno == ESTALE || errno == EAGAIN || errno == ENOENT)) {
109 nattempt++;
110 if(nattempt > 30) {
111 break;
112 }
113 sleep(1);
114 #else
115 if (res < 0 && (errno == ESTALE || errno == EAGAIN)) {
116 #endif
117 /* Stale NFS file handle. Try again */
118 res = open(path, oflag, mode);
119 }
120 return res;
121 }
122
123 /*
124 * void
125 * redirect_io(char *stdout_file, char *stderr_file)
126 *
127 * Redirects stdout and stderr for a child mksh process.
128 */
129 void
130 redirect_io(char *stdout_file, char *stderr_file)
131 {
132 long descriptor_limit;
133 int i;
134
135 #if defined (HP_UX) || defined (linux)
136 /*
137 * HP-UX does not support the UL_GDESLIM command for ulimit().
138 * NOFILE == max num open files per process (from <sys/param.h>)
139 */
140 descriptor_limit = NOFILE;
141 #else
142 if ((descriptor_limit = ulimit(UL_GDESLIM)) < 0) {
143 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 89, "ulimit() failed: %s"), errmsg(errno));
144 }
145 #endif
146 for (i = 3; i < descriptor_limit; i++) {
147 (void) close(i);
148 }
149 if ((i = my_open(stdout_file,
150 O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
151 S_IREAD | S_IWRITE)) < 0) {
152 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 90, "Couldn't open standard out temp file `%s': %s"),
153 stdout_file,
154 errmsg(errno));
155 } else {
156 if (dup2(i, 1) == -1) {
157 fatal_mksh(NOCATGETS("*** Error: dup2(3, 1) failed: %s"),
158 errmsg(errno));
159 }
160 close(i);
161 }
162 if (stderr_file == NULL) {
163 if (dup2(1, 2) == -1) {
164 fatal_mksh(NOCATGETS("*** Error: dup2(1, 2) failed: %s"),
165 errmsg(errno));
327 if (IS_EQUAL(shell->string_mb, "")) {
328 shell = shell_name;
329 }
330 if ((shellname = strrchr(shell->string_mb, (int) slash_char)) == NULL) {
331 shellname = shell->string_mb;
332 } else {
333 shellname++;
334 }
335
336 /*
337 * Only prepend the /usr/bin/nice command to the original command
338 * if the nice priority, nice_prio, is NOT zero (0).
339 * Nice priorities can be a positive or a negative number.
340 */
341 if (nice_prio != 0) {
342 argv[argv_index++] = (char *)NOCATGETS("nice");
343 (void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
344 argv[argv_index++] = strdup(nice_prio_buf);
345 }
346 argv[argv_index++] = shellname;
347 #if defined(linux)
348 if(0 == strcmp(shell->string_mb, (char*)NOCATGETS("/bin/sh"))) {
349 argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
350 } else {
351 argv[argv_index++] = (char*)NOCATGETS("-c");
352 }
353 #else
354 argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
355 #endif
356 if ((length = wslen(command)) >= MAXPATHLEN) {
357 tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
358 (void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
359 cmd_argv_index = argv_index;
360 argv[argv_index++] = strdup(tmp_mbs_buffer);
361 retmem_mb(tmp_mbs_buffer);
362 } else {
363 WCSTOMBS(mbs_buffer, command);
364 cmd_argv_index = argv_index;
365 #if defined(linux)
366 int mbl = strlen(mbs_buffer);
367 if(mbl > 2) {
368 if(mbs_buffer[mbl-1] == '\n' && mbs_buffer[mbl-2] == '\\') {
369 mbs_buffer[mbl] = '\n';
370 mbs_buffer[mbl+1] = 0;
371 }
372 }
373 #endif
374 argv[argv_index++] = strdup(mbs_buffer);
375 }
376 argv[argv_index] = NULL;
377 (void) fflush(stdout);
378 if ((childPid = fork()) == 0) {
379 enable_interrupt((void (*) (int)) SIG_DFL);
380 if (redirect_out_err) {
381 redirect_io(stdout_file, stderr_file);
382 }
383 #if 0
384 if (filter_stderr) {
385 redirect_stderr();
386 }
387 #endif
388 if (nice_prio != 0) {
389 (void) execve(NOCATGETS("/usr/bin/nice"), argv, environ);
390 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 92, "Could not load `/usr/bin/nice': %s"),
391 errmsg(errno));
392 } else {
393 (void) execve(shell->string_mb, argv, environ);
|
40 # include <avo/strings.h> /* AVO_STRDUP() */
41 #if defined(DISTRIBUTED)
42 # include <dm/Avo_CmdOutput.h>
43 # include <rw/xdrstrea.h>
44 #endif
45 #endif
46
47 #include <stdio.h> /* errno */
48 #include <errno.h> /* errno */
49 #include <fcntl.h> /* open() */
50 #include <mksh/dosys.h>
51 #include <mksh/macro.h> /* getvar() */
52 #include <mksh/misc.h> /* getmem(), fatal_mksh(), errmsg() */
53 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
54 #include <sys/signal.h> /* SIG_DFL */
55 #include <sys/stat.h> /* open() */
56 #include <sys/wait.h> /* wait() */
57 #include <ulimit.h> /* ulimit() */
58 #include <unistd.h> /* close(), dup2() */
59
60
61
62 /*
63 * Defined macros
64 */
65 #if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
66 #define SEND_MTOOL_MSG(cmds) \
67 if (send_mtool_msgs) { \
68 cmds \
69 }
70 #else
71 #define SEND_MTOOL_MSG(cmds)
72 #endif
73
74 /*
75 * typedefs & structs
76 */
77
78 /*
79 * Static variables
80 */
81
82 /*
83 * File table of contents
84 */
85 static Boolean exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path);
86
87 /*
88 * Workaround for NFS bug. Sometimes, when running 'open' on a remote
89 * dmake server, it fails with "Stale NFS file handle" error.
90 * The second attempt seems to work.
91 */
92 int
93 my_open(const char *path, int oflag, mode_t mode) {
94 int res = open(path, oflag, mode);
95 if (res < 0 && (errno == ESTALE || errno == EAGAIN)) {
96 /* Stale NFS file handle. Try again */
97 res = open(path, oflag, mode);
98 }
99 return res;
100 }
101
102 /*
103 * void
104 * redirect_io(char *stdout_file, char *stderr_file)
105 *
106 * Redirects stdout and stderr for a child mksh process.
107 */
108 void
109 redirect_io(char *stdout_file, char *stderr_file)
110 {
111 long descriptor_limit;
112 int i;
113
114 if ((descriptor_limit = ulimit(UL_GDESLIM)) < 0) {
115 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 89, "ulimit() failed: %s"), errmsg(errno));
116 }
117 for (i = 3; i < descriptor_limit; i++) {
118 (void) close(i);
119 }
120 if ((i = my_open(stdout_file,
121 O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
122 S_IREAD | S_IWRITE)) < 0) {
123 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 90, "Couldn't open standard out temp file `%s': %s"),
124 stdout_file,
125 errmsg(errno));
126 } else {
127 if (dup2(i, 1) == -1) {
128 fatal_mksh(NOCATGETS("*** Error: dup2(3, 1) failed: %s"),
129 errmsg(errno));
130 }
131 close(i);
132 }
133 if (stderr_file == NULL) {
134 if (dup2(1, 2) == -1) {
135 fatal_mksh(NOCATGETS("*** Error: dup2(1, 2) failed: %s"),
136 errmsg(errno));
298 if (IS_EQUAL(shell->string_mb, "")) {
299 shell = shell_name;
300 }
301 if ((shellname = strrchr(shell->string_mb, (int) slash_char)) == NULL) {
302 shellname = shell->string_mb;
303 } else {
304 shellname++;
305 }
306
307 /*
308 * Only prepend the /usr/bin/nice command to the original command
309 * if the nice priority, nice_prio, is NOT zero (0).
310 * Nice priorities can be a positive or a negative number.
311 */
312 if (nice_prio != 0) {
313 argv[argv_index++] = (char *)NOCATGETS("nice");
314 (void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
315 argv[argv_index++] = strdup(nice_prio_buf);
316 }
317 argv[argv_index++] = shellname;
318 argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
319 if ((length = wslen(command)) >= MAXPATHLEN) {
320 tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
321 (void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
322 cmd_argv_index = argv_index;
323 argv[argv_index++] = strdup(tmp_mbs_buffer);
324 retmem_mb(tmp_mbs_buffer);
325 } else {
326 WCSTOMBS(mbs_buffer, command);
327 cmd_argv_index = argv_index;
328 argv[argv_index++] = strdup(mbs_buffer);
329 }
330 argv[argv_index] = NULL;
331 (void) fflush(stdout);
332 if ((childPid = fork()) == 0) {
333 enable_interrupt((void (*) (int)) SIG_DFL);
334 if (redirect_out_err) {
335 redirect_io(stdout_file, stderr_file);
336 }
337 #if 0
338 if (filter_stderr) {
339 redirect_stderr();
340 }
341 #endif
342 if (nice_prio != 0) {
343 (void) execve(NOCATGETS("/usr/bin/nice"), argv, environ);
344 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 92, "Could not load `/usr/bin/nice': %s"),
345 errmsg(errno));
346 } else {
347 (void) execve(shell->string_mb, argv, environ);
|