Having strange behaving programs,at the bottom you can find them, but here is short explenation.

Main program will present a menu from which you can pick operation to do. When I choose 1 it is suppouse to create file of certain name(not exactly, you have to complile score.c program and on command line pass name of file which you wish to create, I'm using "score") with new 5 accounts of zero value, dispalay its inode number and syze than get back to main program.
What is does is :
- display option menu and ask for number of operation to perform
- display again menu
- its displays info about new accounts and hang, thats how is it looks like

here is output

* * * * * * * * * * * * * * * * * * * * * * * *
1. New Game
2. Display current score
3. Enter new score
4. Exit game
* * * * * * * * * * * * * * * * * * * * * * * *

Choose number for operation to perform : 1
* * * * * * * * * * * * * * * * * * * * * * * *
1. New Game
2. Display current score
3. Enter new score
4. Exit game
* * * * * * * * * * * * * * * * * * * * * * * *

Choose number for operation to perform : 0
0
0
0
0
Inumber :        7550163
Size in bytes :  20

However that is not true, after above discribed actions is actualy waiting for new number for operation. So it is just matter of processing.
Question
How can I force program to display information in correct order!!!
MENU ->if 1 -> CREATE NEW FILE -> NEW MENU

MAIN program

//MAIN PROGRAM

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

void newGame()
{
  if(fork()==0)
    {
    execl("score.out","score.out","score",NULL);
    printf("\nback to newGame\n");
    }
}

main ( int argc, char *argv[])
{
  int fd, i, status;

do
  {
    printf("* * * * * * * * * * * * * * * * * * * * * * * *\n");
    printf("1. New Game\n");
    printf("2. Display current score\n");
    printf("3. Enter new score\n");
    printf("4. Exit game\n");
    printf("* * * * * * * * * * * * * * * * * * * * * * * *");
    printf("\n\nChoose number for operation to perform : ");
    scanf("%d",&status);

    switch(status){
    case 1: newGame();
      break;
    case 2: printf("choosen display score\n");
      break;
    case 3: printf("choosen enter new value\n");
      break;
    default:
      break;
    }
  }while( status != 4);
}

SCORE.C

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

main( int argc, char *argv[])
{
  struct stat buf;
  int fd, i;
  int a=0;

  fd = open(argv[1], O_RDWR | O_CREAT, 0600);
  if (fd<0) {
    perror("cannot open file");
    exit(1);
  }

  for(i=0; i < 5; i++)
    {
      write(fd,&a, sizeof (int));
      printf("%d\n", a);
    }

  close(fd);


  if(stat(argv[1], &buf) !=0)
    {
      perror(argv[1]);
      exit(2);
    }

  printf("Inumber :        %d\n", buf.st_ino);
  printf("Size in bytes :  %d\n", buf.st_size);
}

Dani AI

Generated

Quick summary tied to the thread: the original interleaved menu/output was the parent and child both running (so prints came from both processes). As suggested, waiting for the child fixes ordering. The later segmentation fault came from passing the fork return value to wait() as if it were a pointer — wait() expects an int * (or use waitpid() to wait for a specific PID). Calling wait(cid) where cid is the PID causes wait() to try to write status to an invalid address and so causes a crash.

A safe fork/ wait pattern (showing the important bits) is:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

pid_t pid = fork();
if (pid < 0) { perror("fork"); /* handle error */ }
if (pid == 0) {
  /* child: replace image with exec*() or _exit on failure */
  /* execlp(...) */
  perror("exec failed");
  _exit(127);
}

/* parent: wait for that child and examine its exit status */
int status;
if (waitpid(pid, &status, 0) == -1) {
  perror("waitpid");
} else if (WIFEXITED(status)) {
  printf("child exited with %d\n", WEXITSTATUS(status));
}

Practical extra notes and checks reflected in the replies: flush stdio before fork (fflush(stdout)) if buffered output looks duplicated, include the proper headers (<unistd.h>, <sys/wait.h>, <stdlib.h>), prefer _exit() in the child after an exec failure, and check all return values. If a segfault persists, a quick gdb backtrace or strace will show whether the crash comes from incorrect wait() usage or something else. These points explain the symptom progression in the thread and give a robust pattern to follow.

Recommended Answers

All 3 Replies

Hmm, was not really sure what you were doing with exec, but I suppose you compile score.c to score.out... you never return from exec btw so what you want would probably be (and do check bad returns plz)

pid_t pid ;
if( (pid = fork()) == 0 )
{
  execl("score.out","score.out","score",NULL);
  perror( "Im fucked" ) ;
} 
wait( pid ) ; // Not sure about this one, might need status variable, check man
puts("Game ended") ;

And I have not really checked the rest of the code for any sanity, fix that and se what the results are...

hmm, this sorted my problem with print order, but come new problem.
This how newGame function in main program looks like

void newGame()
{
  int cid;
  if((cid = fork())==0)
    {
    execl("score.out","score.out","score",NULL);
    perror("Didn't work.");
    }
  wait( cid);
}

Here is copy of output

* * * * * * * * * * * * * * * * * * * * * * * *
1. New Game
2. Display current score
3. Enter new score
4. Exit game
* * * * * * * * * * * * * * * * * * * * * * * *

Choose number for operation to perform : 1
0
0
0
0
0
Inumber :        7550163
Size in bytes :  20
Segmentation fault

Segmentation error, I love this ones, usually mean rewrite your program/algorithm. Any usefull sugestions? What and where do I try to access or overwrite some important information?

Sorry, forgot thank you for help :o

Sorted out, found my mistake.

Thank you for your help again :cheesy:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.