Ejemplo n.º 1
0
int main (void) {
   pid_t childpid;
   char inbuf[MAX_CANON];
   int len;

   for( ; ; ) {
      if (fputs(PROMPT_STRING, stdout) == EOF)
          continue;
      if (fgets(inbuf, MAX_CANON, stdin) == NULL)
          continue; 
      len = strlen(inbuf);
      if (inbuf[len - 1] == '\n')
          inbuf[len - 1] = 0;
      if (strcmp(inbuf, QUIT_STRING) == 0)
          break;
      if ((childpid = fork()) == -1)
          perror("Failed to fork child");
      else if (childpid == 0) {
          executecmd(inbuf);
          return 1; 
      } else 
         wait(NULL);
   }
   return 0; 
}
Ejemplo n.º 2
0
int main (void) {
	char *backp;
	sigset_t blockmask;
	pid_t childpid;
	struct sigaction defhandler;
	int inbackground;
	char inbuf[MAX_CANON];
	int len;

	if (signalsetup(&defhandler, &blockmask, jumphd) == -1) {
		perror("Failed to set up shell signal handling");
		return 1;
	}

	for( ; ; ) {
		if ((sigsetjmp(jumptoprompt, 1)) &&   /* if return from signal, newline */
				(fputs("\n", stdout) == EOF) )
			continue;
		okaytojump = 1;
		printf("%d",(int)getpid());
		if (fputs(PROMPT_STRING, stdout) == EOF)
			continue;
		if (fgets(inbuf, MAX_CANON, stdin) == NULL)
			continue;
		len = strlen(inbuf);
		if (inbuf[len - 1] == '\n')
			inbuf[len - 1] = 0;
		if (strcmp(inbuf, QUIT_STRING) == 0)
			break;
		if ((backp = strchr(inbuf, BACK_SYMBOL)) == NULL)
			inbackground = 0;
		else {
			inbackground = 1; 
			*backp = 0;
		}
		if (sigprocmask(SIG_BLOCK, &blockmask, NULL) == -1)
			perror("Failed to block signals");
		if ((childpid = fork()) == -1)
			perror("Failed to fork");
		else if (childpid == 0) {
			if (inbackground && (setpgid(0, 0) == -1))
				return 1; 
			if ((sigaction(SIGINT, &defhandler, NULL) == -1) ||
					(sigaction(SIGQUIT, &defhandler, NULL) == -1) ||
					(sigprocmask(SIG_UNBLOCK, &blockmask, NULL) == -1)) {
				perror("Failed to set signal handling for command "); 
				return 1; 
			}
			executecmd(inbuf);
			return 1;
		}
		if (sigprocmask(SIG_UNBLOCK, &blockmask, NULL) == -1)
			perror("Failed to unblock signals");
		if (!inbackground)        /* wait explicitly for the foreground process */
			waitpid(childpid, NULL, 0);
		while (waitpid(-1, NULL, WNOHANG) > 0);    /* wait for background procs */
	}
	return 0;
}
Ejemplo n.º 3
0
//	===========================================================================
//	METHOD: authdclient::setserviceonboot
//	===========================================================================
int authdclient::setserviceonboot (const string &servicename, bool enabled)
{
	string command;

	command.printf ("setonboot \"%S\" %d\n", servicename.str(), (int) enabled);
			  
	return executecmd (command);
}
Ejemplo n.º 4
0
//	===========================================================================
//	METHOD: authdclient::reloadservice
//	===========================================================================
int authdclient::reloadservice (const string &servicename)
{	
	string command;

	command.printf ("reloadservice \"%S\"\n", servicename.str());
			  
	return executecmd (command);
}
Ejemplo n.º 5
0
//	===========================================================================
//	METHOD: authdclient::deluser
//	===========================================================================
int authdclient::deluser (const string &username)
{
	string command;

	command.printf ("deleteuser \"%S\"\n", username.str());
	
	return executecmd (command);
}
Ejemplo n.º 6
0
//	===========================================================================
//	METHOD: authdclient::installfile
//	===========================================================================
int authdclient::installfile (const string &source, const string &dest)
{
	string command;

	command.printf ("installfile \"%S\" \"%S\"\n", source.str(), dest.str());
	
	return executecmd (command);
}
Ejemplo n.º 7
0
//	===========================================================================
//	METHOD: authdclient::deletefile
//	===========================================================================
int authdclient::deletefile  (const string &conffile)
{
	string command;

	command.printf ("deletefile \"%S\"\n", conffile.str());
	
	return executecmd (command);
}
Ejemplo n.º 8
0
//	===========================================================================
//	METHOD: authdclient::setusershell
//	===========================================================================
int authdclient::setuserpass (const string &username, const string &password)
{
	string command;

	command.printf ("setuserpass \"%S\" \"%S\"\n", username.str(), 
				    password.str());
			  
	return executecmd (command);
}
Ejemplo n.º 9
0
//	===========================================================================
//	METHOD: authdclient::adduser
//	===========================================================================
int authdclient::adduser (const string &username,
				  		const string &shell, const string &passwd)
{
	string command;

	command.printf ("createuser \"%S\" \"%S\"\n", username.str(), passwd.str());
	
	return executecmd (command);
}
Ejemplo n.º 10
0
//	===========================================================================
//	METHOD: authdclient::setusershell
//	===========================================================================
int authdclient::setusershell (const string &username, const string &shell)
{
	string command;

	command.printf ("setusershell \"%S\" \"%S\"\n", username.str(), 
				    shell.str());
			  
	return executecmd (command);
}
Ejemplo n.º 11
0
//	===========================================================================
//	METHOD: authdclient::setquota
//	===========================================================================
int authdclient::setquota (const string &username, unsigned int softlimit, 
						 unsigned int hardlimit)
{
	string command;

	command.printf ("setquota \"%S\" %u %u\n", username.str(), 
				    softlimit, hardlimit);
			  
	return executecmd (command);
}
Ejemplo n.º 12
0
int builtin_exec_from_history(cmd_t* cmd, job_list_t* jobs, history_t* hist) {
  int index = (int) strtol(cmd->args[0], NULL, 10);
  cmd_t* past_cmd = get_from_history(hist, index);
  if (past_cmd) {
    cmd_t* new_cmd = copycmd(past_cmd);
    printcmd(new_cmd, stdout);
    return executecmd(new_cmd, jobs, hist);
  }
  return COMMAND_NOT_FOUND;
}
Ejemplo n.º 13
0
int main (int argc, char **argv)
{
    string user; //user name
    char* host = (char*)malloc(300); //host name
    if (getlogin() != NULL) 
    {
        user = getlogin();
    }
    else 
    {
        perror("Error with getting user");
    }
    if (gethostname(host, 300) == -1) 
    {
        perror("Error with getting host name");
    }
    //cout << host << endl;
    while (true)
    {
        BEGINNING:
        string cmd;
        string test = "test";
        string bracket = "[";
        cout << user << "@" << host <<"$ ";
        getline(cin, cmd);
        parsing(cmd);
        if(AreParenBal(cmd) == false)
        {
            perror("Parenthesis not balanced\n");
            goto BEGINNING;
        }
        char* b[MEMORY]; //character array that stores commands
        char command[MEMORY]; //char array that holds the converted command
        //cout << "Copying \n";
        for(unsigned i =0; cmd[i] != '\0'; i++)
        {
            command[i] = cmd[i];
        }
        command[cmd.length()] = '\0';
        for (unsigned i = 0; command[i] != '\0'; i++) //outputs user input 
        {
            cout << command[i];
        }
        cout << endl;
        commandsort(command, b);
        queue<string> connectors;
        cout << "Executing commands\n";
        executecmd(b, connectors);
        cout << "Executing done\n";
        
        
    }
    free (host);
    return 0;
}
Ejemplo n.º 14
0
int main()
{
	char linea[MAXLEN];
	int result=1;
	while(result)
	{
		printf("vshell > ");
		fflush(stdout);
		read(0,linea,80);
		locateend(linea);
		result=executecmd(linea);
	} 
}
Ejemplo n.º 15
0
int main (void) {
   sigset_t blockmask;
   pid_t childpid;
   struct sigaction defaction;
   char inbuf[MAX_CANON];
   int len;

   if (signalsetup(&defaction, &blockmask, SIG_IGN) == -1) {
      perror("Failed to set up shell signal handling");
      return 1;
   }
   if (sigprocmask(SIG_BLOCK, &blockmask, NULL) == -1) {
      perror("Failed to block signals");
      return 1;
   }

   for( ; ; ) {
      if (fputs(PROMPT_STRING, stdout) == EOF)
          continue;
      if (fgets(inbuf, MAX_CANON, stdin) == NULL)
          continue;
      len = strlen(inbuf);
      if (inbuf[len - 1] == '\n')
         inbuf[len - 1] = 0;
      if (strcmp(inbuf, QUIT_STRING) == 0)
          break;
      if ((childpid = fork()) == -1) {
          perror("Failed to fork child to execute command");
      } else if (childpid == 0) {
          if ((sigaction(SIGINT, &defaction, NULL) == -1) ||
              (sigaction(SIGQUIT, &defaction, NULL) == -1) ||
              (sigprocmask(SIG_UNBLOCK, &blockmask, NULL) == -1)) {
              perror("Failed to set signal handling for command ");
              return 1;
          }
          executecmd(inbuf);
          return 1;
      }
      wait(NULL);
   }
   return 0;
}
Ejemplo n.º 16
0
int runLINK()
{
#if _WIN32
    if (global.params.is64bit)
    {
        OutBuffer cmdbuf;

        cmdbuf.writestring("/NOLOGO ");

        for (size_t i = 0; i < global.params.objfiles->dim; i++)
        {
            if (i)
                cmdbuf.writeByte(' ');
            const char *p = (*global.params.objfiles)[i];
            const char *basename = FileName::removeExt(FileName::name(p));
            const char *ext = FileName::ext(p);
            if (ext && !strchr(basename, '.'))
            {
                // Write name sans extension (but not if a double extension)
                writeFilename(&cmdbuf, p, ext - p - 1);
            }
            else
                writeFilename(&cmdbuf, p);
            FileName::free(basename);
        }

        if (global.params.resfile)
        {
            cmdbuf.writeByte(' ');
            writeFilename(&cmdbuf, global.params.resfile);
        }

        cmdbuf.writeByte(' ');
        if (global.params.exefile)
        {   cmdbuf.writestring("/OUT:");
            writeFilename(&cmdbuf, global.params.exefile);
        }
        else
        {   /* Generate exe file name from first obj name.
             * No need to add it to cmdbuf because the linker will default to it.
             */
            const char *n = (*global.params.objfiles)[0];
            n = FileName::name(n);
            global.params.exefile = (char *)FileName::forceExt(n, "exe");
        }

        // Make sure path to exe file exists
        ensurePathToNameExists(Loc(), global.params.exefile);

        cmdbuf.writeByte(' ');
        if (global.params.mapfile)
        {   cmdbuf.writestring("/MAP:");
            writeFilename(&cmdbuf, global.params.mapfile);
        }
        else if (global.params.map)
        {
            const char *fn = FileName::forceExt(global.params.exefile, "map");

            const char *path = FileName::path(global.params.exefile);
            const char *p;
            if (path[0] == '\0')
                p = FileName::combine(global.params.objdir, fn);
            else
                p = fn;

            cmdbuf.writestring("/MAP:");
            writeFilename(&cmdbuf, p);
        }

        for (size_t i = 0; i < global.params.libfiles->dim; i++)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DEFAULTLIB:");
            writeFilename(&cmdbuf, (*global.params.libfiles)[i]);
        }

        if (global.params.deffile)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DEF:");
            writeFilename(&cmdbuf, global.params.deffile);
        }

        if (global.params.symdebug)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DEBUG");

            // in release mode we need to reactivate /OPT:REF after /DEBUG
            if (global.params.release)
                cmdbuf.writestring(" /OPT:REF");
        }

        if (global.params.dll)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DLL");
        }

        for (size_t i = 0; i < global.params.linkswitches->dim; i++)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring((*global.params.linkswitches)[i]);
        }

        /* Append the path to the VC lib files, and then the SDK lib files
         */
        const char *vcinstalldir = getenv("VCINSTALLDIR");
        if (vcinstalldir)
        {   cmdbuf.writestring(" \"/LIBPATH:");
            cmdbuf.writestring(vcinstalldir);
            cmdbuf.writestring("lib\\amd64\"");
        }

        const char *windowssdkdir = getenv("WindowsSdkDir");
        if (windowssdkdir)
        {   cmdbuf.writestring(" \"/LIBPATH:");
            cmdbuf.writestring(windowssdkdir);
            cmdbuf.writestring("lib\\x64\"");
        }

        char *p = cmdbuf.peekString();

        const char *lnkfilename = NULL;
        size_t plen = strlen(p);
        if (plen > 7000)
        {
            lnkfilename = FileName::forceExt(global.params.exefile, "lnk");
            File flnk(lnkfilename);
            flnk.setbuffer(p, plen);
            flnk.ref = 1;
            if (flnk.write())
                error(Loc(), "error writing file %s", lnkfilename);
            if (strlen(lnkfilename) < plen)
                sprintf(p, "@%s", lnkfilename);
        }

        const char *linkcmd = getenv("LINKCMD64");
        if (!linkcmd)
            linkcmd = getenv("LINKCMD"); // backward compatible
        if (!linkcmd)
        {
            if (vcinstalldir)
            {
                OutBuffer linkcmdbuf;
                linkcmdbuf.writestring(vcinstalldir);
                linkcmdbuf.writestring("bin\\amd64\\link");
                linkcmd = linkcmdbuf.extractString();
            }
            else
                linkcmd = "link";
        }
        int status = executecmd(linkcmd, p);
        if (lnkfilename)
        {
            remove(lnkfilename);
            FileName::free(lnkfilename);
        }
        return status;
    }
    else
    {
        OutBuffer cmdbuf;

        global.params.libfiles->push("user32");
        global.params.libfiles->push("kernel32");

        for (size_t i = 0; i < global.params.objfiles->dim; i++)
        {
            if (i)
                cmdbuf.writeByte('+');
            const char *p = (*global.params.objfiles)[i];
            const char *basename = FileName::removeExt(FileName::name(p));
            const char *ext = FileName::ext(p);
            if (ext && !strchr(basename, '.'))
            {
                // Write name sans extension (but not if a double extension)
                writeFilename(&cmdbuf, p, ext - p - 1);
            }
            else
                writeFilename(&cmdbuf, p);
            FileName::free(basename);
        }
        cmdbuf.writeByte(',');
        if (global.params.exefile)
            writeFilename(&cmdbuf, global.params.exefile);
        else
        {   /* Generate exe file name from first obj name.
             * No need to add it to cmdbuf because the linker will default to it.
             */
            const char *n = (*global.params.objfiles)[0];
            n = FileName::name(n);
            global.params.exefile = (char *)FileName::forceExt(n, "exe");
        }

        // Make sure path to exe file exists
        ensurePathToNameExists(Loc(), global.params.exefile);

        cmdbuf.writeByte(',');
        if (global.params.mapfile)
            writeFilename(&cmdbuf, global.params.mapfile);
        else if (global.params.map)
        {
            const char *fn = FileName::forceExt(global.params.exefile, "map");

            const char *path = FileName::path(global.params.exefile);
            const char *p;
            if (path[0] == '\0')
                p = FileName::combine(global.params.objdir, fn);
            else
                p = fn;

            writeFilename(&cmdbuf, p);
        }
        else
            cmdbuf.writestring("nul");
        cmdbuf.writeByte(',');

        for (size_t i = 0; i < global.params.libfiles->dim; i++)
        {
            if (i)
                cmdbuf.writeByte('+');
            writeFilename(&cmdbuf, (*global.params.libfiles)[i]);
        }

        if (global.params.deffile)
        {
            cmdbuf.writeByte(',');
            writeFilename(&cmdbuf, global.params.deffile);
        }

        /* Eliminate unnecessary trailing commas    */
        while (1)
        {   size_t i = cmdbuf.offset;
            if (!i || cmdbuf.data[i - 1] != ',')
                break;
            cmdbuf.offset--;
        }

        if (global.params.resfile)
        {
            cmdbuf.writestring("/RC:");
            writeFilename(&cmdbuf, global.params.resfile);
        }

        if (global.params.map || global.params.mapfile)
            cmdbuf.writestring("/m");

#if 0
        if (debuginfo)
            cmdbuf.writestring("/li");
        if (codeview)
        {
            cmdbuf.writestring("/co");
            if (codeview3)
                cmdbuf.writestring(":3");
        }
#else
        if (global.params.symdebug)
            cmdbuf.writestring("/co");
#endif

        cmdbuf.writestring("/noi");
        for (size_t i = 0; i < global.params.linkswitches->dim; i++)
        {
            cmdbuf.writestring((*global.params.linkswitches)[i]);
        }
        cmdbuf.writeByte(';');

        char *p = cmdbuf.peekString();

        const char *lnkfilename = NULL;
        size_t plen = strlen(p);
        if (plen > 7000)
        {
            lnkfilename = FileName::forceExt(global.params.exefile, "lnk");
            File flnk(lnkfilename);
            flnk.setbuffer(p, plen);
            flnk.ref = 1;
            if (flnk.write())
                error(Loc(), "error writing file %s", lnkfilename);
            if (strlen(lnkfilename) < plen)
                sprintf(p, "@%s", lnkfilename);
        }

        const char *linkcmd = getenv("LINKCMD");
        if (!linkcmd)
            linkcmd = "link";
        int status = executecmd(linkcmd, p);
        if (lnkfilename)
        {
            remove(lnkfilename);
            FileName::free(lnkfilename);
        }
        return status;
    }
#elif __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
    pid_t childpid;
    int status;

    // Build argv[]
    Strings argv;

    const char *cc = getenv("CC");
    if (!cc)
        cc = "gcc";
    argv.push(cc);
    argv.insert(1, global.params.objfiles);

#if __APPLE__
    // If we are on Mac OS X and linking a dynamic library,
    // add the "-dynamiclib" flag
    if (global.params.dll)
        argv.push("-dynamiclib");
#elif __linux__ || __FreeBSD__ || __OpenBSD__ || __sun
    if (global.params.dll)
        argv.push("-shared");
#endif

    // None of that a.out stuff. Use explicit exe file name, or
    // generate one from name of first source file.
    argv.push("-o");
    if (global.params.exefile)
    {
        argv.push(global.params.exefile);
    }
    else if (global.params.run)
    {
#if 1
        char name[L_tmpnam + 14 + 1];
        strcpy(name, P_tmpdir);
        strcat(name, "/dmd_runXXXXXX");
        int fd = mkstemp(name);
        if (fd == -1)
        {   error(Loc(), "error creating temporary file");
            return 1;
        }
        else
            close(fd);
        global.params.exefile = mem.strdup(name);
        argv.push(global.params.exefile);
#else
        /* The use of tmpnam raises the issue of "is this a security hole"?
         * The hole is that after tmpnam and before the file is opened,
         * the attacker modifies the file system to get control of the
         * file with that name. I do not know if this is an issue in
         * this context.
         * We cannot just replace it with mkstemp, because this name is
         * passed to the linker that actually opens the file and writes to it.
         */
        char s[L_tmpnam + 1];
        char *n = tmpnam(s);
        global.params.exefile = mem.strdup(n);
        argv.push(global.params.exefile);
#endif
    }
    else
    {   // Generate exe file name from first obj name
        const char *n = (*global.params.objfiles)[0];
        char *ex;

        n = FileName::name(n);
        const char *e = FileName::ext(n);
        if (e)
        {
            e--;                        // back up over '.'
            ex = (char *)mem.malloc(e - n + 1);
            memcpy(ex, n, e - n);
            ex[e - n] = 0;
            // If generating dll then force dll extension
            if (global.params.dll)
                ex = (char *)FileName::forceExt(ex, global.dll_ext);
        }
        else
            ex = (char *)"a.out";       // no extension, so give up
        argv.push(ex);
        global.params.exefile = ex;
    }

    // Make sure path to exe file exists
    ensurePathToNameExists(Loc(), global.params.exefile);

    if (global.params.symdebug)
        argv.push("-g");

    if (global.params.is64bit)
        argv.push("-m64");
    else
        argv.push("-m32");

    if (global.params.map || global.params.mapfile)
    {
        argv.push("-Xlinker");
#if __APPLE__
        argv.push("-map");
#else
        argv.push("-Map");
#endif
        if (!global.params.mapfile)
        {
            const char *fn = FileName::forceExt(global.params.exefile, "map");

            const char *path = FileName::path(global.params.exefile);
            const char *p;
            if (path[0] == '\0')
                p = FileName::combine(global.params.objdir, fn);
            else
                p = fn;

            global.params.mapfile = (char *)p;
        }
        argv.push("-Xlinker");
        argv.push(global.params.mapfile);
    }

    if (0 && global.params.exefile)
    {
        /* This switch enables what is known as 'smart linking'
         * in the Windows world, where unreferenced sections
         * are removed from the executable. It eliminates unreferenced
         * functions, essentially making a 'library' out of a module.
         * Although it is documented to work with ld version 2.13,
         * in practice it does not, but just seems to be ignored.
         * Thomas Kuehne has verified that it works with ld 2.16.1.
         * BUG: disabled because it causes exception handling to fail
         * because EH sections are "unreferenced" and elided
         */
        argv.push("-Xlinker");
        argv.push("--gc-sections");
    }

    for (size_t i = 0; i < global.params.linkswitches->dim; i++)
    {   const char *p = (*global.params.linkswitches)[i];
        if (!p || !p[0] || !(p[0] == '-' && (p[1] == 'l' || p[1] == 'L')))
            // Don't need -Xlinker if switch starts with -l or -L.
            // Eliding -Xlinker is significant for -L since it allows our paths
            // to take precedence over gcc defaults.
            argv.push("-Xlinker");
        argv.push(p);
    }

    /* Add each library, prefixing it with "-l".
     * The order of libraries passed is:
     *  1. any libraries passed with -L command line switch
     *  2. libraries specified on the command line
     *  3. libraries specified by pragma(lib), which were appended
     *     to global.params.libfiles.
     *  4. standard libraries.
     */
    for (size_t i = 0; i < global.params.libfiles->dim; i++)
    {   const char *p = (*global.params.libfiles)[i];
        size_t plen = strlen(p);
        if (plen > 2 && p[plen - 2] == '.' && p[plen -1] == 'a')
            argv.push(p);
        else
        {
            char *s = (char *)mem.malloc(plen + 3);
            s[0] = '-';
            s[1] = 'l';
            memcpy(s + 2, p, plen + 1);
            argv.push(s);
        }
    }

    for (size_t i = 0; i < global.params.dllfiles->dim; i++)
    {
        const char *p = (*global.params.dllfiles)[i];
        argv.push(p);
    }

    /* Standard libraries must go after user specified libraries
     * passed with -l.
     */
    const char *libname = (global.params.symdebug)
                                ? global.params.debuglibname
                                : global.params.defaultlibname;
    size_t slen = strlen(libname);
    if (slen)
    {
        char *buf = (char *)malloc(3 + slen + 1);
        strcpy(buf, "-l");
        /* Use "-l:libname.a" if the library name is complete
         */
        if (slen > 3 + 2 &&
            memcmp(libname, "lib", 3) == 0 &&
            (memcmp(libname + slen - 2, ".a", 2) == 0 ||
             memcmp(libname + slen - 3, ".so", 3) == 0)
           )
        {
            strcat(buf, ":");
        }
        strcat(buf, libname);
        argv.push(buf);             // turns into /usr/lib/libphobos2.a
    }

#ifdef __sun
    argv.push("-mt");
#endif

//    argv.push("-ldruntime");
    argv.push("-lpthread");
    argv.push("-lm");
#if __linux__
    // Changes in ld for Ubuntu 11.10 require this to appear after phobos2
    argv.push("-lrt");
#endif

    if (global.params.verbose)
    {
        // Print it
        for (size_t i = 0; i < argv.dim; i++)
            fprintf(global.stdmsg, "%s ", argv[i]);
        fprintf(global.stdmsg, "\n");
    }

    argv.push(NULL);

    // set up pipes
    int fds[2];

    if (pipe(fds) == -1)
    {
        perror("Unable to create pipe to linker");
        return -1;
    }

    childpid = fork();
    if (childpid == 0)
    {
        // pipe linker stderr to fds[0]
        dup2(fds[1], STDERR_FILENO);
        close(fds[0]);

        execvp(argv[0], (char **)argv.tdata());
        perror(argv[0]);           // failed to execute
        return -1;
    }
    else if (childpid == -1)
    {
        perror("Unable to fork");
        return -1;
    }
    close(fds[1]);
    const int nme = findNoMainError(fds[0]);
    waitpid(childpid, &status, 0);

    if (WIFEXITED(status))
    {
        status = WEXITSTATUS(status);
        if (status)
        {
            if (nme == -1)
            {
                perror("Error with the linker pipe");
                return -1;
            }
            else
            {
                printf("--- errorlevel %d\n", status);
                if (nme == 1) error(Loc(), "no main function specified");
            }
        }
    }
    else if (WIFSIGNALED(status))
    {
        printf("--- killed by signal %d\n", WTERMSIG(status));
        status = 1;
    }
    return status;
#else
    printf ("Linking is not yet supported for this version of DMD.\n");
    return -1;
#endif
}
Ejemplo n.º 17
0
int main (void) {
   char *backp;
   sigset_t blockmask;
   pid_t childpid;
   struct sigaction defhandler;
   int inbackground;
   int len;
   char inbuf[MAX_CANON];

   if (signalsetup(&defhandler, &blockmask, jumphd) == -1) {
      perror("Failed to set up shell signal handling");
      return 1;
   }

   for( ; ; ) {
      if ((sigsetjmp(jumptoprompt, 1)) &&   /* if return from signal, \n */
          (fputs("\n", stdout) == EOF) )
         continue;
      okaytojump = 1;
      printf("%d",(int)getpid());
      if (fputs(PROMPT_STRING, stdout) == EOF)
          continue;
      if (fgets(inbuf, MAX_CANON, stdin) == NULL)
          continue;
      len = strlen(inbuf);
      if (inbuf[len - 1] == '\n')
          inbuf[len - 1] = 0;
      if (strcmp(inbuf, QUIT_STRING) == 0)
          break;
      if ((backp = strchr(inbuf, BACK_SYMBOL)) == NULL)
          inbackground = 0;
      else {
         inbackground = 1; 
         *backp = 0;
      }
      if (sigprocmask(SIG_BLOCK, &blockmask, NULL) == -1)
         perror("Failed to block signals");
      if ((childpid = fork()) == -1)
          perror("Failed to fork");
      else if (childpid == 0) {
         if (inbackground) {             /* child creates another process */
             if ((childpid = fork()) == -1) {
                perror("Second fork failed"); 
                return 1;
             }
             if (childpid > 0)
                return 0;
             if (setpgid(0, 0) == -1) {
                perror("setpgod failed");
                return 1;
             }
         }
         if ((sigaction(SIGINT, &defhandler, NULL) < 0) ||
             (sigaction(SIGQUIT, &defhandler, NULL) < 0) || 
             (sigprocmask(SIG_UNBLOCK, &blockmask, NULL) == -1)) {
             perror("Failed to set signal handling for command "); 
             return 1; 
         }
         executecmd(inbuf);
         perror("Failed to execute command");
         return 1;
      }
      if (sigprocmask(SIG_UNBLOCK, &blockmask, NULL) == -1)
         perror("Failed to unblock signals");
      wait(NULL);
   }
   return 0;
}
Ejemplo n.º 18
0
Archivo: link.c Proyecto: shoo/dmd
int runLINK()
{
#if _WIN32
    if (global.params.is64bit)
    {
        OutBuffer cmdbuf;

        for (size_t i = 0; i < global.params.objfiles->dim; i++)
        {
            if (i)
                cmdbuf.writeByte(' ');
            char *p = (*global.params.objfiles)[i];
            char *basename = FileName::removeExt(FileName::name(p));
            char *ext = FileName::ext(p);
            if (ext && !strchr(basename, '.'))
                // Write name sans extension (but not if a double extension)
                writeFilename(&cmdbuf, p, ext - p - 1);
            else
                writeFilename(&cmdbuf, p);
            mem.free(basename);
        }

        if (global.params.resfile)
        {
            cmdbuf.writeByte(' ');
            writeFilename(&cmdbuf, global.params.resfile);
        }

        cmdbuf.writeByte(' ');
        if (global.params.exefile)
        {   cmdbuf.writestring("/OUT:");
            writeFilename(&cmdbuf, global.params.exefile);
        }
        else
        {   /* Generate exe file name from first obj name.
             * No need to add it to cmdbuf because the linker will default to it.
             */
            char *n = (*global.params.objfiles)[0];
            n = FileName::name(n);
            FileName *fn = FileName::forceExt(n, "exe");
            global.params.exefile = fn->toChars();
        }

        // Make sure path to exe file exists
        {   char *p = FileName::path(global.params.exefile);
            FileName::ensurePathExists(p);
            mem.free(p);
        }

        cmdbuf.writeByte(' ');
        if (global.params.mapfile)
        {   cmdbuf.writestring("/MAP:");
            writeFilename(&cmdbuf, global.params.mapfile);
        }
        else if (global.params.map)
        {
            FileName *fn = FileName::forceExt(global.params.exefile, "map");

            char *path = FileName::path(global.params.exefile);
            char *p;
            if (path[0] == '\0')
                p = FileName::combine(global.params.objdir, fn->toChars());
            else
                p = fn->toChars();

            cmdbuf.writestring("/MAP:");
            writeFilename(&cmdbuf, p);
        }

        for (size_t i = 0; i < global.params.libfiles->dim; i++)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DEFAULTLIB:");
            writeFilename(&cmdbuf, (*global.params.libfiles)[i]);
        }

        if (global.params.deffile)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DEF:");
            writeFilename(&cmdbuf, global.params.deffile);
        }

        if (global.params.symdebug)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DEBUG");
        }

        if (global.params.dll)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring("/DLL");
        }

        cmdbuf.writestring(" /MERGE:.minfobg=.minfodt /MERGE:.minfoen=.minfodt");
        cmdbuf.writestring(" /MERGE:._deh_bg=._deh_eh /MERGE:._deh_en=._deh_eh");

        for (size_t i = 0; i < global.params.linkswitches->dim; i++)
        {
            cmdbuf.writeByte(' ');
            cmdbuf.writestring((*global.params.linkswitches)[i]);
        }

        /* Append the path to the VC lib files, and then the SDK lib files
         */
        const char *vcinstalldir = getenv("VCINSTALLDIR");
        if (vcinstalldir)
        {   cmdbuf.writestring(" \"/LIBPATH:");
            cmdbuf.writestring(vcinstalldir);
            cmdbuf.writestring("lib\\amd64\"");
        }

        const char *windowssdkdir = getenv("WindowsSdkDir");
        if (windowssdkdir)
        {   cmdbuf.writestring(" \"/LIBPATH:");
            cmdbuf.writestring(windowssdkdir);
            cmdbuf.writestring("lib\\x64\"");
        }

        char *p = cmdbuf.toChars();

        FileName *lnkfilename = NULL;
        size_t plen = strlen(p);
        if (plen > 7000)
        {
            lnkfilename = FileName::forceExt(global.params.exefile, "lnk");
            File flnk(lnkfilename);
            flnk.setbuffer(p, plen);
            flnk.ref = 1;
            if (flnk.write())
                error(0, "error writing file %s", lnkfilename);
            if (lnkfilename->len() < plen)
                sprintf(p, "@%s", lnkfilename->toChars());
        }

        char *linkcmd = getenv("LINKCMD");
        if (!linkcmd)
        {
            if (vcinstalldir)
            {
                OutBuffer linkcmdbuf;
                linkcmdbuf.writestring(vcinstalldir);
                linkcmdbuf.writestring("bin\\amd64\\link");
                linkcmd = linkcmdbuf.toChars();
                linkcmdbuf.extractData();
            }
            else
                linkcmd = "link";
        }
        int status = executecmd(linkcmd, p, 1);
        if (lnkfilename)
        {
            remove(lnkfilename->toChars());
            delete lnkfilename;
        }
        return status;
    }
    else
    {
        OutBuffer cmdbuf;

        global.params.libfiles->push("user32");
        global.params.libfiles->push("kernel32");

        for (size_t i = 0; i < global.params.objfiles->dim; i++)
        {
            if (i)
                cmdbuf.writeByte('+');
            char *p = (*global.params.objfiles)[i];
            char *basename = FileName::removeExt(FileName::name(p));
            char *ext = FileName::ext(p);
            if (ext && !strchr(basename, '.'))
                // Write name sans extension (but not if a double extension)
                writeFilename(&cmdbuf, p, ext - p - 1);
            else
                writeFilename(&cmdbuf, p);
            mem.free(basename);
        }
        cmdbuf.writeByte(',');
        if (global.params.exefile)
            writeFilename(&cmdbuf, global.params.exefile);
        else
        {   /* Generate exe file name from first obj name.
             * No need to add it to cmdbuf because the linker will default to it.
             */
            char *n = (*global.params.objfiles)[0];
            n = FileName::name(n);
            FileName *fn = FileName::forceExt(n, "exe");
            global.params.exefile = fn->toChars();
        }

        // Make sure path to exe file exists
        {   char *p = FileName::path(global.params.exefile);
            FileName::ensurePathExists(p);
            mem.free(p);
        }

        cmdbuf.writeByte(',');
        if (global.params.mapfile)
            writeFilename(&cmdbuf, global.params.mapfile);
        else if (global.params.map)
        {
            FileName *fn = FileName::forceExt(global.params.exefile, "map");

            char *path = FileName::path(global.params.exefile);
            char *p;
            if (path[0] == '\0')
                p = FileName::combine(global.params.objdir, fn->toChars());
            else
                p = fn->toChars();

            writeFilename(&cmdbuf, p);
        }
        else
            cmdbuf.writestring("nul");
        cmdbuf.writeByte(',');

        for (size_t i = 0; i < global.params.libfiles->dim; i++)
        {
            if (i)
                cmdbuf.writeByte('+');
            writeFilename(&cmdbuf, (*global.params.libfiles)[i]);
        }

        if (global.params.deffile)
        {
            cmdbuf.writeByte(',');
            writeFilename(&cmdbuf, global.params.deffile);
        }

        /* Eliminate unnecessary trailing commas    */
        while (1)
        {   size_t i = cmdbuf.offset;
            if (!i || cmdbuf.data[i - 1] != ',')
                break;
            cmdbuf.offset--;
        }

        if (global.params.resfile)
        {
            cmdbuf.writestring("/RC:");
            writeFilename(&cmdbuf, global.params.resfile);
        }

        if (global.params.map || global.params.mapfile)
            cmdbuf.writestring("/m");

#if 0
        if (debuginfo)
            cmdbuf.writestring("/li");
        if (codeview)
        {
            cmdbuf.writestring("/co");
            if (codeview3)
                cmdbuf.writestring(":3");
        }
#else
        if (global.params.symdebug)
            cmdbuf.writestring("/co");
#endif

        cmdbuf.writestring("/noi");
        for (size_t i = 0; i < global.params.linkswitches->dim; i++)
        {
            cmdbuf.writestring((*global.params.linkswitches)[i]);
        }
        cmdbuf.writeByte(';');

        char *p = cmdbuf.toChars();

        FileName *lnkfilename = NULL;
        size_t plen = strlen(p);
        if (plen > 7000)
        {
            lnkfilename = FileName::forceExt(global.params.exefile, "lnk");
            File flnk(lnkfilename);
            flnk.setbuffer(p, plen);
            flnk.ref = 1;
            if (flnk.write())
                error(0, "error writing file %s", lnkfilename);
            if (lnkfilename->len() < plen)
                sprintf(p, "@%s", lnkfilename->toChars());
        }

        char *linkcmd = getenv("LINKCMD");
        if (!linkcmd)
            linkcmd = "link";
        int status = executecmd(linkcmd, p, 1);
        if (lnkfilename)
        {
            remove(lnkfilename->toChars());
            delete lnkfilename;
        }
        return status;
    }
#elif linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
    pid_t childpid;
    int status;

    // Build argv[]
    Strings argv;

    const char *cc = getenv("CC");
    if (!cc)
        cc = "gcc";
    argv.push((char *)cc);
    argv.insert(1, global.params.objfiles);

#if __APPLE__
    // If we are on Mac OS X and linking a dynamic library,
    // add the "-dynamiclib" flag
    if (global.params.dll)
        argv.push((char *) "-dynamiclib");
#elif linux || __FreeBSD__ || __OpenBSD__ || __sun
    if (global.params.dll)
        argv.push((char *) "-shared");
#endif

    // None of that a.out stuff. Use explicit exe file name, or
    // generate one from name of first source file.
    argv.push((char *)"-o");
    if (global.params.exefile)
    {
        if (global.params.dll)
            global.params.exefile = FileName::forceExt(global.params.exefile, global.dll_ext)->toChars();
        argv.push(global.params.exefile);
    }
    else
    {   // Generate exe file name from first obj name
        char *n = (*global.params.objfiles)[0];
        char *e;
        char *ex;

        n = FileName::name(n);
        e = FileName::ext(n);
        if (e)
        {
            e--;                        // back up over '.'
            ex = (char *)mem.malloc(e - n + 1);
            memcpy(ex, n, e - n);
            ex[e - n] = 0;
            // If generating dll then force dll extension
            if (global.params.dll)
                ex = FileName::forceExt(ex, global.dll_ext)->toChars();
        }
        else
            ex = (char *)"a.out";       // no extension, so give up
        argv.push(ex);
        global.params.exefile = ex;
    }

    // Make sure path to exe file exists
    {   char *p = FileName::path(global.params.exefile);
        FileName::ensurePathExists(p);
        mem.free(p);
    }

    if (global.params.symdebug)
        argv.push((char *)"-g");

    if (global.params.is64bit)
        argv.push((char *)"-m64");
    else
        argv.push((char *)"-m32");

    if (global.params.map || global.params.mapfile)
    {
        argv.push((char *)"-Xlinker");
#if __APPLE__
        argv.push((char *)"-map");
#else
        argv.push((char *)"-Map");
#endif
        if (!global.params.mapfile)
        {
            FileName *fn = FileName::forceExt(global.params.exefile, "map");

            char *path = FileName::path(global.params.exefile);
            char *p;
            if (path[0] == '\0')
                p = FileName::combine(global.params.objdir, fn->toChars());
            else
                p = fn->toChars();

            global.params.mapfile = p;
        }
        argv.push((char *)"-Xlinker");
        argv.push(global.params.mapfile);
    }

    if (0 && global.params.exefile)
    {
        /* This switch enables what is known as 'smart linking'
         * in the Windows world, where unreferenced sections
         * are removed from the executable. It eliminates unreferenced
         * functions, essentially making a 'library' out of a module.
         * Although it is documented to work with ld version 2.13,
         * in practice it does not, but just seems to be ignored.
         * Thomas Kuehne has verified that it works with ld 2.16.1.
         * BUG: disabled because it causes exception handling to fail
         * because EH sections are "unreferenced" and elided
         */
        argv.push((char *)"-Xlinker");
        argv.push((char *)"--gc-sections");
    }

    for (size_t i = 0; i < global.params.linkswitches->dim; i++)
    {   char *p = (*global.params.linkswitches)[i];
        if (!p || !p[0] || !(p[0] == '-' && (p[1] == 'l' || p[1] == 'L')))
            // Don't need -Xlinker if switch starts with -l or -L.
            // Eliding -Xlinker is significant for -L since it allows our paths
            // to take precedence over gcc defaults.
            argv.push((char *)"-Xlinker");
        argv.push(p);
    }

    /* Add each library, prefixing it with "-l".
     * The order of libraries passed is:
     *  1. any libraries passed with -L command line switch
     *  2. libraries specified on the command line
     *  3. libraries specified by pragma(lib), which were appended
     *     to global.params.libfiles.
     *  4. standard libraries.
     */
    for (size_t i = 0; i < global.params.libfiles->dim; i++)
    {   char *p = (*global.params.libfiles)[i];
        size_t plen = strlen(p);
        if (plen > 2 && p[plen - 2] == '.' && p[plen -1] == 'a')
            argv.push(p);
        else
        {
            char *s = (char *)mem.malloc(plen + 3);
            s[0] = '-';
            s[1] = 'l';
            memcpy(s + 2, p, plen + 1);
            argv.push(s);
        }
    }

    /* Standard libraries must go after user specified libraries
     * passed with -l.
     */
    const char *libname = (global.params.symdebug)
                                ? global.params.debuglibname
                                : global.params.defaultlibname;
    size_t slen = strlen(libname);
    if (slen)
    {
        char *buf = (char *)malloc(2 + slen + 1);
        strcpy(buf, "-l");
        strcpy(buf + 2, libname);
        argv.push(buf);             // turns into /usr/lib/libphobos2.a
    }

#ifdef __sun
    argv.push((char *)"-mt");
#endif

//    argv.push((void *)"-ldruntime");
    argv.push((char *)"-lpthread");
    argv.push((char *)"-lm");
#if linux && DMDV2
    // Changes in ld for Ubuntu 11.10 require this to appear after phobos2
    argv.push((char *)"-lrt");
#endif

    if (!global.params.quiet || global.params.verbose)
    {
        // Print it
        for (size_t i = 0; i < argv.dim; i++)
            printf("%s ", argv[i]);
        printf("\n");
        fflush(stdout);
    }

    argv.push(NULL);
#if HAS_POSIX_SPAWN
    int spawn_err = posix_spawnp(&childpid, argv[0], NULL, NULL, argv.tdata(), environ);
    if (spawn_err != 0)
    {
        perror(argv[0]);
        return -1;
    }
#else
    childpid = fork();
    if (childpid == 0)
    {
        execvp(argv[0], argv.tdata());
        perror(argv[0]);           // failed to execute
        return -1;
    }
    else if (childpid == -1)
    {
        perror("Unable to fork");
        return -1;
    }
#endif

    waitpid(childpid, &status, 0);

    if (WIFEXITED(status))
    {
        status = WEXITSTATUS(status);
        if (status)
            printf("--- errorlevel %d\n", status);
    }
    else if (WIFSIGNALED(status))
    {
        printf("--- killed by signal %d\n", WTERMSIG(status));
        status = 1;
    }
    return status;
#else
    printf ("Linking is not yet supported for this version of DMD.\n");
    return -1;
#endif
}
Ejemplo n.º 19
0
int runLINK()
{
#if _WIN32
    char *p;
    int i;
    int status;
    OutBuffer cmdbuf;

    global.params.libfiles->push((void *) "user32");
    global.params.libfiles->push((void *) "kernel32");

    for (i = 0; i < global.params.objfiles->dim; i++)
    {
	if (i)
	    cmdbuf.writeByte('+');
	p = (char *)global.params.objfiles->data[i];
	char *ext = FileName::ext(p);
	if (ext)
	    cmdbuf.write(p, ext - p - 1);
	else
	    cmdbuf.writestring(p);
    }
    cmdbuf.writeByte(',');
    if (global.params.exefile)
	cmdbuf.writestring(global.params.exefile);
    else
    {	// Generate exe file name from first obj name
	char *n = (char *)global.params.objfiles->data[0];
	char *ex;

	n = FileName::name(n);
	FileName *fn = FileName::forceExt(n, "exe");
	global.params.exefile = fn->toChars();
    }

    cmdbuf.writeByte(',');
    if (global.params.run)
	cmdbuf.writestring("nul");
//    if (mapfile)
//	cmdbuf.writestring(output);
    cmdbuf.writeByte(',');

    for (i = 0; i < global.params.libfiles->dim; i++)
    {
	if (i)
	    cmdbuf.writeByte('+');
	cmdbuf.writestring((char *) global.params.libfiles->data[i]);
    }

    if (global.params.deffile)
    {
	cmdbuf.writeByte(',');
	cmdbuf.writestring(global.params.deffile);
    }

    /* Eliminate unnecessary trailing commas	*/
    while (1)
    {   i = cmdbuf.offset;
	if (!i || cmdbuf.data[i - 1] != ',')
	    break;
	cmdbuf.offset--;
    }

    if (global.params.resfile)
    {
	cmdbuf.writestring("/RC:");
	cmdbuf.writestring(global.params.resfile);
    }

#if 0
    if (mapfile)
	cmdbuf.writestring("/m");
    if (debuginfo)
	cmdbuf.writestring("/li");
    if (codeview)
    {
	cmdbuf.writestring("/co");
	if (codeview3)
	    cmdbuf.writestring(":3");
    }
#else
    if (global.params.symdebug)
	cmdbuf.writestring("/co");
#endif

    cmdbuf.writestring("/noi");
    for (i = 0; i < global.params.linkswitches->dim; i++)
    {
	cmdbuf.writestring((char *) global.params.linkswitches->data[i]);
    }
    cmdbuf.writeByte(';');

    p = cmdbuf.toChars();

    char *linkcmd = getenv("LINKCMD");
    if (!linkcmd)
	linkcmd = "link";
    status = executecmd(linkcmd, p, 1);
    return status;
#elif linux
    pid_t childpid;
    int i;
    int status;

    // Build argv[]
    Array argv;

    char *cc = getenv("CC");
    if (!cc)
	cc = "gcc";
    argv.push((void *)cc);
    argv.insert(1, global.params.objfiles);

    // None of that a.out stuff. Use explicit exe file name, or
    // generate one from name of first source file.
    argv.push((void *)"-o");
    if (global.params.exefile)
    {
	argv.push(global.params.exefile);
    }
    else
    {	// Generate exe file name from first obj name
	char *n = (char *)global.params.objfiles->data[0];
	char *e;
	char *ex;

	n = FileName::name(n);
	e = FileName::ext(n);
	if (e)
	{
	    e--;			// back up over '.'
	    ex = (char *)mem.malloc(e - n + 1);
	    memcpy(ex, n, e - n);
	    ex[e - n] = 0;
	}
	else
	    ex = (char *)"a.out";	// no extension, so give up
	argv.push(ex);
	global.params.exefile = ex;
    }

    argv.insert(argv.dim, global.params.libfiles);

    if (global.params.symdebug)
	argv.push((void *)"-g");

    argv.push((void *)"-m32");

    argv.push((void *)"-lphobos");	// turns into /usr/lib/libphobos.a
    argv.push((void *)"-lpthread");
    argv.push((void *)"-lm");

    if (0 && global.params.exefile)
    {
	/* This switch enables what is known as 'smart linking'
	 * in the Windows world, where unreferenced sections
	 * are removed from the executable. It eliminates unreferenced
	 * functions, essentially making a 'library' out of a module.
	 * Although it is documented to work with ld version 2.13,
	 * in practice it does not, but just seems to be ignored.
	 * Thomas Kuehne has verified that it works with ld 2.16.1.
	 * BUG: disabled because it causes exception handling to fail
	 */
	argv.push((void *)"-Xlinker");
	argv.push((void *)"--gc-sections");
    }

    for (i = 0; i < global.params.linkswitches->dim; i++)
    {
	argv.push((void *)"-Xlinker");
	argv.push((void *) global.params.linkswitches->data[i]);
    }

    if (!global.params.quiet)
    {
	// Print it
	for (i = 0; i < argv.dim; i++)
	    printf("%s ", (char *)argv.data[i]);
	printf("\n");
	fflush(stdout);
    }

    argv.push(NULL);
    childpid = fork();
    if (childpid == 0)
    {
	execvp((char *)argv.data[0], (char **)argv.data);
	perror((char *)argv.data[0]);		// failed to execute
	return -1;
    }

    waitpid(childpid, &status, 0);

    status=WEXITSTATUS(status);
    if (status)
	printf("--- errorlevel %d\n", status);
    return status;
#else
    printf ("Linking is not yet supported for this version of DMD.\n");
    return -1;
#endif
}