diff --git a/build.sh b/build.sh
index 4c88b53..5e56d60 100755
--- a/build.sh
+++ b/build.sh
@@ -22,6 +22,7 @@
 
 : ${OUTDIR:=.}
 OUTLIB="$OUTDIR/lib"
+PLATFORM=$(/bin/uname -s)
 
 # Directory to find libraries in for '-lXXX'.
 libdir=$exec_prefix/lib
@@ -143,7 +144,12 @@ compile $OBJS
 
 # Link all the objects together.
 echo "linking make..."
+set -x
+if [ ! ${PLATFORM} = "OS/390" ]; then
+$CC $CFLAGS $LDFLAGS -L"$OUTLIB" -o "$OUTDIR/makenew$EXEEXT" $objs -lgnu $LOADLIBES
+else
 $CC $CFLAGS $LDFLAGS -L"$OUTLIB" $objs -lgnu $LOADLIBES -o "$OUTDIR/makenew$EXEEXT"
+fi
 mv -f "$OUTDIR/makenew$EXEEXT" "$OUTDIR/make$EXEEXT"
 
 echo done.
diff --git a/lib/glob.c b/lib/glob.c
index adad16f..aa57b92 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -20,6 +20,14 @@ USA.  */
 #if defined _AIX && !defined __GNUC__
  #pragma alloca
 #endif
+#ifdef __MVS__
+  #ifndef alloca                                           
+    #define alloca(x) __alloca2(x)                          
+    #pragma linkage(__alloca2,builtin)                    
+    void *__alloca2(unsigned int x);                      
+    #define __alloca2 __alloca2
+  #endif
+#endif
 
 #ifdef	HAVE_CONFIG_H
 # include <config.h>
@@ -229,7 +237,7 @@ extern char *alloca ();
 #endif
 
 #ifndef __GNU_LIBRARY__
-# define __stat stat
+# define __gnustat stat
 # ifdef STAT_MACROS_BROKEN
 #  undef S_ISDIR
 # endif
@@ -247,8 +255,8 @@ extern char *alloca ();
 # define readdir(str) __readdir (str)
 # define getpwnam_r(name, bufp, buf, len, res) \
    __getpwnam_r (name, bufp, buf, len, res)
-# ifndef __stat
-#  define __stat(fname, buf) __xstat (_STAT_VER, fname, buf)
+# ifndef __gnustat
+#  define __gnustat(fname, buf) __xstat (_STAT_VER, fname, buf)
 # endif
 #endif
 
@@ -284,8 +292,8 @@ extern char *alloca ();
 # define __alloca alloca
 #endif
 
-#if !defined __stat
-# define __stat stat
+#if !defined __gnustat
+# define __gnustat stat
 #endif
 
 #ifdef HAVE_GETLOGIN_R
@@ -816,7 +824,7 @@ glob (pattern, flags, errfunc, pglob)
       if ((flags & GLOB_NOCHECK)
 	  || (((flags & GLOB_ALTDIRFUNC)
 	       ? (*pglob->gl_stat) (dirname, &st)
-	       : __stat (dirname, &st)) == 0
+	       : __gnustat (dirname, &st)) == 0
 	      && S_ISDIR (st.st_mode)))
 	{
 	  pglob->gl_pathv
@@ -962,7 +970,7 @@ glob (pattern, flags, errfunc, pglob)
 
 		  /* First check whether this really is a directory.  */
 		  if (((flags & GLOB_ALTDIRFUNC)
-		       ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
+		       ? (*pglob->gl_stat) (dir, &st) : __gnustat (dir, &st)) != 0
 		      || !S_ISDIR (st.st_mode))
 		    /* No directory, ignore this entry.  */
 		    continue;
@@ -1038,7 +1046,7 @@ glob (pattern, flags, errfunc, pglob)
       for (i = oldcount; i < pglob->gl_pathc; ++i)
 	if (((flags & GLOB_ALTDIRFUNC)
 	     ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
-	     : __stat (pglob->gl_pathv[i], &st)) == 0
+	     : __gnustat (pglob->gl_pathv[i], &st)) == 0
 	    && S_ISDIR (st.st_mode))
 	  {
  	    size_t len = strlen (pglob->gl_pathv[i]) + 2;
@@ -1271,7 +1279,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
 # endif
 	  if (((flags & GLOB_ALTDIRFUNC)
 	       ? (*pglob->gl_stat) (fullname, &st)
-	       : __stat (fullname, &st)) == 0)
+	       : __gnustat (fullname, &st)) == 0)
 	    /* We found this file to be existing.  Now tell the rest
 	       of the function to copy this name into the result.  */
 	    flags |= GLOB_NOCHECK;
diff --git a/src/arscan.c b/src/arscan.c
index 3ce21db..06d9965 100644
--- a/src/arscan.c
+++ b/src/arscan.c
@@ -331,7 +331,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *varg)
 #endif
 
 #ifndef WINDOWS32
-# if !defined (__ANDROID__) && !defined (__BEOS__)
+# if !defined (__ANDROID__) && !defined (__BEOS__) && !defined(__MVS__)
 #  include <ar.h>
 # else
    /* These platforms don't have <ar.h> but have archives in the same format
@@ -426,6 +426,9 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
     char buf[SARMAG];
     int nread;
     nread = readbuf (desc, buf, SARMAG);
+#ifdef __MVS__
+    __e2a_s(buf);
+#endif
     if (nread != SARMAG || memcmp (buf, ARMAG, SARMAG))
       goto invalid;
   }
@@ -613,6 +616,9 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
 
 #else   /* Not AIAMAG.  */
         nread = readbuf (desc, &member_header, AR_HDR_SIZE);
+#ifdef __MVS__
+        __e2a_l((char*)&member_header, sizeof(member_header));
+#endif
         if (nread == 0)
           /* No data left means end of file; that is OK.  */
           break;
diff --git a/src/job.c b/src/job.c
index ae1f18b..844d85e 100644
--- a/src/job.c
+++ b/src/job.c
@@ -26,6 +26,93 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "variable.h"
 #include "os.h"
 
+#ifdef __MVS__
+int execvpe(const char* name,
+                       char* const argv[],
+                       char* const envp[]) {
+  int lp, ln;
+  const char* p;
+
+  int eacces = 0, etxtbsy = 0;
+  char *bp, *cur, *path, *buf = 0;
+
+  // Absolute or Relative Path Name
+  if (strchr(name, '/')) {
+    return execve(name, argv, envp);
+  }
+
+  // Get the path we're searching
+  if (!(path = getenv("PATH"))) {
+    if ((cur = path = (char*)alloca(2)) != NULL) {
+      path[0] = ':';
+      path[1] = '\0';
+    }
+  } else {
+    char* n = (char*)alloca(strlen(path) + 1);
+    strcpy(n, path);
+    cur = path = n;
+  }
+
+  if (path == NULL ||
+      (bp = buf = (char*)alloca(strlen(path) + strlen(name) + 2)) == NULL)
+    goto done;
+
+  while (cur != NULL) {
+    p = cur;
+    if ((cur = strchr(cur, ':')) != NULL) *cur++ = '\0';
+
+    if (!*p) {
+      p = ".";
+      lp = 1;
+    } else
+      lp = strlen(p);
+    ln = strlen(name);
+
+    memcpy(buf, p, lp);
+    buf[lp] = '/';
+    memcpy(buf + lp + 1, name, ln);
+    buf[lp + ln + 1] = '\0';
+
+  retry:
+    (void)execve(bp, argv, envp);
+    switch (errno) {
+      case EACCES:
+        eacces = 1;
+        break;
+      case ENOTDIR:
+      case ENOENT:
+        break;
+      case ENOEXEC: {
+        size_t cnt;
+        char** ap;
+
+        for (cnt = 0, ap = (char**)argv; *ap; ++ap, ++cnt)
+          ;
+        if ((ap = (char**)alloca((cnt + 2) * sizeof(char*))) != NULL) {
+          memcpy(ap + 2, argv + 1, cnt * sizeof(char*));
+
+          ap[0] = (char*)"sh";
+          ap[1] = bp;
+          (void)execve("/bin/sh", ap, envp);
+        }
+        goto done;
+      }
+      case ETXTBSY:
+        if (etxtbsy < 3) (void)sleep(++etxtbsy);
+        goto retry;
+      default:
+        goto done;
+    }
+  }
+  if (eacces)
+    errno = EACCES;
+  else if (!errno)
+    errno = ENOENT;
+done:
+  return (-1);
+}
+#endif
+
 /* Default shell to use.  */
 #ifdef WINDOWS32
 # ifdef HAVE_STRINGS_H
@@ -2297,8 +2384,14 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
 #if !defined(USE_POSIX_SPAWN)
 
   pid = vfork();
-  if (pid != 0)
+  if (pid != 0) {
+#ifdef __MVS__
+    __set_autocvt_on_untagged_fd_stream(fdin, 1047, 1);
+    __set_autocvt_on_untagged_fd_stream(fdout, 1047, 1);
+    __set_autocvt_on_untagged_fd_stream(fderr, 1047, 1);
+#endif
     return pid;
+  }
 
   /* We are the child.  */
   unblock_all_sigs ();
@@ -2544,6 +2637,10 @@ exec_command (char **argv, char **envp)
   /* the file might have a strange shell extension */
   if (errno == ENOENT)
     errno = ENOEXEC;
+#elif __MVS__
+
+  environ = envp;
+  execvpe (argv[0], argv, envp);
 
 # else
   /* Run the program.  */
@@ -2610,6 +2707,9 @@ exec_command (char **argv, char **envp)
         pid = spawnvpe (P_NOWAIT, shell, new_argv, envp);
         if (pid >= 0)
           break;
+# elif __MVS__
+        environ = envp;
+        execvpe (shell, new_argv, envp);
 # else
         execvp (shell, new_argv);
 # endif
diff --git a/src/main.c b/src/main.c
index 78a27d7..2816f59 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1046,14 +1046,172 @@ reset_jobserver (void)
   jobserver_auth = NULL;
 }
 
+#ifdef __MVS__
+#include <string.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ps.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <varargs.h>
+#include <limits.h>
+#include <_Nascii.h>
+#include <fcntl.h>
+#include <libgen.h>
+
+int __setccsid(int fd, int ccsid) 
+{
+  attrib_t attr;
+  int rc;
+
+  memset(&attr, 0, sizeof(attr));
+  attr.att_filetagchg = 1;
+  attr.att_filetag.ft_ccsid = ccsid;
+  attr.att_filetag.ft_txtflag = 1;
+
+  rc = __fchattr(fd, &attr, sizeof(attr));
+  return rc;
+}
+
+void __updateccsid(int fd, const char* path, int oflag, int perm) 
+{ 
+  int rc;
+  if (oflag & O_CREAT) {
+    rc = __setccsid(fd, 819);
+  }
+}
+
+int __pipe(int [2]);
+#pragma map(__pipe, "pipe")
+int __open(const char *filename, int opts, ...);
+#pragma map(__open, "@@A00144")
+
+int __open_ascii(const char *filename, int opts, ...) {
+  va_list ap;
+  va_start(ap, opts);
+  int perms = va_arg(ap, int);
+  struct stat sb;
+  int is_new_file = stat(filename, &sb) != 0;
+  int fd = __open(filename, opts, perms);
+  // Tag new files as 819
+  if (fd >= 0 && is_new_file)
+    __chgfdccsid(fd, 819);
+  va_end(ap);
+  return fd;
+}
+
+int __pipe_ascii(int fd[2]) {
+  int ret = __pipe(fd);
+
+  // Default ccsid for new pipes should be 819
+  __chgfdccsid(fd[0], 819);
+  __chgfdccsid(fd[1], 819);
+  return ret;
+}
+
+int __getfdccsid(int fd) {
+  struct stat st;
+  int rc;
+  rc = fstat(fd, &st);
+  if (rc != 0)
+    return -1;
+  unsigned short ccsid = st.st_tag.ft_ccsid;
+  if (st.st_tag.ft_txtflag) {
+    return 65536 + ccsid;
+  }
+  return ccsid;
+}
+
+int __chgfdccsid(int fd, unsigned short ccsid) 
+{
+  attrib_t attr;
+  memset(&attr, 0, sizeof(attr));
+  attr.att_filetagchg = 1;
+  attr.att_filetag.ft_ccsid = ccsid;
+  if (ccsid != FT_BINARY) {
+    attr.att_filetag.ft_txtflag = 1;
+  }
+  return __fchattr(fd, &attr, sizeof(attr));
+}
+
+void __set_autocvt_on_untagged_fd_stream(int fd, unsigned short ccsid, unsigned char txtflag) {
+  struct file_tag tag;
+
+  tag.ft_ccsid = ccsid;
+  tag.ft_txtflag = txtflag;
+
+  struct f_cnvrt req = {SETCVTON, 0, (short)ccsid};
+
+  if (!isatty(fd) && 0 == __getfdccsid(fd)) {
+    fcntl(fd, F_CONTROL_CVT, &req);
+    fcntl(fd, F_SETTAG, &tag);
+  }
+}
+
+int orig_mode;
+int orig_cvstate;
+
+void __init()
+{
+    // With "_EDC_SIG_DFLT" set to '0', a process closing with SIGINT send output both to stderr and stdout. 
+    // Setting "_EDC_SIG_DFLT" default action of the following signals is abnormal termination of the process with no message output: SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGPOLL, SIGPROF, SIGSYS, SIGTERM, SIGUSR1, SIGUSR2, and SIGVTALRM
+    setenv("_EDC_SIG_DFLT", "1", 1);
+
+    // Setting _EDC_SUSV3 can be used to control the behavior of setenv() with respect to setting EINVAL when var_name is a null pointer, points to an empty string or points to a string containing an '=' character. By default, setenv() will not set EINVAL for these conditions. 
+    // When _EDC_SUSV3 is set to 1, setenv() will set errno to EINVAL if one of these conditions is true. 
+    setenv("_EDC_SUSV3", "1", 1);
+
+    // Sets the _TAG_REDIR state to txt
+    setenv("_TAG_REDIR_ERR", "txt", 1);
+    setenv("_TAG_REDIR_IN", "txt", 1);
+    setenv("_TAG_REDIR_OUT", "txt", 1);
+
+    // Force to ASCII mode and AUTOCVT to ON
+#if (__CHARSET_LIB == 1)
+    orig_mode = __ae_thread_swapmode(__AE_ASCII_MODE);
+#else
+    orig_mode = __ae_thread_swapmode(__AE_EBCDIC_MODE);
+#endif
+    orig_cvstate = __ae_autoconvert_state(_CVTSTATE_QUERY);
+    if (_CVTSTATE_OFF == orig_cvstate)
+        __ae_autoconvert_state(_CVTSTATE_ON);
+
+    setenv("_BPXK_AUTOCVT", "ON", 1);
+    char* cee_runopts_env = getenv("_CEE_RUNOPTS");
+    char* appended_cee_runopts = "FILETAG(AUTOCVT,AUTOTAG) POSIX(ON)";
+    char* new_cee_runopts = (char*)malloc(strlen(cee_runopts_env) + strlen(appended_cee_runopts) + 2);
+    memset(new_cee_runopts, 0, strlen(cee_runopts_env) + strlen(appended_cee_runopts) + 2);
+    if (cee_runopts_env)
+    {
+      strcpy(new_cee_runopts, cee_runopts_env);
+      strcat(new_cee_runopts, " ");
+    }
+    strcat(new_cee_runopts, appended_cee_runopts);
+    setenv("_CEE_RUNOPTS", new_cee_runopts, 1);
+    free(new_cee_runopts);
+}
+#endif
+
 #ifdef _AMIGA
 int
 main (int argc, char **argv)
 #else
+#ifdef __MVS__
+extern char **environ;
+int 
+main (int argc, char **argv)
+#else
 int
 main (int argc, char **argv, char **envp)
 #endif
+#endif
 {
+#ifdef __MVS__
+  char** envp = environ;
+  __init();
+#endif
+
   static char *stdin_nm = 0;
   int makefile_status = MAKE_SUCCESS;
   struct goaldep *read_files;
@@ -1072,6 +1230,12 @@ main (int argc, char **argv, char **envp)
   no_default_sh_exe = 1;
 #endif
 
+#ifdef __MVS__
+  __set_autocvt_on_untagged_fd_stream(STDIN_FILENO, 1047, 1);
+  __set_autocvt_on_untagged_fd_stream(STDOUT_FILENO, 1047, 1);
+  __set_autocvt_on_untagged_fd_stream(STDERR_FILENO, 1047, 1);
+#endif
+
   /* Useful for attaching debuggers, etc.  */
   SPIN ("main-entry");
 
@@ -1815,6 +1979,7 @@ main (int argc, char **argv, char **envp)
 
             strcat (template, DEFAULT_TMPFILE);
             outfile = get_tmpfile (&stdin_nm, template);
+            
             if (outfile == 0)
               pfatal_with_name (_("fopen (temporary file)"));
             while (!feof (stdin) && ! ferror (stdin))
diff --git a/src/makeint.h b/src/makeint.h
index c428a36..bf0529d 100644
--- a/src/makeint.h
+++ b/src/makeint.h
@@ -26,6 +26,12 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #define _GNU_SOURCE 1
 
+#ifdef __MVS__
+#include "os390.h"
+# include <fcntl.h>
+# define pipe(_p)        __pipe_ascii(_p)
+#endif
+
 /* AIX requires this to be the first thing in the file.  */
 #if HAVE_ALLOCA_H
 # include <alloca.h>
diff --git a/src/misc.c b/src/misc.c
index de19e37..439cf91 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -508,7 +508,7 @@ get_tmpfile (char **name, const char *template)
   (void) tmpnam (*name);
 # endif
 
-# ifdef HAVE_FDOPEN
+# if defined(HAVE_FDOPEN)
   /* Can't use mkstemp(), but guard against a race condition.  */
   EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
   if (fd == -1)
@@ -522,6 +522,10 @@ get_tmpfile (char **name, const char *template)
 
   umask (mask);
 
+#if defined(__MVS__)
+  __chgfdccsid(fileno(file), 819);
+#endif
+
   return file;
 }
 
diff --git a/src/output.c b/src/output.c
index 2211749..e2b6bc7 100644
--- a/src/output.c
+++ b/src/output.c
@@ -364,7 +364,10 @@ output_dump (struct output *out)
       /* Try to acquire the semaphore.  If it fails, dump the output
          unsynchronized; still better than silently discarding it.
          We want to keep this lock for as little time as possible.  */
+#ifndef __MVS__
+      //TODO: Implement alternative
       void *sem = acquire_semaphore ();
+#endif
 
       /* Log the working directory for this dump.  */
       if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
@@ -379,8 +382,11 @@ output_dump (struct output *out)
         log_working_directory (0);
 
       /* Exit the critical section.  */
+#ifndef __MVS__
+      //TODO: Implement alternative
       if (sem)
         release_semaphore (sem);
+#endif
 
       /* Truncate and reset the output, in case we use it again.  */
       if (out->out != OUTPUT_NONE)
diff --git a/src/posixos.c b/src/posixos.c
index 525f292..ee6e14d 100644
--- a/src/posixos.c
+++ b/src/posixos.c
@@ -37,7 +37,7 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 /* This section provides OS-specific functions to support the jobserver.  */
 
 /* These track the state of the jobserver pipe.  Passed to child instances.  */
-static int job_fds[2] = { -1, -1 };
+static int job_fds[2] = {};
 
 /* Used to signal read() that a SIGCHLD happened.  Always CLOEXEC.
    If we use pselect() this will never be created and always -1.
diff --git a/tests/test_driver.pl b/tests/test_driver.pl
index f18e785..46544a5 100644
--- a/tests/test_driver.pl
+++ b/tests/test_driver.pl
@@ -164,6 +164,10 @@ sub toplevel
   foreach (# UNIX-specific things
            'TZ', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH',
            'LD_LIBRARY_PATH',
+           # z/OS specific things
+           'LIBPATH',
+           '_BPXK_AUTOCVT',
+           '_TAG_REDIR_IN', '_TAG_REDIR_ERR', '_TAG_REDIR_OUT',
            # SAN things
            'ASAN_OPTIONS', 'UBSAN_OPTIONS',
            # Purify things
@@ -392,15 +396,17 @@ sub get_osname
     # to not get ugly error messages if uname can't be found.
     # Hmmm, BSD/OS 2.0's uname -a is excessively verbose.  Let's try it
     # with switches first.
-    eval "chop (\$osname = `sh -c 'uname -nmsr 2>&1'`)";
-    if ($osname =~ /not found/i) {
-      $osname = "(something posixy with no uname)";
-
-    } elsif ($@ ne "" || $?) {
-      eval "chop (\$osname = `sh -c 'uname -a 2>&1'`)";
-      if ($@ ne "" || $?) {
-        $osname = "(something posixy)";
-      }
+    if ($osname eq "") {
+      eval "chop (\$osname = `uname -nmsr 2>&1`)";
+      if ($osname =~ /not found/i) {
+        $osname = "(something posixy with no uname)";
+
+      } elsif ($@ ne "" || $?) {
+        eval "chop (\$osname = `uname -a 2>&1`)";
+        if ($@ ne "" || $?) {
+          $osname = "(something posixy)";
+        }
+     }
     }
     $vos = 0;
     $pathsep = "/";
diff --git a/src/os390.h b/src/os390.h
new file mode 100644
index 0000000..c18f764
--- /dev/null
+++ b/src/os390.h
@@ -0,0 +1,34 @@
+#ifndef H_OS390
+#define H_OS390 1
+
+#if (__CHARSET_LIB == 1)
+#undef open
+#define open __open_replaced
+#undef pipe 
+#define pipe __pipe_replaced
+#include <fcntl.h>
+#include <unistd.h>
+#undef pipe
+#undef open
+
+int __open_ascii(const char *filename, int opts, ...);
+int __pipe_ascii(int [2]);
+
+int open(const char* path, int oflag, ...) asm("__open_ascii");
+int pipe(int [2]) asm("__open_ascii");
+#endif
+
+#include <string.h>
+#include <sys/ps.h>
+#include <unistd.h>
+#include <limits.h>
+#include <_Nascii.h>
+#include <fcntl.h>
+#include <libgen.h>
+
+int __getfdccsid(int fd);
+int __setccsid(int fd, int ccsid);
+int __chgfdccsid(int fd, unsigned short ccsid);
+void __updateccsid(int fd, const char* path, int oflag, int perm);
+
+#endif
