matt@snave.Eng.Sun.COM (Matt Evans) (05/23/91)
Hello Perl users; I've just started using perl (perl 4.0 on SUNOS 4.1.1 sun4c) and I have some questions relating to the following problems I seen ... ======================= 1) caller command: ======================= PERL core dumps on the following code: #!/usr/local/bin/perl #--------------------------- # start test (caller) main #--------------------------- $prog_dir = "./"; $prog_name = "not_here"; open (ERR_LOG,">./perr"); $proc_name = join ("",$prog_dir,$prog_name); if (!( -e $conv_proc_name)) { &conv_err ("can't access the program",1); } sub conv_err { local($err_msg,$err_code) = @_; # sub arguments # # local variable declaration # local($pack); local($file); local($line); local($sub_name); # # after debugging the core file, it seems perl # dies on the next line # ($pack,$file,$line,$sub_name) = caller (0); if ($err_code == $FATAL_ERR) { print ERR_LOG "\n\n ERROR:$pack:$sub_name:$file:$line"; die "exit test tool"; } else { print ERR_LOG "\n\n ERROR:$pack:$sub_name:$file:$line"; } } ================================ 2) numeric & string equalities ================================ In reading the camel book, it seems there should be no problem in comparing strings and numbers, However the behavior of the following perl code seems inconsistent: #!/asdf/bin/perl $x = "test"; if ($x == 0) { print "x is equal to 0\n"; } if ($x eq "test") { print "x is equal to the str \"test\"\n"; } ------------------------------------------ output: x is equal to 0 x is equal to the str "test" Question: Why does $x compare equally to numeric 0? Is this correct behavior? ================================ 3) tom christiansen's open2.pl ================================ This is more of a question and a FYI. I was using the open2.pl routine to fire off a process from perl. The routine works like a champ, but it has an interesting side effect. This side effect actually occurs in the spawned process. The spawned process I was running does an fstat on STDIN to tell if it has been started interactively from a terminal or if it has been spawned using pipes. (this C program does many things differently based on whether it is started from pipes or a character device). C code snipit: if ((sbuf.st_mode & S_IFMT) == S_IFCHR) { input_term = TRUE; } else { input_term = FALSE; } well, if the process is started from perl using open2.pl the process thinks it was started from a terminal i.e from above the var input_term is assigned to TRUE. I wrote C program to emulate open2.pl with the sequence of using pipe,fork then exec. The above process did in fact register that it is NOT started from a terminal and the C statement (sbuf.st_mode & S_IFMT) is actually equal to S_IFIFO. This is also true if a process is started from the sh pipe ('|') . So the question goes to all the perl internals wizards: Is there any hidden things happening with PERL's pipe, fork and exec commands that would explain the results I'm getting from that fstat routine on the spawned program? thanks in advance for helpin' a perl neophyte! Matt Evans
tchrist@convex.COM (Tom Christiansen) (05/23/91)
From the keyboard of matt@snave.Eng.Sun.COM (Matt Evans): :======================= : 1) caller command: :======================= : PERL core dumps on the following : code: : : :#!/usr/local/bin/perl :#--------------------------- :# start test (caller) main :#--------------------------- : : $prog_dir = "./"; : $prog_name = "not_here"; : : : open (ERR_LOG,">./perr"); : : $proc_name = join ("",$prog_dir,$prog_name); [just side note: this seems is a less obvious method (and more work) than] $proc_name = $proc_dir . $prog_name; or $proc_name = "$proc_dir/$prog_name"; : if (!( -e $conv_proc_name)) { Warning: this variable was never defined. stat()ing a null may count as ".", but then again, maybe not. On my system, it depends on whether you compile in posix or traditional mode. : # after debugging the core file, it seems perl : # dies on the next line : : ($pack,$file,$line,$sub_name) = caller (0); Debugging the core file? My, you *were* seriously curious! I get the same behavior. Using just caller with no args, or caller(1), makes it work. Sounds like a bug for Larry (or other ambitious volunteers.) :================================ : 2) numeric & string equalities :================================ : : In reading the camel book, it seems there should be no problem : in comparing strings and numbers, However the behavior of the : following perl code seems inconsistent: : : :#!/asdf/bin/perl : : $x = "test"; : if ($x == 0) { : print "x is equal to 0\n"; : } : if ($x eq "test") { : print "x is equal to the str \"test\"\n"; : } : : ------------------------------------------ : : output: : : x is equal to 0 : x is equal to the str "test" : : : Question: Why does $x compare equally to numeric 0? Is this : correct behavior? $x evaluates to numeric 0, all right. That's because *numerically* the string "test" is 0, as are nearly all other strings, except things like "-1", "1e8", etc. awk behaves the same way. :================================ : 3) tom christiansen's open2.pl :================================ : : This is more of a question and a FYI. I was using the open2.pl : routine to fire off a process from perl. The routine works : like a champ, but it has an interesting side effect. This side : effect actually occurs in the spawned process. The spawned : process I was running does an fstat on STDIN to tell if it : has been started interactively from a terminal or if it : has been spawned using pipes. (this C program does many things : differently based on whether it is started from pipes or : a character device). : : C code snipit: : : if ((sbuf.st_mode & S_IFMT) == S_IFCHR) { : input_term = TRUE; : } : else { : input_term = FALSE; : } : : well, if the process is started from perl using open2.pl the : process thinks it was started from a terminal i.e from above : the var input_term is assigned to TRUE. Oh REALLY? I can't repro this puppy. Here's my C code: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> main() { struct stat sb; if (fstat(fileno(stdin),&sb) < 0) { perror("fstat"); exit(1); } if ((sb.st_mode & S_IFMT) == S_IFCHR) { fprintf(stderr, "stdin is a character device\n"); } else { fprintf(stderr, "stdin is NOT a character device\n"); } } and I invoke it from perl this way: require 'open2.pl'; &open2('IN_HANDLE', 'OUT_HANDLE', "a.out"); wait; exit $?; On my system, it says that stdin is NOT a character device, which makes sense, since it's reading from a pipe. Does yours say otherwise? However, I'd rather use isatty(fileno(stdin))) to figure out if it's a terminal device or not. That way it won't be fooled by running something like program < /dev/null --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "So much mail, so little time."
lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (05/23/91)
In article <1991May23.020207.12967@convex.com> tchrist@convex.COM (Tom Christiansen) writes:
: From the keyboard of matt@snave.Eng.Sun.COM (Matt Evans):
: :=======================
: : 1) caller command:
: :=======================
: : PERL core dumps on the following
: : code:
: : ($pack,$file,$line,$sub_name) = caller (0);
:
: I get the same behavior. Using just caller with no args, or
: caller(1), makes it work. Sounds like a bug for Larry (or
: other ambitious volunteers.)
I fixed that one several weeks ago. As a workaround, run your script under
the debugger.
: :================================
: : 2) numeric & string equalities
: :================================
: :
: : In reading the camel book, it seems there should be no problem
: : in comparing strings and numbers, However the behavior of the
: : following perl code seems inconsistent:
: :
: :
: :#!/asdf/bin/perl
: :
: : $x = "test";
: : if ($x == 0) {
: : print "x is equal to 0\n";
: : }
: : if ($x eq "test") {
: : print "x is equal to the str \"test\"\n";
: : }
: :
: : ------------------------------------------
: :
: : output:
: :
: : x is equal to 0
: : x is equal to the str "test"
: :
: :
: : Question: Why does $x compare equally to numeric 0? Is this
: : correct behavior?
:
: $x evaluates to numeric 0, all right. That's because *numerically*
: the string "test" is 0, as are nearly all other strings, except
: things like "-1", "1e8", etc. awk behaves the same way.
"test" seems more equal to 0 than to any other number...
: :================================
: : 3) tom christiansen's open2.pl
: :================================
: :
: : This is more of a question and a FYI. I was using the open2.pl
: : routine to fire off a process from perl. The routine works
: : like a champ, but it has an interesting side effect. This side
: : effect actually occurs in the spawned process. The spawned
: : process I was running does an fstat on STDIN to tell if it
: : has been started interactively from a terminal or if it
: : has been spawned using pipes. (this C program does many things
: : differently based on whether it is started from pipes or
: : a character device).
: :
: : C code snipit:
: :
: : if ((sbuf.st_mode & S_IFMT) == S_IFCHR) {
: : input_term = TRUE;
: : }
: : else {
: : input_term = FALSE;
: : }
: :
: : well, if the process is started from perl using open2.pl the
: : process thinks it was started from a terminal i.e from above
: : the var input_term is assigned to TRUE.
In general, what an OS puts into the stat structure for a pipe is
kinda hit or miss. You may have some funny remnants of however dup2()
is implemented. I wouldn't trust st_mode too far on pipes. Maybe
you should check some of the other fields first. If your pipes are
implemented as anonymous FIFO's you should be able to tell from st_dev
and st_ino, I think, or maybe st_nlink. Happy hunting.
Larry
rich@starnet.uucp (Richard Mahn) (05/24/91)
In <13850@exodus.Eng.Sun.COM> matt@snave.Eng.Sun.COM (Matt Evans) writes: >======================= > 1) caller command: >======================= > > PERL core dumps on the following > code: > the problem occurs when there are arguments to the subroutine caller is referring to. In other words if the routine was called by &DO_SOMETHING no problems, if it was called by &DO_SOMETHING(1) core crashes. One solution is to run under debug. Then it works. You could also wait until patch 4. If you're really in a hurry, the following patch keeps it from crashing, but you don't get the argument values. Larry said he'll have it working completely in patch 4. *** dolist.c Fri May 10 10:20:58 1991 --- dolist.c.orig Wed May 1 09:34:25 1991 *************** *** 1590,1596 **** str_2mortal(str_nmake((double)csv->hasargs)) ); (void)astore(stack,++sp, str_2mortal(str_nmake((double)csv->wantarray)) ); ! if (perldb && csv->hasargs) { ARRAY *ary = csv->argarray; if (dbargs->ary_max < ary->ary_fill) --- 1590,1596 ---- str_2mortal(str_nmake((double)csv->hasargs)) ); (void)astore(stack,++sp, str_2mortal(str_nmake((double)csv->wantarray)) ); ! if (csv->hasargs) { ARRAY *ary = csv->argarray; if (dbargs->ary_max < ary->ary_fill) ----- Richard Mahn Starnet Connections rich@starnet.uucp apple!starnet!rich