programi parsing question - Unix

This is a discussion on programi parsing question - Unix ; In the following code snippet, I misplaced one of the parenthesis in read() and as a result, the program outputs junk. The question is why does the misplaced parenthesin read() cause the program to print junk? I guess I probably ...

+ Reply to Thread
Page 1 of 6 1 2 3 ... LastLast
Results 1 to 20 of 113

Thread: programi parsing question

  1. programi parsing question

    In the following code snippet, I misplaced one of the parenthesis in
    read() and as a result, the program outputs junk. The question is why
    does the misplaced parenthesin read() cause the program to print junk?
    I guess I probably don't understand how read() gets parsed or read in
    by the compiler

    #include
    #include
    #include
    #include
    #include

    int main(void)
    {
    int fd;
    struct utmp log;

    if((fd=open(_PATH_UTMP, O_RDONLY)) < 0){
    fprintf(stderr, "can't open file\n");
    exit(1);
    }

    while( read(fd, &log, sizeof(log) == sizeof(log) ) ){
    printf("%s\n", log.ut_user);
    }

    close(fd);
    return 0;
    }

  2. Re: programi parsing question

    K-mart Cashier writes:
    > In the following code snippet, I misplaced one of the parenthesis in
    > read() and as a result, the program outputs junk. The question is why
    > does the misplaced parenthesin read() cause the program to print junk?
    > I guess I probably don't understand how read() gets parsed or read in
    > by the compiler


    [...]

    > struct utmp log;


    [...]

    > while( read(fd, &log, sizeof(log) == sizeof(log) ) ){
    > printf("%s\n", log.ut_user);
    > }


    The comparison used as third argument is always true and its value is
    therefore one. Your call is equivalent to

    read(fd, &log, 1);

    which means that you read the file byte-by-byte, dumping each into the
    first byte occupied by log and then trying to interpret some part of
    the structure as C-string.


  3. Re: programi parsing question

    K-mart Cashier wrote:

    > while( read(fd, &log, sizeof(log) == sizeof(log) ) ){


    The expression 42 == 42 returns 1, so that's the number of bytes read() reads.

    > printf("%s\n", log.ut_user);


    Then the ut_user element never got initialized or written on, so it contains
    stack garbage, and this prints out.

    All this is "undefined behavior", so nearly anything could happen, in theory!

    Now switch to a softer language, like Ruby, so you can start actually writing
    real programs, sooner, and get back to C after you actually need it for something!

    --
    Phlip

  4. Re: programi parsing question

    On 2 aug, 17:21, K-mart Cashier wrote:
    > if((fd=open(_PATH_UTMP, O_RDONLY)) < 0){


    The manual (http://www.gnu.org/software/libtool/manual/libc/User-
    Accounting-Database.html) says:
    The user accounting database typically lives in /etc/utmp, /var/adm/
    utmp or /var/run/utmp. However, these files should *never* be accessed
    directly. For reading information from and writing information to the
    user accounting database, the functions described in this section
    should be used.

    This implies that you should not use open() and read(), but rather
    getutent().

    On 2 aug, 17:28, Phlip wrote:
    > Now switch to a softer language, like Ruby, so you can start actually writing
    > real programs, sooner, and get back to C after you actually need it for something!


    I think you are putting your Ruby evangelism forward a bit harsh.
    Besides, Ruby does not seem to have the utmp functions provided by
    libc (although the poster does not use them in his example). There
    does seem to be a python-utmp package, however.

  5. Re: programi parsing question

    Sjoerd wrote:

    >> Now switch to a softer language, like Ruby, so you can start actually writing
    >> real programs, sooner, and get back to C after you actually need it for something!


    > I think you are putting your Ruby evangelism forward a bit harsh.


    Sorry. I thought I was representing my decades of experience with C.

    --
    Phlip

  6. Re: programi parsing question

    In comp.unix.programmer Phlip wrote:
    | Sjoerd wrote:
    |
    |>> Now switch to a softer language, like Ruby, so you can start actually writing
    |>> real programs, sooner, and get back to C after you actually need it for something!
    |
    |> I think you are putting your Ruby evangelism forward a bit harsh.
    |
    | Sorry. I thought I was representing my decades of experience with C.

    The "start actually writing real programs" part is what suggested evangelism.
    AFAICT, both languages let you write real programs. Which is the best choice
    depends on a lot of factors such as what kind application you are developing,
    your experiences, and whether it impacts continuing your employment.

    --
    |WARNING: Due to extreme spam, googlegroups.com is blocked. Due to ignorance |
    | by the abuse department, bellsouth.net is blocked. If you post to |
    | Usenet from these places, find another Usenet provider ASAP. |
    | Phil Howard KA9WGN (email for humans: first name in lower case at ipal.net) |

  7. Re: programi parsing question

    >In the following code snippet, I misplaced one of the parenthesis in
    >read() and as a result, the program outputs junk. The question is why
    >does the misplaced parenthesin read() cause the program to print junk?
    >I guess I probably don't understand how read() gets parsed or read in
    >by the compiler


    The length argument to read() was the constant 1, as others have
    pointed out.

    > while( read(fd, &log, sizeof(log)) == sizeof(log) ){

    /* parens fixed above */
    > printf("%s\n", log.ut_user);
    > }


    HOWEVER, even if that problem is corrected, I see no guarantee that
    what is read is '\0'-terminated. read() makes no such guarantee,
    and I doubt that the file format does either. Ensure that strings
    are terminated before trying to print them with %s.



  8. Re: programi parsing question

    On Aug 2, 10:40 am, Sjoerd wrote:
    > On 2 aug, 17:21, K-mart Cashier wrote:
    >
    > > if((fd=open(_PATH_UTMP, O_RDONLY)) < 0){

    >
    > The manual (http://www.gnu.org/software/libtool/manual/libc/User-
    > Accounting-Database.html) says:
    > The user accounting database typically lives in /etc/utmp, /var/adm/
    > utmp or /var/run/utmp. However, these files should *never* be accessed
    > directly. For reading information from and writing information to the
    > user accounting database, the functions described in this section
    > should be used.
    >
    > This implies that you should not use open() and read(), but rather
    > getutent().
    >


    There are some *nix variants that don't have getutent().

  9. Re: programi parsing question

    On Aug 2, 3:04 pm, gordonb.0c...@burditt.org (Gordon Burditt) wrote:
    > >In the following code snippet, I misplaced one of the parenthesis in
    > >read() and as a result, the program outputs junk. The question is why
    > >does the misplaced parenthesin read() cause the program to print junk?
    > >I guess I probably don't understand how read() gets parsed or read in
    > >by the compiler

    >
    > The length argument to read() was the constant 1, as others have
    > pointed out.
    >
    > > while( read(fd, &log, sizeof(log)) == sizeof(log) ){

    >
    > /* parens fixed above */
    >
    > > printf("%s\n", log.ut_user);
    > > }

    >
    > HOWEVER, even if that problem is corrected, I see no guarantee that
    > what is read is '\0'-terminated. read() makes no such guarantee,
    > and I doubt that the file format does either. Ensure that strings
    > are terminated before trying to print them with %s.



    So should I have done something like

    memset(&log, 0, sizeof (log));

    before the call to read()?

  10. Re: programi parsing question

    On Aug 2, 6:12 pm, Chad wrote:
    > On Aug 2, 3:04 pm, gordonb.0c...@burditt.org (Gordon Burditt) wrote:
    >
    >
    >
    > > >In the following code snippet, I misplaced one of the parenthesis in
    > > >read() and as a result, the program outputs junk. The question is why
    > > >does the misplaced parenthesin read() cause the program to print junk?
    > > >I guess I probably don't understand how read() gets parsed or read in
    > > >by the compiler

    >
    > > The length argument to read() was the constant 1, as others have
    > > pointed out.

    >
    > > > while( read(fd, &log, sizeof(log)) == sizeof(log) ){

    >
    > > /* parens fixed above */

    >
    > > > printf("%s\n", log.ut_user);
    > > > }

    >
    > > HOWEVER, even if that problem is corrected, I see no guarantee that
    > > what is read is '\0'-terminated. read() makes no such guarantee,
    > > and I doubt that the file format does either. Ensure that strings
    > > are terminated before trying to print them with %s.

    >
    > So should I have done something like
    >
    > memset(&log, 0, sizeof (log));
    >
    > before the call to read()?



    Now that I think about it, I have a second question. How come doesn't
    get checked for a return value (on error)?

  11. Re: programi parsing question

    On Aug 2, 6:12 pm, Chad wrote:
    > On Aug 2, 3:04 pm, gordonb.0c...@burditt.org (Gordon Burditt) wrote:
    >
    >
    >
    > > >In the following code snippet, I misplaced one of the parenthesis in
    > > >read() and as a result, the program outputs junk. The question is why
    > > >does the misplaced parenthesin read() cause the program to print junk?
    > > >I guess I probably don't understand how read() gets parsed or read in
    > > >by the compiler

    >
    > > The length argument to read() was the constant 1, as others have
    > > pointed out.

    >
    > > > while( read(fd, &log, sizeof(log)) == sizeof(log) ){

    >
    > > /* parens fixed above */

    >
    > > > printf("%s\n", log.ut_user);
    > > > }

    >
    > > HOWEVER, even if that problem is corrected, I see no guarantee that
    > > what is read is '\0'-terminated. read() makes no such guarantee,
    > > and I doubt that the file format does either. Ensure that strings
    > > are terminated before trying to print them with %s.

    >
    > So should I have done something like
    >
    > memset(&log, 0, sizeof (log));
    >
    > before the call to read()?


    No, that's not good enough, because you're reading sizeof(log) bytes.
    All those zeros will get overwritten. If you want to printf with %s,
    you would probably want to copy the whole thing into a buffer that's
    one byte larger, so you can put the zero byte there. Alternatively,
    use a precision specifier for printf, so that it won't try to read
    more than the appropriate number of bytes.

    But I don't understand why you're trying to print out a struct utmp as
    ASCII anyway when it's got binary data in it. Wouldn't you rather be
    printing the fields one at a time, with appropriate formatting?

    I think maybe what you want to be doing is

    while (read(fd, log, sizeof(log)) == sizeof(log)) {
    time_t t = log.ut_time;
    printf("Line %.*s, name %.*s, host %.*s, time %s\n", UT_LINESIZE,
    ut.ut_line, UT_NAMESIZE, ut.ut_name, UT_HOSTSIZE, ut.ut_host,
    ctime(&t));
    }

  12. Re: programi parsing question

    On Aug 2, 7:27 pm, K-mart Cashier wrote:
    > On Aug 2, 6:12 pm, Chad wrote:
    >
    >
    >
    > > On Aug 2, 3:04 pm, gordonb.0c...@burditt.org (Gordon Burditt) wrote:

    >
    > > > >In the following code snippet, I misplaced one of the parenthesis in
    > > > >read() and as a result, the program outputs junk. The question is why
    > > > >does the misplaced parenthesin read() cause the program to print junk?
    > > > >I guess I probably don't understand how read() gets parsed or read in
    > > > >by the compiler

    >
    > > > The length argument to read() was the constant 1, as others have
    > > > pointed out.

    >
    > > > > while( read(fd, &log, sizeof(log)) == sizeof(log) ){

    >
    > > > /* parens fixed above */

    >
    > > > > printf("%s\n", log.ut_user);
    > > > > }

    >
    > > > HOWEVER, even if that problem is corrected, I see no guarantee that
    > > > what is read is '\0'-terminated. read() makes no such guarantee,
    > > > and I doubt that the file format does either. Ensure that strings
    > > > are terminated before trying to print them with %s.

    >
    > > So should I have done something like

    >
    > > memset(&log, 0, sizeof (log));

    >
    > > before the call to read()?

    >
    > Now that I think about it, I have a second question. How come doesn't
    > get checked for a return value (on error)?


    How come *what* doesn't get checked?

  13. Re: programi parsing question

    phil-news-nospam@ipal.net wrote:

    > |>> Now switch to a softer language, like Ruby, so you can start actually writing
    > |>> real programs, sooner, and get back to C after you actually need it for something!
    > |
    > |> I think you are putting your Ruby evangelism forward a bit harsh.
    > |
    > | Sorry. I thought I was representing my decades of experience with C.
    >
    > The "start actually writing real programs" part is what suggested evangelism.


    You snipped "sooner".

    I think if two groups were learning programming, from scratch, the first ones
    writing real programs that do useful things would be the ones using a soft
    language, such as Javascript, Python, or Ruby. The ones that take longer to
    learn the basics (and all the Gotchas) would be using harder languages, such as
    BASIC, C, C++, Java, or Pascal.

    You read too much into "real" programs...

  14. Re: programi parsing question

    On Aug 2, 9:36 pm, fjbl...@yahoo.com wrote:
    > On Aug 2, 7:27 pm, K-mart Cashier wrote:
    >
    >
    >
    > > On Aug 2, 6:12 pm, Chad wrote:

    >
    > > > On Aug 2, 3:04 pm, gordonb.0c...@burditt.org (Gordon Burditt) wrote:

    >
    > > > > >In the following code snippet, I misplaced one of the parenthesis in
    > > > > >read() and as a result, the program outputs junk. The question is why
    > > > > >does the misplaced parenthesin read() cause the program to print junk?
    > > > > >I guess I probably don't understand how read() gets parsed or read in
    > > > > >by the compiler

    >
    > > > > The length argument to read() was the constant 1, as others have
    > > > > pointed out.

    >
    > > > > > while( read(fd, &log, sizeof(log)) == sizeof(log) ){

    >
    > > > > /* parens fixed above */

    >
    > > > > > printf("%s\n", log.ut_user);
    > > > > > }

    >
    > > > > HOWEVER, even if that problem is corrected, I see no guarantee that
    > > > > what is read is '\0'-terminated. read() makes no such guarantee,
    > > > > and I doubt that the file format does either. Ensure that strings
    > > > > are terminated before trying to print them with %s.

    >
    > > > So should I have done something like

    >
    > > > memset(&log, 0, sizeof (log));

    >
    > > > before the call to read()?

    >
    > > Now that I think about it, I have a second question. How come doesn't
    > > get checked for a return value (on error)?

    >
    > How come *what* doesn't get checked?


    memset()

  15. Re: programi parsing question

    K-mart Cashier said:

    > On Aug 2, 9:36 pm, fjbl...@yahoo.com wrote:
    >> On Aug 2, 7:27 pm, K-mart Cashier wrote:
    >>
    >>
    >>
    >> > On Aug 2, 6:12 pm, Chad wrote:

    >>
    >> > > On Aug 2, 3:04 pm, gordonb.0c...@burditt.org (Gordon Burditt) wrote:

    >>
    >> > > > >In the following code snippet, I misplaced one of the parenthesis
    >> > > > >in read() and as a result, the program outputs junk. The question
    >> > > > >is why does the misplaced parenthesin read() cause the program to
    >> > > > >print junk? I guess I probably don't understand how read() gets
    >> > > > >parsed or read in by the compiler

    >>
    >> > > > The length argument to read() was the constant 1, as others have
    >> > > > pointed out.

    >>
    >> > > > > while( read(fd, &log, sizeof(log)) == sizeof(log) ){

    >>
    >> > > > /* parens fixed above */

    >>
    >> > > > > printf("%s\n", log.ut_user);
    >> > > > > }

    >>
    >> > > > HOWEVER, even if that problem is corrected, I see no guarantee
    >> > > > that
    >> > > > what is read is '\0'-terminated. read() makes no such guarantee,
    >> > > > and I doubt that the file format does either. Ensure that strings
    >> > > > are terminated before trying to print them with %s.

    >>
    >> > > So should I have done something like

    >>
    >> > > memset(&log, 0, sizeof (log));

    >>
    >> > > before the call to read()?

    >>
    >> > Now that I think about it, I have a second question. How come doesn't
    >> > get checked for a return value (on error)?

    >>
    >> How come *what* doesn't get checked?

    >
    > memset()


    What are you going to check it against? memset() has no error return. It
    always returns the same pointer you give to it.

    But in fact you don't need the memset call anyway, since every byte is
    written. Rather more useful would be a way of storing and checking the
    result of read().

    And in any case, if you really want to set every element of a struct to 0
    on initialisation, memset isn't the best way to do it. Instead, take
    advantage of the default initialiser rule:

    struct utmp log = {0};

    sets every element of log (except the first) to 0 (because of the partial
    initialisation, which it observes, making the first element get set to 0
    too because that's what you told it to do).

    Given the frequency with which comp.lang.c gets off-topic questions, I find
    it amusing that a question that - for once - would have been bang on-topic
    in clc for several reasons, has ended up in c.p and c.u.p instead.

    --
    Richard Heathfield
    Email: -http://www. +rjh@
    Google users:
    "Usenet is a strange place" - dmr 29 July 1999

  16. Re: programi parsing question

    Phlip wrote:

    > phil-news-nospam@ipal.net wrote:
    >
    >> |>> Now switch to a softer language, like Ruby, so you can start
    >> |>> actually writing real programs, sooner, and get back to C after
    >> |>> you actually need it for something!
    >> |
    >> |> I think you are putting your Ruby evangelism forward a bit harsh.
    >> |
    >> | Sorry. I thought I was representing my decades of experience with
    >> | C.
    >>
    >> The "start actually writing real programs" part is what suggested
    >> evangelism.

    >
    > You snipped "sooner".
    >
    > I think if two groups were learning programming, from scratch, the
    > first ones writing real programs that do useful things would be the
    > ones using a soft language, such as Javascript, Python, or Ruby. The
    > ones that take longer to learn the basics (and all the Gotchas) would
    > be using harder languages, such as BASIC, C, C++, Java, or Pascal.
    >
    > You read too much into "real" programs...


    I'm rather surprised that you classify Java as a "hard" language.


  17. Re: programi parsing question

    >> >In the following code snippet, I misplaced one of the parenthesis in
    >> >read() and as a result, the program outputs junk. The question is why
    >> >does the misplaced parenthesin read() cause the program to print junk?
    >> >I guess I probably don't understand how read() gets parsed or read in
    >> >by the compiler

    >>
    >> The length argument to read() was the constant 1, as others have
    >> pointed out.
    >>
    >> > while( read(fd, &log, sizeof(log)) == sizeof(log) ){

    >>
    >> /* parens fixed above */
    >>
    >> > printf("%s\n", log.ut_user);
    >> > }


    My system (FreeBSD) seems to have a ut_name, not a ut_user structure
    member.

    >> HOWEVER, even if that problem is corrected, I see no guarantee that
    >> what is read is '\0'-terminated. read() makes no such guarantee,
    >> and I doubt that the file format does either. Ensure that strings
    >> are terminated before trying to print them with %s.

    >
    >
    >So should I have done something like
    >
    >memset(&log, 0, sizeof (log));
    >
    >before the call to read()?


    That is insufficient. Consider a system in which the administrator
    insists that all names (well, perhaps not including root) MUST be
    UT_NAMESIZE characters long (NOT including the '\0', because there
    isn't room for one) to make them hard to guess.

    This is one application where strncpy() can be put to good use:

    You need to declare dest somewhere, and make sure it's at
    least sizeof(src.ut_name)+1 large.

    strncpy(dest, src.ut_name, sizeof(src.ut_name));
    dest[sizeof(src.ut_name)] = '\0';

    If you also want to use ut_host and ut_line, you have the same issues
    with them. These fields are not guaranteed to be '\0' terminated
    and there isn't room to put one there.


  18. Re: programi parsing question

    Phlip writes:
    > phil-news-nospam@ipal.net wrote:
    >> |>> Now switch to a softer language, like Ruby, so you can start actually writing
    >> |>> real programs, sooner, and get back to C after you actually need it for something!
    >> | |> I think you are putting your Ruby evangelism forward a bit
    >> harsh.
    >> | | Sorry. I thought I was representing my decades of experience
    >> with C.
    >> The "start actually writing real programs" part is what suggested
    >> evangelism.

    >
    > You snipped "sooner".
    >
    > I think if two groups were learning programming, from scratch, the
    > first ones writing real programs that do useful things would be the
    > ones using a soft language, such as Javascript, Python, or Ruby.


    I don't think that people who consider 'programming language grammar
    and syntax' to be 'a really hard problem' will ever write a useful
    program. That would be close to expecting first-graders struggling
    with expressing themselves in writing to publish enlightening treaties
    on epistemology. Programming languages are tools (or toys :-). The
    world is a complex thing and most of the (unsolved) problems that
    spring from it are hard problems in their own right. Solving them
    requires use of suitable tools, not necessarily familiar ones.


  19. Re: programi parsing question

    Phlip wrote:
    ) phil-news-nospam@ipal.net wrote:
    )
    )> |>> Now switch to a softer language, like Ruby, so you can start actually writing
    )> |>> real programs, sooner, and get back to C after you actually need it for something!
    )> |
    )> |> I think you are putting your Ruby evangelism forward a bit harsh.
    )> |
    )> | Sorry. I thought I was representing my decades of experience with C.
    )>
    )> The "start actually writing real programs" part is what suggested evangelism.
    )
    ) You snipped "sooner".

    It's still there. However, there is a comma between "writing real
    programs" and "sooner", which gives it a different meaning.

    Just a comment, though.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT

  20. Re: programi parsing question

    santosh wrote:

    > I'm rather surprised that you classify Java as a "hard" language.


    This is what happens when someone cross-posts between two technical newsgroups -
    the introductions go around!

    Java is amazingly hard, despite its brochure. To get a useful project going,
    like a website, you often find yourself managing a thousand lines of
    configuration, spread out over several files, before finally clawing your way to
    the "hello, world".

    Further, Java uses static typing, which tends to require a huge number of extra
    lines just to "fill out forms" and prove that various objects have the right to
    interact with each other.

    --
    Phlip


+ Reply to Thread
Page 1 of 6 1 2 3 ... LastLast