0

Firstly, I'll say how much I appreciate this forum. I can't count how many times during my undergrad that I have come here for information.

Ok, so the language is C. I have a doubly-linked list (ready_list) that I would like to print the contents of. The lists (there are 4 others) have been declared globally for reasons that I believe are outside the scope of my question.

The following is the segment of my code declaring structures. At the bottom of the code inside the signal handler for SIGHUP, I am trying to print the data of my nodes from my linked list. My programming environment is telling me there are some errors. Would someone mind looking at it and letting me know where I have made my mistake?

Thanks in advance, Darrell

typedef struct ready_node {       //ready process nodes
    void              *data;
    struct ready_node *next;
    struct ready_node *prev;
} ready_node;

typedef struct ready_printer {    //ready process list pointer for printing
    void                 *data;
    struct ready_printer *next;
    struct ready_printer *prev;
} ready_printer;

typedef struct ready_list{        //ready process list
    ready_node *head;
    ready_node *tail;
} ready_list;

typedef struct {
    char name[NAME_MAX];
    int  lifetime;
} pcb_t;

void sig_handler(int signal) {      //signal handlers
    if (signal == SIGALRM)
        printf("recieved SIGALRM\n");
    else if (signal == SIGUSR1)
        printf("recieved SIGUSR1\n");
    else if (signal == SIGUSR2)
        printf("revieved SIGUSR2\n");
    else if (signal == SIGHUP) {
        printf("recieved SUGHUP\n");
        ready_printer = ready_list;  // <- Expected Identifier or ‘('

        while (ready_printer != NULL) {   // <- Unexpected type name ‘ready_printer’:expected expression
            printf("%d", ready_printer->data);
            ready_printer=ready_printer->next; // <- Expected Identifier or ‘('
        }
    }
}

UPDATE

Ok, now that I understand the meaning of typdef and struct, here is what I have now:

typedef struct {
    int data;
    void *next;
    void *prev;
} ready_node;


typedef struct {
    ready_node *head;
    ready_node *tail;
} list;

list ready_list;
static int sighup_flag = 0;

void sig_handler(int signal) {      //signal handlers
    if (signal == SIGALRM)
        printf("recieved SIGALRM\n");
    else if (signal == SIGUSR1)
        printf("recieved SIGUSR1\n");
    else if (signal == SIGUSR2)
        printf("revieved SIGUSR2\n");
    else if (signal == SIGHUP)
        sighup_flag = 1;
    }
...
main prog
...
    if (sighup_flag == 1) {
        printf("recieved SIGHUP\n");
        ready_node *printer = ready_list.head;
        while (printer != NULL) {
            printf("%d", printer->data);
            printer = printer->next;
        }
    }

I do appreciate the help. Bruceg posed the question that pointed me in the right direction. As usual, this is a great place to 'receive' help. :)

Stephen Docy
  • 4,738
  • 7
  • 18
  • 31
Darrell
  • 139
  • 7
  • Uh, why are you trying to assign a type to a type? No offense, but you need to understand core concepts/aspects of the language before trying to implement anything as complex as a linked list. And FYI, the word is `receive` – user4520 Jan 19 '16 at 18:21
  • What errors were there? – user3813674 Jan 19 '16 at 18:30
  • You might also want to consider [How to avoid using printf in a signal handler?](http://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler) – Bo Persson Jan 19 '16 at 18:34
  • szczurcio, thank you for the spelling lesson, nothing else though. – Darrell Jan 19 '16 at 23:06
  • Bo Persson - Thanks for the advice on printf inside signal handlers. I've created a global static integer to be used as a flag. – Darrell Jan 19 '16 at 23:18
  • Actually, one more thing. Is it okay to use a void type pointer for next and prev? I've heard that a void* is a generic pointer. Is that true? – Darrell Jan 20 '16 at 00:08
  • 1) do not call `printf()` inside a signal handler. ( you might use `fprintf()` instead) the edit version of the code has 3 instances of calling `printf() inside a signal handler 2) do not use `void*` for the previous/next links, use the `struct tagname` of the struct otherwise the code will contain a lot of 'unneeded' casts and be much more difficult to understand, debug, maintain. – user3629249 Jan 21 '16 at 16:01
  • it is not a good idea to have the tag name of the struct and the typedef name be the same. While a modern compiler can handle it, it does lead to confusion in the human reader of the code. – user3629249 Jan 21 '16 at 16:10

1 Answers1

0

ready_printer is declared as a type not a variable. Assume that there's a variable declared someplace to the head of the ready_printer list:

struct ready_printer *ready_printer_head; 

You need to declare a variable inside of sig_handler like this:

struct ready_printer *p = NULL

Then later inside the handler for SIGHUP:

p = ready_list_head;
while (p) {
        printf("%d", p->data);
        p = p->next;   <— Expected Identifier or ‘('
}

Note that in C you don't have to say (p != NULL). You can just say (p) and it's the same.

bruceg
  • 2,433
  • 1
  • 22
  • 29
  • 2
    I like the for( p = ready_list; p; p = p->next ) printf( "%d", p->data ); style too. The advantage there is if you have complex logic that needs to use continue; you won't forget to move the iterator. – George Houpis Jan 19 '16 at 18:32
  • @GeorgeHoupis I agree. That's the best. I often see that with trees and other structure where going to the next element is not so easy as accessing the next pointer. – bruceg Jan 19 '16 at 18:35
  • George Houpis "for( p = ready_list; p; p = p->next ) printf( "%d", p->data ); " That's pretty slick. I like it too. – Darrell Jan 19 '16 at 23:06
  • bruceg, thanks for the help. I followed your advice and have it down to one error now. The p=ready_list; has the following error beside it: Unexpected type name 'ready_list':expected expression. – Darrell Jan 19 '16 at 23:12
  • My mistake. Your code only has a list of typedefs. Where are the actual list headers? They're not in the code you pasted. Do you understand the difference between a typedef and an actual variable? – bruceg Jan 19 '16 at 23:16
  • maybe. a typedef would be like a C++ class with its methods. an actual variable would be like the attributes of the class?? – Darrell Jan 19 '16 at 23:31
  • Actually, bruceg. It turns out I have (had) no idea what typedef and/or struct were used for. I'm still reading about their uses. I'll get back to you. – Darrell Jan 19 '16 at 23:40
  • typedef is sort of like a C++ class, and a variable is like an instance. – bruceg Jan 19 '16 at 23:42