fork/exec clobbers write. I need ideas why...


 
Thread Tools Search this Thread
Top Forums Programming fork/exec clobbers write. I need ideas why...
# 1  
Old 05-27-2007
fork/exec clobbers write. I need ideas why...

On my *nix box, I have a telegram program.

When I go like
tel person "la\nla\nla\n"

the person sees
"la\nla\nla\n"

However, when I have a program that forks and execs tel like:

pid = fork();
if (pid < 0) {
perror("fork failed");
exit(EXIT_FAILURE);
}
if (pid == 0) {
execlp("tel", "tel", user, what, (char *)0);
perror("execlp tel failed");
exit(EXIT_FAILURE);
}


and pass the string "la\nla\nla\n" to execlp()

The person sees
la
la
la

I'm pretty sure the exec() is clobbering tel. In the source code for tel, I see

void dotelegram(bool nl)
{
int ch;

/* Ask the user for a message if we don't already have one */
if (telmsg == NULL || telmsg[0] == '\0' || telmsg[0] == '\n')
{
if (nl) putchar('\n');
printf("Msg: ");
fgets(telmsg= linebuf, LBSIZE, stdin);
if (telmsg[0] == '\n') done(0);
}

/* slow down if we are sending stuff too fast */
if (f_wrthist != NULL)
{
sleep(check_flood());
register_tel();
}

/* send him a banner, if we weren't writing him already */
if (!nested_write())
sendbanner();

/* Send the telegram */
is_writing= TRUE;
while (*telmsg != '\0')
sendchar(*(telmsg++));
if (rec_only)
printf("SAVED\n");
else
printf("SENT\n");
}

void sendchar(int ch)
{
if (ch == '\n' || ch == '\b' || ch == '\t' || ch == '\r')
putb(ch)
else
{
if (!isascii(ch))
{
putsb("M-");
ch= toascii(ch);
}
if (!isprint(ch))
{
putb('^');
ch= ((ch == '\177') ? '?' : ch + '@');
}
putb(ch);
}
fflush(histerm);
}


I was thinking that tel might be confusing "string related" lines with "logical related" lines.
Possible ideas what might be going on or what to look for in the source code?

Thanks in advance
# 2  
Old 05-28-2007
Quote:
Originally Posted by frequency8
and pass the string "la\nla\nla\n" to execlp()
Try
Code:
"la\\nla\\nla\\n"

What does the following do?

Code:
int main(int argc,char **argv)
{
    execlp("tel","tel",argv[1],argv[2],NULL);
    return 1;
}

# 3  
Old 05-28-2007
When I run
Code:
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char **argv)
{
  execlp("tel","tel",argv[1],argv[2],NULL);
  return 1;
}

I get the following
[cda@localhost ~]$ ./flood2 cda "la\\nla\\nla\\n"
cda logged on more than once
Telegram to pts/2...Telegram from cda on pts/2 at 19:22 PDT ...
la\nla\nla\n
SENT
EOF (cda)

[cda@localhost ~]$ ./flood2 cda la\\nla\\nla\\n
cda logged on more than once
Telegram to pts/2...Telegram from cda on pts/2 at 19:24 PDT ...
la\nla\nla\n
SENT
EOF (cda)

The exact same behavior as if I were just passing the strings via tel. Notice how the '\n' doest get 'interpreted'

Now I'm really puzzled as to why, when I fork the process, the newlines get interpreted. Could is be maybe some kind of funy shell trick tel might be doing?

I know in wrt_sig.c, there is the following sheep trick with the shell
Code:
#ifdef USER_SHELL
/* WSYSTEM:  A modified version of the system() command that uses the user's
 * own shell (as specified by the "SHELL" environment variable) instead of
 * always using sh.
 */

void wsystem(char *cmd)
{
register int cpid,wpid;
RETSIGTYPE (*old_intr)(), (*old_quit)();
char *shell;

        if ((cpid = fork()) == 0)
        {
            dup2(2,1);
            /*setuid(getuid()); setgid(getgid());*/
            endutent();
            if ((shell= getenv("SHELL")) == NULL) shell= "/bin/sh";
            execl(shell,leafname(shell),"-c",cmd,(char *)NULL);
            fprintf(stderr,"%s: cannot execute shell %s\n", progname,shell);
            exit(-1);
        }
        old_intr = signal(SIGINT,SIG_IGN);
        old_quit = signal(SIGQUIT,SIG_IGN);
        while ((wpid = wait((int *)0)) != cpid && wpid != -1)
            ;
        signal(SIGINT,old_intr);
        signal(SIGQUIT,old_quit);
}

# 4  
Old 05-29-2007
Try
Code:
execlp("tel","tel","cda","la\\nla\\nla\\n",NULL);

And..

Code:
int main(int argc,char **argv)
{
    int s=0;
    int pid=fork();
    if (!pid) {
           execlp("tel","tel",argv[1],argv[2],NULL);
           _exit(1);
    }
    waitpid(pid,&s,0);
    return s;
}

[/QUOTE]
# 5  
Old 05-29-2007
neither one worked.

Below is a crude, but working example of what I mean. Please be gentle on the coding errors.

Code:
/*I wrote the original base code. I only know of one person that has taken this code and improved upon it.
*/
#include <sys/types.h>
#include <sys/wait.h>


#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

#define PATH "/home/cda/input"
#define COUNT 20
#define MAXLINE 1024

enum
  {
    /*NINSULTS = sizeof(insults) / sizeof(insults[0]),*/
    PAUSE = 3,
    TIMES = 24
  };


void init(void) 
{
  /*system("mesg -ye -r -xw");*/
  system("mesg n");
}

 static void
 tel(char *user, char *what)
{
  pid_t   pid;
  /*int     status;*/

  pid = fork();
  if (pid < 0) {
    perror("fork failed");
    exit(EXIT_FAILURE);
  }
  if (pid == 0) {
    execlp("tel", "tel", user, what, (char *)0);
    perror("execlp tel failed");
    exit(EXIT_FAILURE);
  }
  /*status = 0;
  wait(&status);
  if (status != 0) {
    fprintf(stderr, "tel failed, bailing.\n");
    exit(EXIT_FAILURE);
    }*/
}


int main(int argc, char *argv[])
{
  char    **users;
  int     i, j, k;
  char **strarray = NULL;
  int strcount = 0;
  char line[MAXLINE];
  FILE *fp;
  char *new;

  int status;

  if (argc < 2) {
    fprintf(stderr, "Usage: telflood user[s].\n");
    return(EXIT_FAILURE);
  }

  /*i need to get around to fixing this*/
  init();

  for(j=0; j < COUNT; j++) {
    if ((fp = fopen(PATH,"r")) == NULL){
      exit(1);
    }

    while((fgets(line, MAXLINE, fp)) != NULL) {
      strarray = (char **)realloc(strarray, (strcount + 1) * sizeof(char *));
      strarray[strcount++] = strdup(line);
    }

  }

  /*char *new = malloc(5*strlen(strarray[0]) + (strlen(strarray[0])+1) );*/

  new=malloc(85*strlen(strarray[0]) + (strlen(strarray[0]) + 1) );

  for(k=0; k<80; k++){
    strcat(new, strarray[0]);
  }



  for (i = 1, j = -1; i < TIMES; i++) {
    for (users = argv + 1; *users; users++) {
      /*tel(*users, insults[j = ((j + 1) % NINSULTS)]);*/
      tel(*users, new);
      sleep(PAUSE);

      status = 0;
      wait(&status);
      if (status != 0) {
        fprintf(stderr, "tel failed, bailing.\n");
        exit(EXIT_FAILURE);
      }

      /*sleep(PAUSE);*/
    }
  }



  for(i = 0; i < COUNT; i++)
    free((void *)strarray[i]);
  free((void *)strarray);
  free(new);


  fclose(fp);
  return(EXIT_SUCCESS);
}

[cda@localhost ~]$ more input
la

[cda@localhost ~]$ ./flood cdalten
cda logged on more than once
Telegram to pts/5...Telegram from cda on pts/5 at 21:12 PDT ...
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la

SENT
EOF (cda)
# 6  
Old 05-29-2007
An older version of this program I had used an array vs an input file. Ie, I would use something like

Code:
char *name[MAX]="la\nla\nla\n";

Then I would pass this array to my tel() function (ie the one that is commented out in the code).

With that, I'm going to bed.

Thanks for helping me.
# 7  
Old 05-29-2007
Code:
  new=malloc(85*strlen(strarray[0]) + (strlen(strarray[0]) + 1) );

  for(k=0; k<80; k++){
    strcat(new, strarray[0]);
  }

You did not initialise "new" prior to strcat().

Strange program.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Question about global environment variables & fork() exec()

Hello... And thanks in advance for any help anyone can offer me on my question! I've been doing a lot of reading to try and find my answer... But I haven't had any luck What I'm trying to understand is where a child process inherits global environment variables from? I understand the exec()... (2 Replies)
Discussion started by: bodisha
2 Replies

2. UNIX for Dummies Questions & Answers

fork with exec

What is is difference between 'fork with exec' and 'fork without exec'? How both are related? (1 Reply)
Discussion started by: kkalyan
1 Replies

3. Programming

Newbie question on exec,fork, wait,pipe C

Hello everybody.I want to make clear that i am not going to ask from anybody to build my asignement but i have a big problem. I can't seem to find anywhere ONE good example on C about what i am trying to do:wall:.I think it is simple. All i ask is one example, even a link is fine. So, i want to... (1 Reply)
Discussion started by: Cuervo
1 Replies

4. Programming

Fork and then exec problem with signals

Hi All, In my program i am handling SIGHUP signal. In the handler i fork and then exec on child process same binary file which is running. Parent process will die after 10 mins. Now my child process which was exec with same binary file is not receiving SIGHUP signal. Below is the progran code:... (6 Replies)
Discussion started by: sushil_shalin
6 Replies

5. Programming

How forbid use fork() in exec() program.

Hello World! I am writing code in C++ which have to launch another application X using exec(). I would like to set some limits on it using setrlimit etc... My problem is that i don't know how to forbid using fork() and strlimit by application X. How can i do it? (3 Replies)
Discussion started by: kzi
3 Replies

6. Shell Programming and Scripting

fork and exec

I need to ssh to a remote server and run my script there. This is my script. $ssh = "ssh username@host"; $cmd = "$ssh 'cd <my dir> && < sudo Run_exe>'"; my $pid = fork; if ($pid == 0){ exec $cmd; } When I run this I get: pccons_getchar: got r == 0 (1 Reply)
Discussion started by: looza
1 Replies

7. UNIX for Dummies Questions & Answers

How to write a script by fork() in unix

Hello to UNIX Champs, Can any body help me out to write the script using fork() thru shell scripting.....i am a layman to fork(), so please give me the link or any scripts which will help me out to know the details about fork. (1 Reply)
Discussion started by: manas_ranjan
1 Replies

8. Solaris

fork and exec ftp

Hi, I need to find/implement an application that FTPs (puts) all new files in a certain directory to an external storage unit. This application should check for new files every 10 seconds (leaving the FTP connection open in between the 10 seconds). The easiest way would be if there are... (2 Replies)
Discussion started by: KittyJ
2 Replies

9. UNIX for Dummies Questions & Answers

FORK/EXEC technique

Hi! Can someone explain me exactly this technique? Why a process (PARENT) creates a copy of itself with FORK (CHILD)? What's the reason of this behaviour? Sorry, but I cannot understand the logic behind it. Thanks. (4 Replies)
Discussion started by: marshmallow
4 Replies

10. Programming

Fork and exec

Hello! I am working on a server where I should have 4 (resident)processes, one of them being "the father" of the others, so I do 3 forks. The problem that I have is that I do an accept (for sockets) in the "father" process and I want to transmit the job to one of the processes "child" with... (3 Replies)
Discussion started by: driki
3 Replies
Login or Register to Ask a Question