jonas@lkbpyr.UUCP (Jonas Heyman) (08/29/89)
Hello, I was wondering why this work: -------------------------------------- #include <stdio.h> main() { char *term; char *ttyname(); term=ttyname(); printf("%d",term); } --------------------------------------- And why this don't: -------------------------------------- #include <stdio.h> main() { test(); } test() { char *term; char *ttyname(); term=ttyname(); printf("%d",term); } ---------------------------------------- All the above should type out your current 'tty',example: '/dev/tty023'. Be glad for an answer,sincerely jonas -- jonas@lkbpyr.lkb.se
fieland@hobbiton.prime.com (08/30/89)
I can't answer your question. In fact, your program(s) didn't print out my tty on either the MIPS or my Sun 386i. I was able to get my tty on the mips with the program below, although the term returned was null when I executted the program on the SUn in a window. Notice the print format. Peggy #include <stdio.h> main() { char *term; char *ttyname(); term=ttyname(); printf("%s\n",term); test(); } test() { char *term; char *ttyname(); term=ttyname(); printf("%s\n",term); }
fieland@hobbiton.prime.com (08/30/89)
A further note: tried this out on another Sun without the windows up. Sure enough, the call in Main got the ttyname and the call in test didn't. Clearly, results are system dependent. So how about it??? Any answers out there?????? Peggy
ping@cubmol.BIO.COLUMBIA.EDU (Shiping Zhang) (08/30/89)
In article <99@lkbpyr.UUCP> jonas@lkbpyr.UUCP (Jonas Heyman) writes: >Hello, > >I was wondering why this work: >#include <stdio.h> >main() >{ > char *term; > char *ttyname(); > term=ttyname(); > printf("%d",term); >} I am wondring too because the format of printf() should be %s. >And why this don't: >#include <stdio.h> >main() >{ > test(); >} > >test() >{ > char *term; > char *ttyname(); > term=ttyname(); > printf("%d",term); >} I guess because the format of printf() is incorrect. -ping
chris@mimsy.UUCP (Chris Torek) (08/30/89)
In article <192700003@hobbiton> fieland@hobbiton.prime.com writes: >A further note: >tried this out on another Sun without the windows up. >Sure enough, the call in Main got the ttyname and the >call in test didn't. >Clearly, results are system dependent. Does no one use lint?? Hint: RTFM, or use lint. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
cpcahil@virtech.UUCP (Conor P. Cahill) (08/30/89)
In article <99@lkbpyr.UUCP>, jonas@lkbpyr.UUCP (Jonas Heyman) writes: > Hello, > > I was wondering why this work: > [ example 1 with ttyname() in main() ] > And why this don't: [ example 2 with ttyname() in test() called from main() ] > > All the above should type out your current 'tty',example: '/dev/tty023'. > This is really on of those RTFM kind of things. ttyname() takes a file descriptor as an argument. Both times you were getting whatever value happened to be on the stack at the time the ttyname was called, you were lucky the first time (within main) probably because the ttyname was called so early that the stack was relatively clean, but even this is a bad assumption because other processing has already been accomplished in the startup routines before main is called. So add the appropriate file descriptor whose ttyname you wish to obtain. (I usually use 2, to allow for redirection of stdout and stdin and still get the ttyname. Of course if the user redirects all three, you're out of luck (unless you open /dev/tty and then call ttyname() with the fd returned from the open). -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
diamond@csl.sony.co.jp (Norman Diamond) (08/30/89)
In article <99@lkbpyr.UUCP> jonas@lkbpyr.UUCP (Jonas Heyman) writes:
->I was wondering why this works:
->#include <stdio.h>
->main()
->{
-> char *term;
-> char *ttyname();
-> term=ttyname();
-> printf("%d",term);
->}
->
->And why this doesnn't:
->#include <stdio.h>
->main()
->{
-> test();
->}
->test()
->{
-> char *term;
-> char *ttyname();
-> term=ttyname();
-> printf("%d",term);
->}
Looks to me like they should both fail. You CAN print the decimal
value of a pointer (using "%d") but it isn't what you're asking for.
Try "%s" or maybe even "%s\n".
--
Norman Diamond, Sony Corporation (diamond@ws.sony.junet)
The above opinions are inherited by your machine's init process (pid 1),
after being disowned and orphaned. However, if you see this at Waterloo or
Anterior, then their administrators must have approved of these opinions.
tbecker@incas.UUCP (Thomas Becker) (08/30/89)
jonas@lkbpyr.UUCP (Jonas Heyman) writes: > printf("%d",term); ^^ yes, of course, use %d ... Anyway, I have tried the two versions on a Sun 3/60 and found out the same. The manpage of ttyname(3) says that the function takes a field descritor as an argument. So I tried to call ttyname(NULL) within test(), and it worked! > jonas@lkbpyr.lkb.se Thomas -- Thomas Becker --------- University of Kaiserslautern ------------- West Germany ------------ P.O. Box 3049 -------------------- D-6750 Kaiserslautern --------- -------------------- e-mail: incas!tbecker@uklirb.uucp ------------------------ ------------------------- phone: +49 631 205 3295 -----------------------------
andre@targon.UUCP (andre) (08/30/89)
In article <99@lkbpyr.UUCP> jonas@lkbpyr.UUCP (Jonas Heyman) writes:
]I was wondering why this work:
]#include <stdio.h>
]main()
]{
] char *term;
] char *ttyname();
] term=ttyname();
] printf("%d",term);
]}
Because you were lucky,
]And why this don't:
]--------------------------------------
]#include <stdio.h>
]main()
]{
] test();
]}
]
]test()
]{
] char *term;
] char *ttyname();
] term=ttyname();
] printf("%d",term);
]}
because you were not lucky, there was something else on the stack.
The *MANUAL* says, char *ttyname(filedes).
So if you use in on stdin it will work:
term=ttyname(0);
--
\---| AAA DDDD It's not the kill, but the thrill of the chase.
\ | AA AAvv vvDD DD Ketchup is a vegetable.
/\ \ | AAAAAAAvv vvDD DD {nixbur|nixtor}!adalen.via
_/__\__\| AAA AAAvvvDDDDDD Andre van Dalen, uunet!hp4nl!targon!andre
bazza@hppad.HP.COM (Carlos Bazzarella) (08/30/89)
Hello, I was wondering why this work: -------------------------------------- #include <stdio.h> main() { char *term; char *ttyname(); term=ttyname(); printf("%d",term); } --------------------------------------- And why this don't: -------------------------------------- #include <stdio.h> main() { test(); } test() { char *term; char *ttyname(); term=ttyname(); printf("%d",term); } ---------------------------------------- The second one doesn't work because when the compiler gets to main() and sees test(), he doesn't know what to do with it, since it was not previously defined or compiled. there are 2 things you can do. first you could move the test() function prior to main(), that way by the time main() is compiled, test() will the ready. second you could declared test() on top of your program or in a include file, so when main() is compiled, test() will be given a function overhead, that way the linker will know what to do with test(). a function declaration, for your case, looks like this: void test(); 3 1 2 /* it reads: test (1) is a function (2) with no * returning value (void (2)) */ Carlos Bazzarella. University of Waterloo.
vaughan@mcc.com (Paul Vaughan) (08/30/89)
From: cpcahil@virtech.UUCP (Conor P. Cahill) In article <99@lkbpyr.UUCP>, jonas@lkbpyr.UUCP (Jonas Heyman) writes: > Hello, > > I was wondering why this work: > [ example 1 with ttyname() in main() ] > And why this don't: [ example 2 with ttyname() in test() called from main() ] > > All the above should type out your current 'tty',example: '/dev/tty023'. > This is really on of those RTFM kind of things. ttyname() takes a file descriptor as an argument. Both times you were getting whatever value happened to be on the stack at the time the ttyname was called, you were lucky the first time (within main) probably because the ttyname was called so early that the stack was relatively clean, but even this is a bad assumption because other processing has already been accomplished in the startup routines before main is called. Good answer. I was wondering why the compiler hadn't cited the appropriate passages of TFM to him. I guess that's something you give up if you use <stdio.h> instead of <stream.h>. I tried it using (the gnu lib-g++) <stream.h> and got io.cc:8: warning: type mismatch with previous external decl /usr/local/gnu/lib/g++-include/std.h:204: warning: previous external decl of `char *ttyname (int)' The line number is different because I also bothered to declare test first to get rid of the implicit declaration warning. When I found the argument passing error, I decided the original poster was completely lost and that it wasn't worth looking at. However, I think it's useful to note that using <stream.h> instead of stdio.h would have caught this one. Not to mention that using cout instead of printf would obviated the problem with the %d format specifier and that the program is very clearly expressed in one line cout << ttyname(2); Paul Vaughan, MCC CAD Program | ARPA: vaughan@mcc.com | Phone: [512] 338-3639 Box 200195, Austin, TX 78720 | UUCP: ...!cs.utexas.edu!milano!cadillac!vaughan
karl@haddock.ima.isc.com (Karl Heuer) (08/31/89)
In article <1088@virtech.UUCP> cpcahil@virtech.UUCP (Conor P. Cahill) writes: >Of course if the user redirects all three, you're out of luck (unless you >open /dev/tty and then call ttyname() with the fd returned from the open). In which case you'll probably (depending on flavor) get the return string "/dev/tty" rather than the true name of the terminal. (Assuming the open succeeds in the first place. Not every process has a controlling terminal.)
cpcahil@virtech.UUCP (Conor P. Cahill) (08/31/89)
In article <14481@haddock.ima.isc.com>, karl@haddock.ima.isc.com (Karl Heuer) writes: > In article <1088@virtech.UUCP> cpcahil@virtech.UUCP (Conor P. Cahill) writes: > >Of course if the user redirects all three, you're out of luck (unless you > >open /dev/tty and then call ttyname() with the fd returned from the open). > > In which case you'll probably (depending on flavor) get the return string > "/dev/tty" rather than the true name of the terminal. (Assuming the open > succeeds in the first place. Not every process has a controlling terminal.) I beg to differ. If the open succeeded you will have gotten a file descriptor for the "controlling terminal", not /dev/tty. The gentty driver, which is the driver for /dev/tty, just obtains the major/minor device number for the current process and calls the device specific open routine for that device. I can't imagine that there is a kernel out there that will return a file descriptor associated with /dev/tty and then re-maps it to the appropriate device for every read and write (which it would have to do if the fd is associated with /dev/tty as opposed to the real terminal). Now that we have the file descriptor for the controlling terminal we pass this to ttyname() which will perform an fstat on that file descriptor and then look through the /dev directory for an entry that matches the device number obtained in the fstat(). -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
ams@cbnewsl.ATT.COM (andrew.m.shaw) (08/31/89)
From article <2613@incas.UUCP>, by tbecker@incas.UUCP (Thomas Becker): > The manpage of ttyname(3) says that the function takes a field descritor as > an argument. So I tried to call ttyname(NULL) within test(), and it worked! You were lucky that in your implementation the representation of NULL is the same as the representation of (int)0, giving you stdin. A field [sic] descriptor is properly an int, not a pointer. Andrew Shaw
uri@arnor.UUCP (Uri Blumenthal) (09/01/89)
From article <192700003@hobbiton>, by fieland@hobbiton.prime.com: > > tried this out on another Sun without the windows up. > > Sure enough, the call in Main got the ttyname and the > call in test didn't. > > Clearly, results are system dependent. > So how about it??? Any answers out there?????? This definitely works correctly (AIX system): ------------------- #include <stdio.h> void test() { char *ttyname(); printf("test: %s\n", ttyname(2)); } main() { char *ttyname(); printf("main: %s\n", ttyname(2)); test(); exit(0); } ------------------------------- Points to be made: a) %s in 'printf' statement; b) the manual says: char *ttyname(fildes) int fildes; and when you call 'ttyname' WITHOUT proper parameter - it does work from 'main', but doesn't work in subroutines. Why? Implementation details, who cares? Regards, Uri. ________________ <Disclaimer>
flaps@dgp.toronto.edu (Alan J Rosenthal) (09/01/89)
cpcahil@virtech.UUCP (Conor P. Cahill) writes: >I beg to differ. If the open succeeded you will have gotten a file >descriptor for the "controlling terminal", not /dev/tty... >I can't imagine that there is a kernel out there that will return a >file descriptor associated with /dev/tty and then re-maps it to the >appropriate device for every read and write... FOR F***K'S SAKE DOES NO ONE CHECK THINGS OUT BEFORE POSTING? Script started on Thu Aug 31 16:40:46 1989 champlain.dgp% cat ttyname.c #include <stdio.h> #include <fcntl.h> int main() { int fd; char *p; extern char *ttyname(); if ((fd = open("/dev/tty", O_RDWR)) < 0) perror("/dev/tty"); else if ((p = ttyname(fd)) == NULL) fprintf(stderr, "ttyname failed\n"); else printf("tty is %s\n", p); return(0); } champlain.dgp% cc ttyname.c champlain.dgp% a.out tty is /dev/tty champlain.dgp% ^D script done on Thu Aug 31 16:41:04 1989 That was on a sun running 3.5; I got the same output on an iris running sys V whose motd says "IRIX System V Release 4D1-3.1D". -- Posting etiquette: When I saw Karl's posting about /dev/tty, I was surprised and I thought it was wrong. But I didn't just bang on my followup key. I pressed ^Z and typed "ttyname </dev/tty". Much to my surprise I got the output "/dev/tty". It's quite simple to check before posting. Remember that when you post hasty replies you are wasting many people's time, especially by the volume of followups to your followup which are generated. ajr
gwyn@smoke.BRL.MIL (Doug Gwyn) (09/01/89)
In article <2613@incas.UUCP> tbecker@incas.UUCP (Thomas Becker) writes: >So I tried to call ttyname(NULL) within test(), and it worked! Only by accident. You should use NULL only as a null pointer constant. For a file descriptor that's associated with the terminal, try 2 (in a UNIX environment), or, more portably, fileno(stderr).
gwyn@smoke.BRL.MIL (Doug Gwyn) (09/01/89)
In article <1860001@hppad.HP.COM> bazza@hppad.HP.COM (Carlos Bazzarella) writes: >The second one doesn't work because when the >compiler gets to main() and sees test(), he doesn't >know what to do with it, since it was not >previously defined or compiled. Therefore "test" must be the name of an function returning int, as has always been the rule in C. Later that is how it is defined, although the required return statement was omitted. Try again..
cpcahil@virtech.UUCP (Conor P. Cahill) (09/01/89)
In article <1860001@hppad.HP.COM>, bazza@hppad.HP.COM (Carlos Bazzarella) writes: > The second one doesn't work because when the > compiler gets to main() and sees test(), he doesn't > know what to do with it, since it was not > previously defined or compiled. I think you need to go back and read your C book again. There is no requirement that functions be defined before being used in C. If there was, every program that uses standard library calls (which the compiler usually knows nothing about) would blow up. The only requirement for pre-definition is that the function is assumed to return an int if it is used before any declaration/definition. In this example the function does return an int so no problem. As I said in an earlier message the problem with the code is that the ttyname() function requires a file descriptor argument. (Several others also pointed out the typo in the printf("%d", but since the author said the first sample worked I would assume that the %d was a typo added when he typed the article. -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
cpcahil@virtech.UUCP (Conor P. Cahill) (09/01/89)
In article <1989Aug31.165349.13125@jarvis.csri.toronto.edu>, flaps@dgp.toronto.edu (Alan J Rosenthal) writes: > > Posting etiquette: > When I saw Karl's posting about /dev/tty, I was surprised and I thought it was > wrong. But I didn't just bang on my followup key. I pressed ^Z and typed > "ttyname </dev/tty". Much to my surprise I got the output "/dev/tty". It's > quite simple to check before posting. Remember that when you post hasty > replies you are wasting many people's time, especially by the volume of > followups to your followup which are generated. You are absolutely correct and I apologize for the inaccurate response. I just "KNEW" it had to be that way. So much for knowing without checking. -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
matthew@sunpix.UUCP ( Sun Visualization Products) (09/02/89)
In article <1860001@hppad.HP.COM> bazza@hppad.HP.COM (Carlos Bazzarella) writes:
)
)The second one doesn't work because when the
)compiler gets to main() and sees test(), he doesn't
)know what to do with it, since it was not
)previously defined or compiled. there are 2 things
)you can do. first you could move the test() function
)prior to main(), that way by the time main() is
)compiled, test() will the ready. second you could
)declared test() on top of your program or in a include
)file, so when main() is compiled, test() will be given
)a function overhead, that way the linker will know what
)to do with test().
)a function declaration, for your case, looks like this:
)void test();
) 3 1 2
)/* it reads: test (1) is a function (2) with no
) * returning value (void (2))
) */
)
)
What's this!!!
Sorry, This newsgroup is "comp.lang.c", not "comp.lang.pascal", function order
is not important.
The correct answer to this problem is the one previosly posted. The 'ttyname()'
function call was lacking the file descriptor arguement. Changing the function
call to 'ttyname(0)' fixes the problem.
--
Matthew Lee Stier |
Sun Microsystems --- RTP, NC 27709-3447 | "Wisconsin Escapee"
uucp: sun!mstier or mcnc!rti!sunpix!matthew |
phone: (919) 469-8300 fax: (919) 460-8355 |
karzes@mfci.UUCP (Tom Karzes) (09/02/89)
In article <1860001@hppad.HP.COM> bazza@hppad.HP.COM (Carlos Bazzarella) writes: >The second one doesn't work because when the >compiler gets to main() and sees test(), he doesn't >know what to do with it, since it was not >previously defined or compiled. Nonsense. You obviously know nothing of C. You should probably try to understand something simple like "Hello world" before bothering the net again with such rank amateur comments. (I can tolerate dumb questions, but not dumb answers, particularly when it's obvious that the code has not been tested, or run through lint, or when TFM hasn't been consulted.)
cpcahil@virtech.UUCP (Conor P. Cahill) (09/02/89)
After some more thought as to why ttyname(open("/dev/tty",0)) == "/dev/tty" as opposed to /dev/tty?? or whatever the name of the controlling terminal is, I *think* I figured out the problem. When open is called with the name "/dev/tty", it translates the name into the inode (using the appropriate kernel routine such as namei()), and then determines that the file to be opened is a device special file. At this point the open calls the device specific open, which in this case just calls another device specific open (for the controlling terminal). The open code is not aware that the device that was actually opened is different than the one it thought was being opened and so sets up the file table entries to point to /dev/tty. -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
rfg@dg-rtp.dg.com (Ron Guilmette) (09/02/89)
In article <1111@virtech.UUCP> cpcahil@virtech.UUCP (Conor P. Cahill) writes: >After some more thought as to why ttyname(open("/dev/tty",0)) == "/dev/tty" >... Has this discussion got anything specifically to do with C++? If not, could you please confine it to comp.lang.c. Thanks. // rfg
mccaugh@s.cs.uiuc.edu (10/04/89)
Shouldn't the declaration be: extern char *ttyname(); as it surely isn't defined by you, nor does it appear in <stdio.h>. Also, did you know that 'ttyname' takes a system file-descriptor (I did not see one as an argument). You might try calling 'isatty' just to determine if your tty is "recognized" by the system. You refer to system differences, so I would con- sult the 'man' pages, then include enough #ifdef's to (hopefully) cover most of the cases. Best of Luck. Scott McCaughrin University of Illinois (mccaugh@s.cs.uiuc.edu) P.S. Perhaps some other '.h' has to be included for 'ttyname' to be under- stood properly in your configuration.