业精于勤,荒于嬉;行成于思,毁于随。——韩愈
为在windows下编写linux c/c++程序,本地搭建了clion+MinGW+cmake环境。
在进行linux编程时,进行调用fork()函数时:
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
void l_process()
{
char buf[1024];
pid_t pid;
int status;
printf("%% ");
while(fgets(buf,1024,stdin)!=NULL)
{
buf[strlen(buf)-1] = 0;
if((pid = fork())<0)
{
printf("fork error");
}
else if(pid==0)
{
execlp(buf,buf,(char *)0);
printf("couldn't execute:%s",buf);
exit(127);
}
if((pid=waitpid(pid,&status,0))<0)
printf("waitpid error");
printf("%% ");
}
}
int main(int argc,char *argv[]) {
l_process();
return 0;
}
提示错误:implicit declaration of function 'fork' :
====================[ Build | base_learn1 | Debug ]=============================
"C:\Program Files\JetBrains\CLion 2020.2\bin\cmake\win\bin\cmake.exe" --build F:\myprogram\c-program\unix-learn\base-learn1\cmake-build-debug --target base_learn1 -- -j 6
Scanning dependencies of target base_learn1
[ 50%] Building C object CMakeFiles/base_learn1.dir/main.c.obj
F:\myprogram\c-program\unix-learn\base-learn1\main.c: In function 'l_process':
F:\myprogram\c-program\unix-learn\base-learn1\main.c:54:19: warning: implicit declaration of function 'fork' [-Wimplicit-function-declaration]
if((pid = fork())<0)
^~~~
F:\myprogram\c-program\unix-learn\base-learn1\main.c:65:17: warning: implicit declaration of function 'waitpid'; did you mean 'getpid'? [-Wimplicit-function-declaration]
if((pid=waitpid(pid,&status,0))<0)
^~~~~~~
getpid
[100%] Linking C executable base_learn1.exe
CMakeFiles\base_learn1.dir/objects.a(main.c.obj): In function `l_process':
F:/myprogram/c-program/unix-learn/base-learn1/main.c:54: undefined reference to `fork'
F:/myprogram/c-program/unix-learn/base-learn1/main.c:65: undefined reference to `waitpid'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [CMakeFiles\base_learn1.dir\build.make:105: base_learn1.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:95: CMakeFiles/base_learn1.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:102: CMakeFiles/base_learn1.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:137: base_learn1] Error 2
我们进入linux,shell命令行中查看fork函数说明
[root@redhat6 myprogram]# man 2 fork
FORK(2) Linux Programmer’s Manual FORK(2)
NAME
fork - create a child process
SYNOPSIS
#include <unistd.h>
pid_t fork(void);
DESCRIPTION
fork() creates a new process by duplicating the calling process. The new process, referred to as the child, is an exact duplicate of
the calling process, referred to as the parent, except for the following points:
* The child has its own unique process ID, and this PID does not match the ID of any existing process group (setpgid(2)).
* The child’s parent process ID is the same as the parent’s process ID.
* The child does not inherit its parent’s memory locks (mlock(2), mlockall(2)).
* Process resource utilizations (getrusage(2)) and CPU time counters (times(2)) are reset to zero in the child.
* The child’s set of pending signals is initially empty (sigpending(2)).
* The child does not inherit semaphore adjustments from its parent (semop(2)).
* The child does not inherit record locks from its parent (fcntl(2)).
* The child does not inherit timers from its parent (setitimer(2), alarm(2), timer_create(2)).
我们可以清晰知道,fork()函数为linux内置库函数,它包含的声明在/usr/include/unistd.h中:
。。。。。。。。。。。。。。。。。。。。。。
Return -1 for errors, 0 to the new process,
and the process ID of the new process to the old process. */
extern __pid_t fork (void) __THROW;
#if (defined __USE_XOPEN_EXTENDED && !defined __USE_XOPEN2K8) \
|| defined __USE_BSD
/* Clone the calling process, but without copying the whole address space.
The calling process is suspended until the new process exits or is
replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
and the process ID of the new process to the old process. */
extern __pid_t vfork (void) __THROW;
#endif /* Use BSD or XPG < 7. */
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
而我们本地windows搭建的MinGW环境中,unistd.h中并为进行fork()函数声明,所以报错:
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#ifndef _UNISTD_H
#define _UNISTD_H
#define __UNISTD_H_SOURCED__ 1
#include <io.h>
#include <process.h>
#include <getopt.h>
/* These are also defined in stdio.h. */
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
/* These are also defined in stdio.h. */
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
/* Used by shutdown(2). */
#ifdef _POSIX_SOURCE
/* MySql connector already defined SHUT_RDWR. */
#ifndef SHUT_RDWR
#define SHUT_RD 0x00
#define SHUT_WR 0x01
#define SHUT_RDWR 0x02
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#pragma push_macro("sleep")
#undef sleep
unsigned int __cdecl sleep (unsigned int);
#pragma pop_macro("sleep")
#if !defined __NO_ISOCEXT
#include <sys/types.h> /* For useconds_t. */
int __cdecl __MINGW_NOTHROW usleep(useconds_t);
#endif /* Not __NO_ISOCEXT */
#ifndef FTRUNCATE_DEFINED
#define FTRUNCATE_DEFINED
/* This is defined as a real library function to allow autoconf
to verify its existence. */
#if !defined(NO_OLDNAMES) || defined(_POSIX)
int ftruncate(int, off32_t);
int ftruncate64(int, off64_t);
int truncate(const char *, off32_t);
int truncate64(const char *, off64_t);
#ifndef __CRT__NO_INLINE
__CRT_INLINE int ftruncate(int __fd, off32_t __length)
{
return _chsize (__fd, __length);
}
#endif /* !__CRT__NO_INLINE */
#else
int ftruncate(int, _off_t);
int ftruncate64(int, _off64_t);
int truncate(const char *, _off_t);
int truncate64(const char *, _off64_t);
#ifndef __CRT__NO_INLINE
__CRT_INLINE int ftruncate(int __fd, _off_t __length)
{
return _chsize (__fd, __length);
}
#endif /* !__CRT__NO_INLINE */
#endif
#endif /* FTRUNCATE_DEFINED */
#ifndef _FILE_OFFSET_BITS_SET_FTRUNCATE
#define _FILE_OFFSET_BITS_SET_FTRUNCATE
#if (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64))
#define ftruncate ftruncate64
#endif /* _FILE_OFFSET_BITS_SET_FTRUNCATE */
#endif /* _FILE_OFFSET_BITS_SET_FTRUNCATE */
#ifndef _CRT_SWAB_DEFINED
#define _CRT_SWAB_DEFINED /* Also in stdlib.h */
void __cdecl swab(char *_Buf1,char *_Buf2,int _SizeInBytes) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
#endif
#ifndef _CRT_GETPID_DEFINED
#define _CRT_GETPID_DEFINED /* Also in process.h */
int __cdecl getpid(void) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
#endif
#ifdef __cplusplus
}
#endif
#include <pthread_unistd.h>
#undef __UNISTD_H_SOURCED__
#endif /* _UNISTD_H */
我们如果要调取fork(),waitpid()等linux内置库函数,最好的方式还是在linux中编写程序,进行编译运行。