On Thu Jul 17 15:53:12 2008, julianalbo wrote: > On Thu, Jul 17, 2008 at 9:59 PM, Christoph Otto via RT > <[EMAIL PROTECTED]> wrote: > > > With this patch, the new tests still pass on Linux/x86. The patch uses > > STRING->strstart to avoid leaking a malloc'd buffer when throwing an > > exception, which may or may not be considered kosher in this situation. > > Can't you use real_exception(interp, NULL, E_SystemError, "%Ss", > errmsg_pstring); ? > > Using internal details of parrot strings must be avoided. >
I agree. I just didn't know real_exception was smart enough to do that trick. The attached patch (v5) properly fixes the problem on my system. There shouldn't be any remaining issues, but the patch ought to be tested on a another *nix and Windows.
Index: src/pmc/file.pmc =================================================================== --- src/pmc/file.pmc (revision 29551) +++ src/pmc/file.pmc (working copy) @@ -26,6 +26,21 @@ /* RT#46681 apparently, strerror_r is thread-safe and should be used instead.*/ +/* strerror_r should truncate the message if its too long for the supplied buffer + * it's probably best to just specify a sane default buffer size than to worry + * about retrying calls + */ +#define ERRBUF_SIZE 128 + +#define STRERROR_R_EXCEPTION() \ + { \ + char errmsg[ERRBUF_SIZE]; \ + char *errstr = strerror_r(errno, errmsg, ERRBUF_SIZE); \ + STRING *errmsg_pstring = string_make(interp, errstr, strlen(errstr), NULL, 0); \ + real_exception(interp, NULL, E_SystemError, "%Ss", errmsg_pstring); \ + } + + static PMC *File_PMC; pmclass File singleton { @@ -89,6 +104,7 @@ */ + METHOD is_dir(STRING *path) { struct stat info; char *cpath = string_to_cstring(interp, path); @@ -100,8 +116,7 @@ string_cstring_free(cpath); if (error) { - char *errmsg = strerror(errno); - real_exception(interp, NULL, E_SystemError, errmsg); + STRERROR_R_EXCEPTION(); } if (S_ISDIR(info.st_mode)) @@ -131,8 +146,7 @@ string_cstring_free(cpath); if (error) { - char *errmsg = strerror(errno); - real_exception(interp, NULL, E_SystemError, errmsg); + STRERROR_R_EXCEPTION(); } if (S_ISREG(info.st_mode)) @@ -164,8 +178,7 @@ string_cstring_free(cpath); if (error) { - char *errmsg = strerror(errno); - real_exception(interp, NULL, E_SystemError, errmsg); + STRERROR_R_EXCEPTION(); } if (S_ISLNK(info.st_mode)) @@ -199,6 +212,8 @@ string_cstring_free(cfrom); + char errmsg[ERRBUF_SIZE]; + if (source) { char *cto = string_to_cstring(interp, to); FILE *target = fopen(cto, "w+b"); @@ -223,14 +238,12 @@ fclose(target); } else { - char *errmsg = strerror(errno); - real_exception(interp, NULL, E_SystemError, errmsg); + STRERROR_R_EXCEPTION(); } fclose(source); } else { - char *errmsg = strerror(errno); - real_exception(interp, NULL, E_SystemError, errmsg); + STRERROR_R_EXCEPTION(); } #undef CHUNK_SIZE } @@ -254,8 +267,7 @@ string_cstring_free(cto); if (error) { - char *errmsg = strerror(errno); - real_exception(interp, NULL, E_SystemError, errmsg); + STRERROR_R_EXCEPTION(); } } } Index: config/gen/platform/win32/string.h =================================================================== --- config/gen/platform/win32/string.h (revision 29551) +++ config/gen/platform/win32/string.h (working copy) @@ -14,6 +14,8 @@ # endif #endif +#define strerror_r(errnum, buf, buflen) strerror_s((buf), (buflen), (errnum)) + #endif /* PARROT_PLATFORM_WIN32_STRING_H_GUARD */ /*