fork(), sleep(), and pipe(int *fd) in Mac OS X - c

I am taking a class called 'Operating Systems' and we are learning about these functions. I have a Mac and i want to know if these function work on Mac, or do I have to install linux. If I can't do this on Mac, what linux distribution should I install? (There's so many, I don't know which one to get).

Your prototype for pipe() is wrong, but all three functions are part of POSIX. Since OS X is a POSIX operating system, it supports all three. Note that you will need to install Apple's developer tools in order to have access to a compiler and the appropriate headers and such in order to build software that uses them.

I just took Operating Systems, and since the course revolves around UNIX, if you were on Windows, I'd recommend installing Linux just for the sake of the course. Since you are on a mac, it shouldn't be too different. By the way, most distros have live versions, so you can just boot up Linux for an assignment or something, if you want. Any popular distro would do just fine.

Related

Programming in C - Differences between Linux and OSX

Hello I'm looking into C Programming.
I'm wondering if there are differences between Linux and OSX in C? I know there are some between Windows and Linux/Unix (like getting a system timestamp). Are there any specific commands or techniques which won't work one of the two? Should "basic" programs run on both?
I'm aware that C isn't a cross compiling language but OSX and Linux are both Unix - aren't they?
What changes is not the language itself, but the libraries (and related API calls). There is no difference between Mac OSX and Linux under this aspect, as long as you stick with standard POSIX calls. Both Linux and Mac OSX are POSIX-compliant systems.
Of course, when talking about proprietary Apple libraries, you can't expect to find them under Linux. But this is another problem. Same for Linux internals.
Note that we are talking about source compatibility, not binary compatibility. You won't have to modify your source code at all, but you will have to compile it for each platform separately.
Linux includes quite a few extensions over the basic POSIX standard that both Linux and Darwin follow (Linux is "standard" in that it is exactly like Linux). As Stefano notes, in many cases this is fine, but if you have a program that was written for Linux without concern for portability ("runs on both Ubuntu and SuSE" is not "portability"), you should expect to see some different behaviors and missing extensions. For instance, mremap() and pipe2() are Linux-specific functions. SOCK_NONBLOCK is a Linux-specific flag to socket(), etc. The man pages will typically indicate when something is Linux-specific in the "Conforming To" section.

How to test POSIX compatibility?

I am writing a C program with POSIX API and using Linux.
I compiled and ran it on a friend's Mac OSX PC and there was a small error, but I did not use Linux specific features.
I will use some specific features that Linux adds to the API. I will also use specific POSIX extensions for Mac Os X and FreeBSD.
I will use conditional compilation to choose the code. If the OS is none of those, I will use generic POSIX code.
I do not own Darwin/Mac OSX and FreeBSD, Linux is the only OS that I have in my PC. I cannot download and install FreeBSD, because it is more than 500 MB.
I want to know a way to test if the program will compile and behave as expected on other POSIX systems.
I wonder if there is a POSIX simulator and compiler to do tests.
The tests are simple, they do not use GUI and drivers, they are only command line.
I will need to do 3 tests: FreeBSD, Mac OSX/Darwin and Generic POSIX, but I do not have the tools.
EDIT
Is there a minimal version of FreeBSD and Darwin without GUI, but with GCC/G++ and ssh/scp? Darwin is free, is not it?
My PC is old, but I think I can install them in a virtual machine, create a virtual network and use ssh/scp to transfer and test the programs.
One simple way is to compile your program with the proper feature test macros. For example if you define _POSIX_C_SOURCE to the target version of POSIX (currently 200809L), you will request the system headers expose to your program nothing except what's needed/allowed by POSIX base. This can be done via the command line CFLAGS with -D_POSIX_C_SOURCE=200809L. If you want the XSI option (full Single Unix Standard functionality, which is a superset of POSIX base) then use -D_XOPEN_SOURCE=700 instead.
This will not help you detect problems that come from either certain systems lacking POSIX functionality (for example, OSX is broken and lacks a working sem_init last I checked, even though it's mandatory in POSIX), or from writing code that depends on non-standard behavior in the POSIX-standard interfaces (for example, using GNU regex extensions in the expressions you pass to regcomp) but it will help you catch any accidental usage of interfaces not in the standard.
If you want to compile for other system, you usually don't need to have the other system, you just need an appropriate cross compiler.

Is a Linux executable "compatible" with OS X?

If you compile a program in say, C, on a Linux based platform, then port it to use the MacOS libraries, will it work?
Is the core machine-code that comes from a compiler compatible on both Mac and Linux?
The reason I ask this is because both are "UNIX based" so I would think this is true, but I'm not really sure.
No, Linux and Mac OS X binaries are not cross-compatible.
For one thing, Linux executables use a format called ELF.
Mac OS X executables use Mach-O format.
Thus, even if a lot of the libraries ordinarily compile separately on each system, they would not be portable in binary format.
Furthermore, Linux is not actually UNIX-based. It does share a number of common features and tools with UNIX, but a lot of that has to do with computing standards like POSIX.
All this said, people can and do create pretty cool ways to deal with the problem of cross-compatibility.
EDIT:
Finally, to address your point on byte-code: when making a binary, compilers usually generate machine code that is specific to the platform you're developing on. (This isn't always the case, but it usually is.)
In general you can easily port a program across various Unix brands. However you need (at least) to recompile it on each platform.
Executables (binaries) are not usable on several platforms, because an executable is tightly coupled with the operating system's ABI (Application Binary Interface), i.e. the conventions of how an application communicates with the operating system.
For instance if your program prints a string onto the console using the POSIX write call, the ABI specifies:
How a system call is done (Linux used to call the 0x80 software interrupt on x86, now it uses the specific sysenter instruction)
The system call number
How are the function's arguments transmitted to the system
Any kind of alignment
...
And this varies a lot across operating systems.
Note however that in some cases there may be “ABI adapters” allowing to run binaries of one OS onto another OS. For instance Wine allows you to run Windows executables on various Unix flavors, NDISwrapper allows you to use Windows network drivers on Linux.
"bytecode" usually refers to code executed by a virtual machine (e.g. for java or python). C is compiled to machine code, which the CPU can execute directly. Machine language is hardware-specific so it it would be the same under any OS running on an intel chip (even under Windows), but the details of how the machine code is wrapped into an executable file, and how it is integrated with system calls and dynamically linked libraries are different from system to system.
So no, you can't take compiled code and use it in a different OS. (However, there are "cross-compilers" that run on one OS but generate code that will run on another OS).
There is no "core byte-code that comes from a compiler". There is only machine code.
While the same machine instructions may be applicable under several operating systems (as long as they're run on the same hardware), there is much more to a hosted executable than that, and since a compiled and linked native executable for Linux has very different runtime and library requirements from one on BSD or Darwin, you won't be able to run one binary on the other system.
By contrast, Windows binaries can sometimes be executed under Linux, because Linux provides both a binary format loader for Windows's PE format, as well as an extensive API implementation (Wine). In principle this idea can be used on other platforms as well, but I'm not aware of anyone having written this for Linux<->Darwin. If you already have the source code, and it compiles in Linux, then you have a good chance of it also compiling under MacOS (modulo UI components, of course).
Well, maybe... but most probably not.
But if it does, it's not "because both are UNIX" it's because:
Mac computers happen to use the same processor nowadays (this was very different in the past)
You happen to use a program that has no dependency on any library at all (very unlikely)
You happen to use the same runtime libraries
You happen to use a loader/binary format that is compatible with both.

Programming MacOS-X and the Linux API - POSIX compatible?

I am learning(just finished) C+Algorithms and am a newbie. I wanted to know if the POSIX Linux API is used on a Mac. Linux has functions like pread pwrite readv writev nftw symlink pipe popen posix_self sigprocmask sigaction (system calls). Does the Mac have the same API?? I heard that OS-X is based on a BSD kernel so i was wondering if i could use code written on Linux on OS-X if i stuck to using only POSIX functions. How similar is the OS-X API to the Linux POSIX/SUSv3 API??
The Wikipedia article on POSIX has a section dedicated to compliance. Short answer: yeah, it's going to have all the POSIX functionality you're likely to come up against. And it will probably have more (e.g. a lot of BSD apis that might not actually be POSIX)
If you're asking if you can write code that works on both platforms, the answer is yes. If you're asking if that's easy, the answer is probably no.
POSIX is not a Linux standard, but Linux follows it, as does OSX, BSD, HPUX, Solaris, and even some real time operating systems like QNX (just to name a few).
If you program to a POSIX API as much as possible, porting your code will be much easier.
They're close. There are some BSD things you won't find in Linux, and some Linux things you won't find on BSD. You can nearly always restrict yourself to a subset which is compatible with both platforms without much trouble. POSIX APIs which are not portable are often given the _np designator. You'll also find some things are not (yet) supported on one platform. There is a safe middle ground in the more established APIs. And this can of course vary by which OS versions you are targeting. Implementations may vary slightly if you wander into less common APIs. My first stop is to check the man pages.

Possible to create universal linux program?

In mac os x, you can combine 32bit, powerpc and 64bit binaries in one executable using "lipo" is something like this possible in linux?
I think Fatelf (available at http://icculus.org/fatelf/ ) is what you are actually asking for, but it requires certain patches to kernel, glibc, gdb etc. So it's currently not for the faint of heart to use. It may be a reasonable burden for a developer to compile on a modified system, but it also requires client-side systems to be modified, too.

Resources