Sample - Linux下演示pthread、fork等函数
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/sysinfo.h>
void command_thread(void *arg);
void setup_daemon();
void message_log(char *text);
void command_thread(void *arg)
{
char str_command[120];
sprintf(str_command, "This is command_thread.");
fprintf(stdout, "we start to fork ......\n");
//message_log(str_command);
pid_t pid = fork();
if (pid < 0){
//message_log("failed to vfork child process.");
pthread_exit(NULL);
return ;
}
if (pid == 0){ // child process
fprintf(stdout, "enter child process.\n");
message_log("enter child process.");
//setuid();
//execlp("");
//int r = chdir("work");
//if (r == -1)
// message_log("failed to run chdir()");
FILE *fp = fopen("/tmp/a.txt", "a+");
if (fp == NULL){
message_log("failed to open file /tmp/a.txt");
}else{
fputs("#!/bin/sh\n", fp);
fputs("echo PATH\n", fp);
fclose(fp);
}
char *cmd_str[] = {"ls", "-l", NULL};
char *env[] = {"PATH=$PATH:/usr/bin:/bin", NULL};
int ret = execve("/bin/ls", cmd_str, env);
fprintf(stdout, "after exec().\n");
message_log("ret: ");
exit(0);
}
waitpid(pid, NULL, 0);
fprintf(stdout, "main precess.\n");
message_log("main precess.\n");
pthread_exit(NULL);
}
void setup_daemon()
{
int i;
// close all open file descriptors
for (i=0; i<NOFILE; i++){
close(i);
}
// 1st fork() call
switch (fork()){
case -1: // error in 1st fork()
message_log("setup_daemon(): 1st fork()");
exit(-1);
case 0:{ // continue in 1st child (2nd parent process)
if (setsid() == -1){ // start new session , exit() on error
message_log("setup_daemon(): setsid()");
exit(-2);
}
// 2nd fork() call
switch (fork()){
case -1:
message_log("setup_daemon(): 2nd fork()");
exit(-1);
case 0:// continue in 2nd child
// reset file creation mask for LOG file
chdir("/tmp");
umask(0);
return;
default: // exit 2nd parent process
exit(0);
}
} // case 0:
default: // exit 1st parent process
exit(0);
}
}
void message_log(char *text)
{
time_t sec;
sec = time(NULL);
struct tm *pt = localtime(&sec);
char logfile[80];
sprintf(logfile, "easy%04d%02d%02d.log", pt->tm_year+1900, pt->tm_mon+1, pt->tm_mday);
FILE *fp = fopen(logfile, "a+");
if (fp == NULL)
return;
char mesg[256];
sprintf(mesg, "%02d:%02d:%02d ", pt->tm_hour, pt->tm_min, pt->tm_sec);
fputs(mesg, fp);
fputs(text, fp);
fputs("\n", fp);
fclose(fp);
}
int main(int argc, char *argv[])
{
setup_daemon();
pthread_t my_th;
int my_id = pthread_create(&my_th, NULL, (void *)&command_thread, NULL);
pthread_join(my_th, NULL);
/*chdir("work");
char *cmd_str[] = {"ls", "-l", NULL};
char *env[] = {"PATH=$PATH:/usr/bin:/bin", NULL};
int ret = execve("/bin/ls", cmd_str, env);
fprintf(stdout, "ret: %d\n", ret);*/
return 1;
}
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/sysinfo.h>
void command_thread(void *arg);
void setup_daemon();
void message_log(char *text);
void command_thread(void *arg)
{
char str_command[120];
sprintf(str_command, "This is command_thread.");
fprintf(stdout, "we start to fork ......\n");
//message_log(str_command);
pid_t pid = fork();
if (pid < 0){
//message_log("failed to vfork child process.");
pthread_exit(NULL);
return ;
}
if (pid == 0){ // child process
fprintf(stdout, "enter child process.\n");
message_log("enter child process.");
//setuid();
//execlp("");
//int r = chdir("work");
//if (r == -1)
// message_log("failed to run chdir()");
FILE *fp = fopen("/tmp/a.txt", "a+");
if (fp == NULL){
message_log("failed to open file /tmp/a.txt");
}else{
fputs("#!/bin/sh\n", fp);
fputs("echo PATH\n", fp);
fclose(fp);
}
char *cmd_str[] = {"ls", "-l", NULL};
char *env[] = {"PATH=$PATH:/usr/bin:/bin", NULL};
int ret = execve("/bin/ls", cmd_str, env);
fprintf(stdout, "after exec().\n");
message_log("ret: ");
exit(0);
}
waitpid(pid, NULL, 0);
fprintf(stdout, "main precess.\n");
message_log("main precess.\n");
pthread_exit(NULL);
}
void setup_daemon()
{
int i;
// close all open file descriptors
for (i=0; i<NOFILE; i++){
close(i);
}
// 1st fork() call
switch (fork()){
case -1: // error in 1st fork()
message_log("setup_daemon(): 1st fork()");
exit(-1);
case 0:{ // continue in 1st child (2nd parent process)
if (setsid() == -1){ // start new session , exit() on error
message_log("setup_daemon(): setsid()");
exit(-2);
}
// 2nd fork() call
switch (fork()){
case -1:
message_log("setup_daemon(): 2nd fork()");
exit(-1);
case 0:// continue in 2nd child
// reset file creation mask for LOG file
chdir("/tmp");
umask(0);
return;
default: // exit 2nd parent process
exit(0);
}
} // case 0:
default: // exit 1st parent process
exit(0);
}
}
void message_log(char *text)
{
time_t sec;
sec = time(NULL);
struct tm *pt = localtime(&sec);
char logfile[80];
sprintf(logfile, "easy%04d%02d%02d.log", pt->tm_year+1900, pt->tm_mon+1, pt->tm_mday);
FILE *fp = fopen(logfile, "a+");
if (fp == NULL)
return;
char mesg[256];
sprintf(mesg, "%02d:%02d:%02d ", pt->tm_hour, pt->tm_min, pt->tm_sec);
fputs(mesg, fp);
fputs(text, fp);
fputs("\n", fp);
fclose(fp);
}
int main(int argc, char *argv[])
{
setup_daemon();
pthread_t my_th;
int my_id = pthread_create(&my_th, NULL, (void *)&command_thread, NULL);
pthread_join(my_th, NULL);
/*chdir("work");
char *cmd_str[] = {"ls", "-l", NULL};
char *env[] = {"PATH=$PATH:/usr/bin:/bin", NULL};
int ret = execve("/bin/ls", cmd_str, env);
fprintf(stdout, "ret: %d\n", ret);*/
return 1;
}