diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2008-02-13 10:20:37 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2008-02-13 10:20:37 -0800 |
commit | ece22163b2913af4823bc4aad397a7e32dc5d4e0 (patch) | |
tree | 6fed87d929401b49319a7f23ab61ce2180e71196 | |
parent | b581a5923ce164af5c8cd5634f4cba4fd098f711 (diff) |
1.0-71671.0-7167
-rw-r--r-- | files.c | 16 | ||||
-rw-r--r-- | format.c | 61 | ||||
-rw-r--r-- | format.h | 2 | ||||
-rw-r--r-- | kernel.c | 69 | ||||
-rw-r--r-- | log.c | 9 | ||||
-rw-r--r-- | misc.c | 82 | ||||
-rw-r--r-- | misc.h | 35 | ||||
-rw-r--r-- | user-interface.c | 65 |
8 files changed, 159 insertions, 180 deletions
@@ -394,7 +394,13 @@ void select_tls_class(Options *op, Package *p) for (i = 0; i < p->num_entries; i++) { if ((p->entries[i].flags & FILE_CLASS_NEW_TLS) && (p->entries[i].flags & FILE_CLASS_NATIVE)) { - nvfree(p->entries[i].dst); + /* + * XXX don't try to free the destination string for + * these invalidated TLS libraries; this prevents + * a crash on some Slackware 10.0 installations that + * I've been unable to reproduce/root cause. + */ + /* nvfree(p->entries[i].dst); */ p->entries[i].flags &= ~FILE_TYPE_MASK; p->entries[i].dst = NULL; } @@ -433,7 +439,13 @@ void select_tls_class(Options *op, Package *p) for (i = 0; i < p->num_entries; i++) { if ((p->entries[i].flags & FILE_CLASS_NEW_TLS) && (p->entries[i].flags & FILE_CLASS_COMPAT32)) { - nvfree(p->entries[i].dst); + /* + * XXX don't try to free the destination string for + * these invalidated TLS libraries; this prevents + * a crash on some Slackware 10.0 installations that + * I've been unable to reproduce/root cause. + */ + /* nvfree(p->entries[i].dst); */ p->entries[i].flags &= ~FILE_TYPE_MASK; p->entries[i].dst = NULL; } @@ -41,6 +41,24 @@ static unsigned short __terminal_width = 0; #define DEFAULT_WIDTH 75 +/* + * Format and display a printf style string such that it fits within + * the terminal width + */ + +#define NV_VFORMAT(stream, wb, prefix, fmt) \ +do { \ + char *buf; \ + NV_VSNPRINTF(buf, fmt); \ + vformat(stream, wb, prefix, buf); \ + free (buf); \ +} while(0) + + +static void vformat(FILE *stream, const int wb, + const char *prefix, const char *buf); + + /* * reset_current_terminal_width() - if new_val is zero, then use the * TIOCGWINSZ ioctl to get the current width of the terminal, and @@ -73,11 +91,7 @@ void reset_current_terminal_width(unsigned short new_val) void fmtout(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vformat(stdout, TRUE, NULL, fmt, ap); - va_end(ap); + NV_VFORMAT(stdout, TRUE, NULL, fmt); } /* fmtout() */ @@ -90,11 +104,7 @@ void fmtout(const char *fmt, ...) void fmtoutp(const char *prefix, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vformat(stdout, TRUE, prefix, fmt, ap); - va_end(ap); + NV_VFORMAT(stdout, TRUE, prefix, fmt); } /* fmtoutp() */ @@ -107,11 +117,7 @@ void fmtoutp(const char *prefix, const char *fmt, ...) void fmterr(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vformat(stderr, TRUE, NULL, fmt, ap); - va_end(ap); + NV_VFORMAT(stderr, TRUE, NULL, fmt); } /* fmterr() */ @@ -124,11 +130,7 @@ void fmterr(const char *fmt, ...) void fmterrp(const char *prefix, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vformat(stderr, TRUE, prefix, fmt, ap); - va_end(ap); + NV_VFORMAT(stderr, TRUE, prefix, fmt); } /* fmterrp() */ @@ -136,7 +138,7 @@ void fmterrp(const char *prefix, const char *fmt, ...) /* * format() & vformat() - these takes a printf-style format string and - * a variable list of args. We use assemble_string to generate the + * a variable list of args. We use NV_VSNPRINTF to generate the * desired string, and then call nv_format_text_rows() to format the * string so that not more than __terminal_width characters are * printed across. @@ -151,29 +153,24 @@ void fmterrp(const char *prefix, const char *fmt, ...) void format(FILE *stream, const char *prefix, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vformat(stream, TRUE, prefix, fmt, ap); - va_end(ap); + NV_VFORMAT(stream, TRUE, prefix, fmt); } /* format() */ -void vformat(FILE *stream, const int wb, - const char *prefix, const char *fmt, va_list ap) + + +static void vformat(FILE *stream, const int wb, + const char *prefix, const char *buf) { - char *buf; int i; TextRows *t; if (!__terminal_width) reset_current_terminal_width(0); - buf = assemble_string(fmt, ap); t = nv_format_text_rows(prefix, buf, __terminal_width, wb); for (i = 0; i < t->n; i++) fprintf(stream, "%s\n", t->t[i]); nv_free_text_rows(t); - free(buf); -} /* vformat_b() */ +} /* vformat() */ @@ -37,7 +37,5 @@ void fmtoutp(const char *prefix, const char *fmt, ...); void fmterr(const char *fmt, ...); void fmterrp(const char *prefix, const char *fmt, ...); void format(FILE *stream, const char *prefix, const char *fmt, ...); -void vformat(FILE *stream, const int wb, - const char *prefix, const char *fmt, va_list ap); #endif /* __NVIDIA_INSTALLER_FORMAT_H__ */ @@ -28,6 +28,7 @@ #include <sys/utsname.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/sysctl.h> #include <ctype.h> #include <stdlib.h> #include <dirent.h> @@ -52,7 +53,7 @@ static int rmmod_kernel_module(Options *op, const char *); static PrecompiledInfo *download_updated_kernel_interface(Options*, Package*, const char*); static int rivafb_check(Options *op, Package *p); -static void rivafb_module_check(Options *op, Package *p); +static void change_page_attr_check(Options *op, Package *p); static PrecompiledInfo *scan_dir(Options *op, Package *p, const char *directory_name, @@ -450,7 +451,7 @@ int build_kernel_module(Options *op, Package *p) } if (!rivafb_check(op, p)) return FALSE; - rivafb_module_check(op, p); + change_page_attr_check(op, p); cmd = nvstrcat("cd ", p->kernel_module_build_directory, "; make print-module-filename", @@ -627,15 +628,14 @@ int build_kernel_interface(Options *op, Package *p) /* * test_kernel_module() - attempt to insmod the kernel module and then * rmmod it. Return TRUE if the insmod succeeded, or FALSE otherwise. - * - * Pass the special silence_nvidia_output option to the kernel module - * to prevent any console output while testing. */ int test_kernel_module(Options *op, Package *p) { char *cmd = NULL, *data; - int ret; + int old_loglevel, new_loglevel = 0; + int ret, name[] = { CTL_KERN, KERN_PRINTK }; + size_t len = sizeof(int); /* * If we're building/installing for a different kernel, then we @@ -644,10 +644,20 @@ int test_kernel_module(Options *op, Package *p) if (op->kernel_name) return TRUE; + /* + * Temporarily disable most console messages to keep the curses + * interface from being clobbered when the module is loaded. + * Save the original console loglevel to allow restoring it once + * we're done. + */ + if (!sysctl(name, 2, &old_loglevel, &len, NULL, 0)) { + new_loglevel = 2; /* KERN_CRIT */ + sysctl(name, 2, NULL, 0, &new_loglevel, len); + } + cmd = nvstrcat(op->utils[INSMOD], " ", p->kernel_module_build_directory, "/", - p->kernel_module_filename, " silence_nvidia_output=1", - NULL); + p->kernel_module_filename, NULL); /* only output the result of the test if in expert mode */ @@ -677,7 +687,7 @@ int test_kernel_module(Options *op, Package *p) */ cmd = nvstrcat(op->utils[DMESG], " | ", - op->utils[TAIL], " -n 5", NULL); + op->utils[TAIL], " -n 15", NULL); if (!run_command(op, cmd, &data, FALSE, 0, TRUE)) ui_log(op, "Kernel messages:\n%s", data); @@ -697,6 +707,8 @@ int test_kernel_module(Options *op, Package *p) if (cmd) free(cmd); if (data) free(data); + if (new_loglevel != 0) sysctl(name, 2, NULL, 0, &old_loglevel, len); + return ret; } /* test_kernel_module() */ @@ -1408,6 +1420,16 @@ int check_cc_version(Options *op, Package *p) return TRUE; } + /* + * Check if the libc development headers are installed; we need + * these to build the gcc version check utility. + */ + if (access("/usr/include/stdio.h", F_OK) == -1) { + ui_error(op, "You do not appear to have libc header files " + "installed on your system. Please install your " + "distribution's libc development package."); + return FALSE; + } CC = getenv("CC"); if (!CC) CC = "cc"; @@ -1478,37 +1500,34 @@ static int rivafb_check(Options *op, Package *p) } /* rivafb_check() */ - /* - * rivafb_module_check() - run the rivafb_module_sanity_check - * conftest; if the test prints anything, print the warning text - * outputted by the test. + * change_page_attr_check() - run the change_page_attr_sanity_check + * conftest; if the test fails, print a warning messages, but continue + * the installation. */ -static void rivafb_module_check(Options *op, Package *p) +static void change_page_attr_check(Options *op, Package *p) { +#if defined(NV_X86_64) char *cmd, *result; int ret; - - ui_log(op, "Performing rivafb module check."); - + + ui_log(op, "Performing change_page_attr() check."); + cmd = nvstrcat("sh ", p->kernel_module_build_directory, "/conftest.sh cc ", op->kernel_source_path, " ", op->kernel_output_path, " ", - "rivafb_module_sanity_check just_msg", NULL); + "change_page_attr_sanity_check just_msg", NULL); ret = run_command(op, cmd, &result, FALSE, 0, TRUE); - nvfree(cmd); - - if (result && result[0]) { - ui_warn(op, result); - } - + + if (result && *result) ui_warn(op, result); nvfree(result); -} /* rivafb_module_check() */ +#endif /* NV_X86_64 */ +} @@ -186,13 +186,10 @@ void log_printf(Options *op, const int wb, char *buf; int i; TextRows *t; - va_list ap; - + if (!op->logging) return; - va_start(ap, fmt); - - buf = assemble_string(fmt, ap); + NV_VSNPRINTF(buf, fmt); t = nv_format_text_rows(prefix, buf, LOG_WIDTH, wb); for (i = 0; i < t->n; i++) fprintf(log_file_stream, "%s\n", t->t[i]); @@ -200,8 +197,6 @@ void log_printf(Options *op, const int wb, nv_free_text_rows(t); nvfree(buf); - va_end(ap); - /* flush, just to be safe */ fflush(log_file_stream); @@ -232,62 +232,6 @@ char *read_next_word (char *buf, char **e) /* - * assemble_string() - takes a fmt string and a va_list, and uses - * vsnprintf to build the resulting string. The caller of this - * function is responsible for freeing the returned string. - * - * XXX replace this with a macro (see X driver sources) - */ - -char *assemble_string(const char *fmt, va_list ap) -{ - char *buf; - int current_len, len, done; - - if (!fmt) return NULL; - - done = FALSE; - current_len = NV_LINE_LEN; - - do { - buf = (char *) nvalloc (current_len); - - len = vsnprintf (buf, current_len, fmt, ap); - - if ((len == -1) || len > current_len) { - - /* - * if we get in here we know that vsnprintf had to - * truncate the string to make it fit in the buffer... we - * need to extend the buffer to encompass the string. - * Unfortunately, we have to deal with two different - * semantics of the return value from (v)snprintf: - * - * -1 when the buffer is not long enough (glibc < 2.1) - * - * or - * - * the length the string would have been if the buffer had - * been large enough (glibc >= 2.1) - */ - - if (len == -1) current_len += NV_LINE_LEN; - else current_len = len+1; - - free (buf); - } - else done = TRUE; - - } while (!done); - - return buf; - -} /* assemble_string() */ - - - - -/* * check_euid() - this function checks that the effective uid of this * application is root, and calls the ui to print an error if it's not * root. @@ -876,11 +820,8 @@ int continue_after_error(Options *op, const char *fmt, ...) { char *msg; int ret; - va_list ap; - va_start (ap, fmt); - msg = assemble_string (fmt, ap); - va_end (ap); + NV_VSNPRINTF(msg, fmt); ret = ui_yes_no(op, TRUE, "The installer has encountered the following " "error during installation: '%s'. Continue anyway? " @@ -1395,6 +1336,26 @@ int check_runtime_configuration(Options *op, Package *p) /* + * collapse_multiple_slashes() - remove any/all occurances of "//" from the + * argument string. + */ + +void collapse_multiple_slashes(char *s) +{ + char *p; + unsigned int i, len; + + while ((p = strstr(s, "//")) != NULL) { + p++; /* advance to second '/' */ + while (*p == '/') { + len = strlen(p); + for (i = 0; i < len; i++) p[i] = p[i+1]; + } + } +} + + +/* * rtld_test_internal() - this routine writes the test binaries to a file * and performs the test; the caller (rtld_test()) selects which array data * is used (native, compat_32). @@ -1474,6 +1435,7 @@ static int rtld_test_internal(Options *op, Package *p, name = nvstrdup(p->entries[i].dst); if (!name) goto next; + collapse_multiple_slashes(data); s = strstr(name, ".so.1"); if (!s) goto next; *(s + strlen(".so.1")) = '\0'; @@ -30,10 +30,45 @@ #include <stdio.h> #include <stdarg.h> +#include <stdlib.h> #include "nvidia-installer.h" #include "command-list.h" +/* + * NV_VSNPRINTF() - takes a fmt string, and uses vsnprintf to build + * the resulting string whic it assigns to buf. The caller of this + * function is responsible for freeing the returned string. + */ +#define NV_VSNPRINTF(buf, fmt) \ +do { \ + if (!fmt) { \ + (buf) = NULL; \ + } else { \ + va_list ap; \ + int len, current_len = NV_LINE_LEN; \ + \ + (buf) = malloc(current_len); \ + \ + while (1) { \ + va_start(ap, fmt); \ + len = vsnprintf((buf), current_len, (fmt), ap); \ + va_end(ap); \ + \ + if ((len > -1) && (len < current_len)) { \ + break; \ + } else if (len > -1) { \ + current_len = len + 1; \ + } else { \ + current_len += NV_LINE_LEN; \ + } \ + \ + (buf) = realloc(buf, current_len); \ + } \ + } \ +} while (0) + + void *nvalloc(size_t size); void *nvrealloc(void *ptr, size_t size); char *nvstrdup(const char *s); diff --git a/user-interface.c b/user-interface.c index 4bfed83..1ec24ea 100644 --- a/user-interface.c +++ b/user-interface.c @@ -175,13 +175,10 @@ int ui_init(Options *op) void ui_set_title(Options *op, const char *fmt, ...) { char *title; - va_list ap; if (op->silent) return; - va_start(ap, fmt); - title = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(title, fmt); __ui->set_title(op, title); free(title); @@ -197,11 +194,8 @@ void ui_set_title(Options *op, const char *fmt, ...) char *ui_get_input(Options *op, const char *def, const char *fmt, ...) { char *msg, *tmp = NULL, *ret; - va_list ap; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); if (op->no_questions) { ret = nvstrdup(def ? def : ""); @@ -244,11 +238,8 @@ int ui_display_license (Options *op, const char *license) void ui_error(Options *op, const char *fmt, ...) { char *msg; - va_list ap; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); __ui->message(op, NV_MSG_LEVEL_ERROR, msg); log_printf(op, TRUE, "ERROR: ", msg); @@ -262,11 +253,8 @@ void ui_error(Options *op, const char *fmt, ...) void ui_warn(Options *op, const char *fmt, ...) { char *msg; - va_list ap; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); __ui->message(op, NV_MSG_LEVEL_WARNING, msg); log_printf(op, TRUE, "WARNING: ", msg); @@ -280,11 +268,8 @@ void ui_warn(Options *op, const char *fmt, ...) void ui_message(Options *op, const char *fmt, ...) { char *msg; - va_list ap; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); if (!op->silent) __ui->message(op, NV_MSG_LEVEL_MESSAGE, msg); @@ -298,11 +283,8 @@ void ui_message(Options *op, const char *fmt, ...) void ui_log(Options *op, const char *fmt, ...) { char *msg; - va_list ap; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); if (!op->silent) __ui->message(op, NV_MSG_LEVEL_LOG, msg); log_printf(op, TRUE, NV_BULLET_STR, msg); @@ -320,13 +302,10 @@ void ui_log(Options *op, const char *fmt, ...) void ui_expert(Options *op, const char *fmt, ...) { char *msg; - va_list ap; if (!op->expert) return; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); if (!op->silent) __ui->message(op, NV_MSG_LEVEL_LOG, msg); log_printf(op, FALSE, NV_BULLET_STR, msg); @@ -340,11 +319,8 @@ void ui_expert(Options *op, const char *fmt, ...) void ui_command_output(Options *op, const char *fmt, ...) { char *msg; - va_list ap; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); if (!op->silent) __ui->command_output(op, msg); @@ -364,13 +340,10 @@ int ui_approve_command_list(Options *op, CommandList *c, const char *fmt, ...) { char *msg; int ret; - va_list ap; if (!op->expert || op->no_questions) return TRUE; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); ret = __ui->approve_command_list(op, c, msg); free(msg); @@ -391,11 +364,8 @@ int ui_yes_no (Options *op, const int def, const char *fmt, ...) { char *msg, *tmp = NULL; int ret; - va_list ap; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); if (op->no_questions) { ret = def; @@ -421,15 +391,12 @@ int ui_yes_no (Options *op, const int def, const char *fmt, ...) void ui_status_begin(Options *op, const char *title, const char *fmt, ...) { char *msg; - va_list ap; log_printf(op, TRUE, NV_BULLET_STR, title); if (op->silent) return; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); __ui->status_begin(op, title, msg); free(msg); @@ -440,13 +407,10 @@ void ui_status_begin(Options *op, const char *title, const char *fmt, ...) void ui_status_update(Options *op, const float percent, const char *fmt, ...) { char *msg; - va_list ap; if (op->silent) return; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); __ui->status_update(op, percent, msg); free(msg); @@ -457,11 +421,8 @@ void ui_status_update(Options *op, const float percent, const char *fmt, ...) void ui_status_end(Options *op, const char *fmt, ...) { char *msg; - va_list ap; - va_start(ap, fmt); - msg = assemble_string(fmt, ap); - va_end(ap); + NV_VSNPRINTF(msg, fmt); if (!op->silent) __ui->status_end(op, msg); log_printf(op, TRUE, NV_BULLET_STR, msg); |