Is there a way of printing out a meaningful description from the errno variable rather than just the numerical number??? This message posted from opensolaris.org
On Tue, Apr 18, 2006 at 07:32:45AM -0700, Phil Coleman wrote:> Is there a way of printing out a meaningful description from the errno > variable rather than just the numerical number???Not yet - I asked about this a long time ago, and the dtrace team responded that they''d been thinking about it, but nothing''s been implemented yet as far as I know. Feel free to file an RFE... regards john
On Tue, Apr 18, 2006 at 03:50:13PM +0100, John Levon wrote:> On Tue, Apr 18, 2006 at 07:32:45AM -0700, Phil Coleman wrote: > > > Is there a way of printing out a meaningful description from the errno > > variable rather than just the numerical number??? > > Not yet - I asked about this a long time ago, and the dtrace team responded > that they''d been thinking about it, but nothing''s been implemented yet as far > as I know. Feel free to file an RFE...I''m afraid this is an example (and hopefully a rare one) where we have let the Perfect become the enemy of the Good Enough. We decided not to add new printf format characters for errnos and signals (the other commonly requested decoding) because the printf format character is already overcrowded, and have instead thought about introducing some new scheme that allows for arbitrary new printf/printa decodings. So for example, we would envision something like this: printf("error is %<errno>\n"); Or something. But the reality is that we haven''t yet implemented this, and that (realistically) people just need a format character for errnos and signals. So maybe we''ll just come up with format characters for these two, and defer a more elaborate scheme when future decodings become required. Thoughts? What other decodings can you envision? (When Brendan and I spoke about this in Sydney, he suggested open(2) flags and fcntl(2) commands -- the former of which I actually would have used yesterday(*), so they''re definitely on the list...) - Bryan -------------------------------------------------------------------------- Bryan Cantrill, Solaris Kernel Development. http://blogs.sun.com/bmc (*) I would have used this when debugging a problem that turned out to be that -- contrary to my expectations and contrary to the expecations of the author of the script I was debugging -- the Bourne shell does not open files O_APPEND when redirecting to a file; it just seeks to EOF and starts writing. (!) The danger of relying on software that predates O_APPEND, I suppose...
> I''m afraid this is an example (and hopefully a rare one) where we have let > the Perfect become the enemy of the Good Enough. We decided not to add new > printf format characters for errnos and signals (the other commonly requested > decoding) because the printf format character is already overcrowded, and > have instead thought about introducing some new scheme that allows for > arbitrary new printf/printa decodings. So for example, we would envision > something like this: > > printf("error is %<errno>\n");That should obviously be: printf("error is %<errno>\n", errval); (Or whatever.) Apologies for any confusion... - Bryan -------------------------------------------------------------------------- Bryan Cantrill, Solaris Kernel Development. http://blogs.sun.com/bmc
Bryan Cantrill''s email at 4/18/2006 11:23 AM, said:>> I''m afraid this is an example (and hopefully a rare one) where we have let >> the Perfect become the enemy of the Good Enough. We decided not to add new >> printf format characters for errnos and signals (the other commonly requested >> decoding) because the printf format character is already overcrowded, and >> have instead thought about introducing some new scheme that allows for >> arbitrary new printf/printa decodings. So for example, we would envision >> something like this: >> >> printf("error is %<errno>\n"); > > That should obviously be: > > printf("error is %<errno>\n", errval); > > (Or whatever.) Apologies for any confusion... > > - Bryan > > -------------------------------------------------------------------------- > Bryan Cantrill, Solaris Kernel Development. http://blogs.sun.com/bmc > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org > >It is a horrible cheesy hack, but here is what I do when I want it purty: BEGIN { strerr[1] = "EPERM: Not super-user"; strerr[2] = "ENOENT: No such file or directory"; strerr[3] = "ESRCH: No such process"; strerr[4] = "EINTR: interrupted system call"; strerr[5] = "EIO: I/O error"; strerr[6] = "ENXIO: No such device or address"; strerr[7] = "E2BIG: Arg list too long"; strerr[8] = "ENOEXEC: Exec format error"; strerr[9] = "EBADF: Bad file number"; strerr[10] = "ECHILD: No children"; strerr[11] = "EAGAIN: Resource temporarily unavailable"; strerr[12] = "ENOMEM: Not enough core"; strerr[13] = "EACCES: Permission denied"; strerr[14] = "EFAULT: Bad address"; strerr[15] = "ENOTBLK: Block device required"; strerr[16] = "EBUSY: Mount device busy"; strerr[17] = "EEXIST: File exists"; strerr[18] = "EXDEV: Cross-device link"; strerr[19] = "ENODEV: No such device"; strerr[20] = "ENOTDIR: Not a directory"; strerr[21] = "EISDIR: Is a directory"; strerr[22] = "EINVAL: Invalid argument"; strerr[23] = "ENFILE: File table overflow"; strerr[24] = "EMFILE: Too many open files"; strerr[25] = "ENOTTY: Inappropriate ioctl for device"; strerr[26] = "ETXTBSY: Text file busy"; strerr[27] = "EFBIG: File too large"; strerr[28] = "ENOSPC: No space left on device"; strerr[29] = "ESPIPE: Illegal seek"; strerr[30] = "EROFS: Read only file system"; strerr[31] = "EMLINK: Too many links"; strerr[32] = "EPIPE: Broken pipe"; strerr[33] = "EDOM: Math arg out of domain of func"; strerr[34] = "ERANGE: Math result not representable"; strerr[35] = "ENOMSG: No message of desired type"; strerr[36] = "EIDRM: Identifier removed"; strerr[37] = "ECHRNG: Channel number out of range"; strerr[38] = "EL2NSYNC: Level 2 not synchronized"; strerr[39] = "EL3HLT: Level 3 halted"; strerr[40] = "EL3RST: Level 3 reset"; strerr[41] = "ELNRNG: Link number out of range"; strerr[42] = "EUNATCH: Protocol driver not attached"; strerr[43] = "ENOCSI: No CSI structure available"; strerr[44] = "EL2HLT: Level 2 halted"; strerr[45] = "EDEADLK: Deadlock condition."; strerr[46] = "ENOLCK: No record locks available."; strerr[47] = "ECANCELED: Operation canceled"; strerr[48] = "ENOTSUP: Operation not supported"; strerr[49] = "EDQUOT: Disc quota exceeded"; strerr[50] = "EBADE: invalid exchange"; strerr[51] = "EBADR: invalid request descriptor"; strerr[52] = "EXFULL: exchange full"; strerr[53] = "ENOANO: no anode"; strerr[54] = "EBADRQC: invalid request code"; strerr[55] = "EBADSLT: invalid slot"; strerr[56] = "EDEADLOCK: file locking deadlock error"; strerr[57] = "EBFONT: bad font file fmt"; strerr[58] = "EOWNERDEAD: process died with the lock"; strerr[59] = "ENOTRECOVERABLE: lock is not recoverable"; strerr[60] = "ENOSTR: Device not a stream"; strerr[61] = "ENODATA: no data (for no delay io)"; strerr[62] = "ETIME: timer expired"; strerr[63] = "ENOSR: out of streams resources"; strerr[64] = "ENONET: Machine is not on the network"; strerr[65] = "ENOPKG: Package not installed"; strerr[66] = "EREMOTE: The object is remote"; strerr[67] = "ENOLINK: the link has been severed"; strerr[68] = "EADV: advertise error"; strerr[69] = "ESRMNT: srmount error"; strerr[70] = "ECOMM: Communication error on send"; strerr[71] = "EPROTO: Protocol error"; strerr[72] = "ELOCKUNMAPPED: locked lock was unmapped"; strerr[73] = "ENOTACTIVE: Facility is not active"; strerr[74] = "EMULTIHOP: multihop attempted"; strerr[77] = "EBADMSG: trying to read unreadable message"; strerr[78] = "ENAMETOOLONG: path name is too long"; strerr[79] = "EOVERFLOW: value too large to be stored in data type"; strerr[80] = "ENOTUNIQ: given log. name not unique"; strerr[81] = "EBADFD: f.d. invalid for this operation"; strerr[82] = "EREMCHG: Remote address changed"; strerr[83] = "ELIBACC: Can''t access a needed shared lib."; strerr[84] = "ELIBBAD: Accessing a corrupted shared lib."; strerr[85] = "ELIBSCN: .lib section in a.out corrupted."; strerr[86] = "ELIBMAX: Attempting to link in too many libs."; strerr[87] = "ELIBEXEC: Attempting to exec a shared library."; strerr[88] = "EILSEQ: Illegal byte sequence."; strerr[89] = "ENOSYS: Unsupported file system operation"; strerr[90] = "ELOOP: Symbolic link loop"; strerr[91] = "ERESTART: Restartable system call"; strerr[92] = "ESTRPIPE: if pipe/FIFO, don''t sleep in stream head"; strerr[93] = "ENOTEMPTY: directory not empty"; strerr[94] = "EUSERS: Too many users (for UFS)"; strerr[95] = "ENOTSOCK: Socket operation on non-socket"; strerr[96] = "EDESTADDRREQ: Destination address required"; strerr[97] = "EMSGSIZE: Message too long"; strerr[98] = "EPROTOTYPE: Protocol wrong type for socket"; strerr[99] = "ENOPROTOOPT: Protocol not available"; strerr[120] = "EPROTONOSUPPORT: Protocol not supported"; strerr[121] = "ESOCKTNOSUPPORT: Socket type not supported"; strerr[122] = "EOPNOTSUPP: Operation not supported on socket"; strerr[123] = "EPFNOSUPPORT: Protocol family not supported"; strerr[124] = "EAFNOSUPPORT: Address family not supported by"; strerr[125] = "EADDRINUSE: Address already in use"; strerr[126] = "EADDRNOTAVAIL: Can''t assign requested address"; strerr[127] = "ENETDOWN: Network is down"; strerr[128] = "ENETUNREACH: Network is unreachable"; strerr[129] = "ENETRESET: Network dropped connection because"; strerr[130] = "ECONNABORTED: Software caused connection abort"; strerr[131] = "ECONNRESET: Connection reset by peer"; strerr[132] = "ENOBUFS: No buffer space available"; strerr[133] = "EISCONN: Socket is already connected"; strerr[134] = "ENOTCONN: Socket is not connected"; strerr[143] = "ESHUTDOWN: Can''t send after socket shutdown"; strerr[144] = "ETOOMANYREFS: Too many references: can''t splice"; strerr[145] = "ETIMEDOUT: Connection timed out"; strerr[146] = "ECONNREFUSED: Connection refused"; strerr[147] = "EHOSTDOWN: Host is down"; strerr[148] = "EHOSTUNREACH: No route to host"; strerr[149] = "EALREADY: operation already in progress"; strerr[150] = "EINPROGRESS: operation now in progress"; strerr[151] = "ESTALE: Stale NFS file handle"; } syscall:::return / errno > 0 / { printf("%s\n", strerr[errno]); } or whatever. Thanks, Jarod
On Tue, Apr 18, 2006 at 09:20:30AM -0700, Bryan Cantrill wrote:> printf("error is %<errno>\n");Ah, mdb_printf() style. I like it. Would this be made available as a user interface? I can think of no end of things where it would be handy *sometimes*. As to whether we need format characters for errno and signal numbers now, personally it doesn''t bother me: I''ve got used to looking ones up I can''t remember offhand, and it''s not hard to post-process as a workaround. regards john
Casper.Dik at Sun.COM
2006-Apr-18 16:58 UTC
[dtrace-discuss] Printing error number desriptions
for privileges, you can use something like: stringof(`priv_names[priv]) as privileges are kept as a global string table/. Casper
Bryan Cantrill wrote:> I''m afraid this is an example (and hopefully a rare one) where we have let > the Perfect become the enemy of the Good Enough. We decided not to add new > printf format characters for errnos and signals (the other commonly requested > decoding) because the printf format character is already overcrowded, and > have instead thought about introducing some new scheme that allows for > arbitrary new printf/printa decodings. So for example, we would envision > something like this: > > printf("error is %<errno>\n"); > > Or something. But the reality is that we haven''t yet implemented this, and > that (realistically) people just need a format character for errnos and > signals. So maybe we''ll just come up with format characters for these two, > and defer a more elaborate scheme when future decodings become required. > Thoughts?Yes, it''s needed all over the place. "Good enough" is certainly a start, and needs to be done ASAP. However, I''m not too comfortable with adding new non-(elsewhere)-standard syntax to printf, nor with "register your decode at startup, use it later" extensible printfs (having had the joy of trying to debug in such an environment). What about plain "const char * errno_string[]" (etc) arrays? The "good enough" implementation supporting errno and signal won''t take long to do, and the Perfect can (later) be auto-generated by parsing suitably-annotated header files (or, in the case of enums, compiler output?) Cheers, Jeremy Harris
G''Day Folks, On Tue, 18 Apr 2006, Jarod Jenson wrote: [...]> It is a horrible cheesy hack, but here is what I do when I want it purty: > > BEGIN > { > strerr[1] = "EPERM: Not super-user"; > strerr[2] = "ENOENT: No such file or directory"; > strerr[3] = "ESRCH: No such process";[...] I don''t think that''s all that bad. :) Here is a (slightly) different way. It lets us write scripts that use both "errno" for integers, and "errnostr" for strings, -----errstr.d--- #!/usr/sbin/dtrace -s #pragma D option quiet dtrace:::BEGIN { printf("%-16s %-12s %3s %s\n", "EXEC", "SYSCALL", "ERR", "DESC"); } syscall:::return /(int)arg0 == -1 && execname != "dtrace"/ { printf("%-16s %-12s %3d %s\n", execname, probefunc, errno, errnostr); } -----errstr.d--- With output like, # ./errstr.d EXEC SYSCALL ERR DESC miniserv.pl waitsys 10 ECHILD: No children snmpd ioctl 12 ENOMEM: Not enough core Xorg read 11 EAGAIN: Resource temporarily unavailable Xorg pollsys 4 EINTR: interrupted system call Xorg read 11 EAGAIN: Resource temporarily unavailable Xorg pollsys 4 EINTR: interrupted system call svc.startd portfs 62 ETIME: timer expired Xorg read 11 EAGAIN: Resource temporarily unavailable Xorg pollsys 4 EINTR: interrupted system call Xorg read 11 EAGAIN: Resource temporarily unavailable Xorg pollsys 4 EINTR: interrupted system call [...] It involves adding a file called /usr/lib/dtrace/errnostr.d which contains, # head /usr/lib/dtrace/errnostr.d /* /usr/lib/dtrace/errnostr.d - provides "errnostr". */ inline string errnostr errno == 1 ? "EPERM: Not super-user" : errno == 2 ? "ENOENT: No such file or directory" : errno == 3 ? "ESRCH: No such process" : errno == 4 ? "EINTR: interrupted system call" : errno == 5 ? "EIO: I/O error" : errno == 6 ? "ENXIO: No such device or address" : errno == 7 ? "E2BIG: Arg list too long" : I''ve attached errnostr.d and the Perl script that built it. It probably makes more sense for it to create both a "errnostr" for just the code ("EPERM"), and a "errnodesc" for the full description ("Not super-user"), allowing the programmer to choose their own components. I haven''t used it (and others) in any DTraceToolkit script, as I don''t want to pollute people''s /usr/lib/dtrace. It also hardcodes errno to strings (although I feel less bad about that after reading the source to truss ;). The D-Team are welcome to add errnostr.d or variations to /usr/lib/dtrace - so long as this doesn''t seem too silly. no worries, Brendan [Sydney, Australia] -------------- next part -------------- /* /usr/lib/dtrace/errnostr.d - provides "errnostr". */ inline string errnostr errno == 1 ? "EPERM: Not super-user" : errno == 2 ? "ENOENT: No such file or directory" : errno == 3 ? "ESRCH: No such process" : errno == 4 ? "EINTR: interrupted system call" : errno == 5 ? "EIO: I/O error" : errno == 6 ? "ENXIO: No such device or address" : errno == 7 ? "E2BIG: Arg list too long" : errno == 8 ? "ENOEXEC: Exec format error" : errno == 9 ? "EBADF: Bad file number" : errno == 10 ? "ECHILD: No children" : errno == 11 ? "EAGAIN: Resource temporarily unavailable" : errno == 12 ? "ENOMEM: Not enough core" : errno == 13 ? "EACCES: Permission denied" : errno == 14 ? "EFAULT: Bad address" : errno == 15 ? "ENOTBLK: Block device required" : errno == 16 ? "EBUSY: Mount device busy" : errno == 17 ? "EEXIST: File exists" : errno == 18 ? "EXDEV: Cross-device link" : errno == 19 ? "ENODEV: No such device" : errno == 20 ? "ENOTDIR: Not a directory" : errno == 21 ? "EISDIR: Is a directory" : errno == 22 ? "EINVAL: Invalid argument" : errno == 23 ? "ENFILE: File table overflow" : errno == 24 ? "EMFILE: Too many open files" : errno == 25 ? "ENOTTY: Inappropriate ioctl for device" : errno == 26 ? "ETXTBSY: Text file busy" : errno == 27 ? "EFBIG: File too large" : errno == 28 ? "ENOSPC: No space left on device" : errno == 29 ? "ESPIPE: Illegal seek" : errno == 30 ? "EROFS: Read only file system" : errno == 31 ? "EMLINK: Too many links" : errno == 32 ? "EPIPE: Broken pipe" : errno == 33 ? "EDOM: Math arg out of domain of func" : errno == 34 ? "ERANGE: Math result not representable" : errno == 35 ? "ENOMSG: No message of desired type" : errno == 36 ? "EIDRM: Identifier removed" : errno == 37 ? "ECHRNG: Channel number out of range" : errno == 38 ? "EL2NSYNC: Level 2 not synchronized" : errno == 39 ? "EL3HLT: Level 3 halted" : errno == 40 ? "EL3RST: Level 3 reset" : errno == 41 ? "ELNRNG: Link number out of range" : errno == 42 ? "EUNATCH: Protocol driver not attached" : errno == 43 ? "ENOCSI: No CSI structure available" : errno == 44 ? "EL2HLT: Level 2 halted" : errno == 45 ? "EDEADLK: Deadlock condition." : errno == 46 ? "ENOLCK: No record locks available." : errno == 47 ? "ECANCELED: Operation canceled" : errno == 48 ? "ENOTSUP: Operation not supported" : errno == 49 ? "EDQUOT: Disc quota exceeded" : errno == 50 ? "EBADE: invalid exchange" : errno == 51 ? "EBADR: invalid request descriptor" : errno == 52 ? "EXFULL: exchange full" : errno == 53 ? "ENOANO: no anode" : errno == 54 ? "EBADRQC: invalid request code" : errno == 55 ? "EBADSLT: invalid slot" : errno == 56 ? "EDEADLOCK: file locking deadlock error" : errno == 57 ? "EBFONT: bad font file fmt" : errno == 58 ? "EOWNERDEAD: process died with the lock" : errno == 59 ? "ENOTRECOVERABLE: lock is not recoverable" : errno == 60 ? "ENOSTR: Device not a stream" : errno == 61 ? "ENODATA: no data (for no delay io)" : errno == 62 ? "ETIME: timer expired" : errno == 63 ? "ENOSR: out of streams resources" : errno == 64 ? "ENONET: Machine is not on the network" : errno == 65 ? "ENOPKG: Package not installed" : errno == 66 ? "EREMOTE: The object is remote" : errno == 67 ? "ENOLINK: the link has been severed" : errno == 68 ? "EADV: advertise error" : errno == 69 ? "ESRMNT: srmount error" : errno == 70 ? "ECOMM: Communication error on send" : errno == 71 ? "EPROTO: Protocol error" : errno == 72 ? "ELOCKUNMAPPED: locked lock was unmapped" : errno == 73 ? "ENOTACTIVE: Facility is not active" : errno == 74 ? "EMULTIHOP: multihop attempted" : errno == 77 ? "EBADMSG: trying to read unreadable message" : errno == 78 ? "ENAMETOOLONG: path name is too long" : errno == 79 ? "EOVERFLOW: value too large to be stored in data type" : errno == 80 ? "ENOTUNIQ: given log. name not unique" : errno == 81 ? "EBADFD: f.d. invalid for this operation" : errno == 82 ? "EREMCHG: Remote address changed" : errno == 83 ? "ELIBACC: Can''t access a needed shared lib." : errno == 84 ? "ELIBBAD: Accessing a corrupted shared lib." : errno == 85 ? "ELIBSCN: .lib section in a.out corrupted." : errno == 86 ? "ELIBMAX: Attempting to link in too many libs." : errno == 87 ? "ELIBEXEC: Attempting to exec a shared library." : errno == 88 ? "EILSEQ: Illegal byte sequence." : errno == 89 ? "ENOSYS: Unsupported file system operation" : errno == 90 ? "ELOOP: Symbolic link loop" : errno == 91 ? "ERESTART: Restartable system call" : errno == 92 ? "ESTRPIPE: if pipe/FIFO, don''t sleep in stream head" : errno == 93 ? "ENOTEMPTY: directory not empty" : errno == 94 ? "EUSERS: Too many users (for UFS)" : errno == 95 ? "ENOTSOCK: Socket operation on non-socket" : errno == 96 ? "EDESTADDRREQ: Destination address required" : errno == 97 ? "EMSGSIZE: Message too long" : errno == 98 ? "EPROTOTYPE: Protocol wrong type for socket" : errno == 99 ? "ENOPROTOOPT: Protocol not available" : errno == 120 ? "EPROTONOSUPPORT: Protocol not supported" : errno == 121 ? "ESOCKTNOSUPPORT: Socket type not supported" : errno == 122 ? "EOPNOTSUPP: Operation not supported on socket" : errno == 123 ? "EPFNOSUPPORT: Protocol family not supported" : errno == 124 ? "EAFNOSUPPORT: Address family not supported by" : errno == 125 ? "EADDRINUSE: Address already in use" : errno == 126 ? "EADDRNOTAVAIL: Can''t assign requested address" : errno == 127 ? "ENETDOWN: Network is down" : errno == 128 ? "ENETUNREACH: Network is unreachable" : errno == 129 ? "ENETRESET: Network dropped connection because" : errno == 130 ? "ECONNABORTED: Software caused connection abort" : errno == 131 ? "ECONNRESET: Connection reset by peer" : errno == 132 ? "ENOBUFS: No buffer space available" : errno == 133 ? "EISCONN: Socket is already connected" : errno == 134 ? "ENOTCONN: Socket is not connected" : errno == 143 ? "ESHUTDOWN: Can''t send after socket shutdown" : errno == 144 ? "ETOOMANYREFS: Too many references: can''t splice" : errno == 145 ? "ETIMEDOUT: Connection timed out" : errno == 146 ? "ECONNREFUSED: Connection refused" : errno == 147 ? "EHOSTDOWN: Host is down" : errno == 148 ? "EHOSTUNREACH: No route to host" : errno == 149 ? "EALREADY: operation already in progress" : errno == 150 ? "EINPROGRESS: operation now in progress" : errno == 151 ? "ESTALE: Stale NFS file handle" : "UNKNOWN: Unknown error code."; -------------- next part -------------- #!/usr/bin/perl # # builderr - build a DTrace /usr/lib/dtrace/errnostr.d file # # 19-Apr-2006 Brendan Gregg Created this print "/* /usr/lib/dtrace/errnostr.d - provides \"errnostr\". */\n\n"; print "inline string errnostr =\n"; open ERRNO, "/usr/include/sys/errno.h" or die "ERROR1: reading errno.h: $!\n"; while (chomp($line = <ERRNO>)) { next unless $line =~ /^#define/; ($code, $errno, $desc) = $line =~ /^#define\s+(\S+)\s+(\d+)\s+\/\*\s*(.*?)\s*\*\//; next if $desc eq ""; $desc =~ s/\"//g; print " errno == $errno ? \"$code: $desc\" :\n", } close ERRNO; print " \"UNKNOWN: Unknown error code.\";\n";
On Wed, 19 Apr 2006, Brendan Gregg wrote: [...]> I''ve attached errnostr.d and the Perl script that built it. It probably[...] Sorry, now I''ve attached the _real_ Perl script that built it. (That''s what I get for keeping older copies around with similar names)... Brendan -------------- next part -------------- #!/usr/bin/perl -w # # builderrnostr - build a DTrace /usr/lib/dtrace/errnostr.d file # # 19-Apr-2006 Brendan Gregg Created this use strict; print "/* /usr/lib/dtrace/errnostr.d - provides \"errnostr\". */\n\n"; print "inline string errnostr =\n"; open ERRNO, "/usr/include/sys/errno.h" or die "ERROR1: reading errno.h: $!\n"; my @Lines = <ERRNO>; close ERRNO; foreach (@Lines) { chomp; my ($code, $errno, $desc) = $_ =~ /^#define\s+(\S+)\s+(\d+)\s+\/\*\s*(.*?)\s*\*\//; next unless defined $desc and $desc ne ""; $desc =~ tr/\"//d; print " errno == $errno ? \"$code: $desc\" :\n", } print " \"UNKNOWN: Unknown error code.\";\n";
Thanks for all the replies. This started out as a question raised on a dtrace course I''m on and it''s been fun incorporating some of the suggestions and examples into the lab examples. Thanks again. This message posted from opensolaris.org