系统调用阅读行为怪异

时间:2014-11-07 20:27:46

标签: c sys

c lang,ubuntu 所以我有一个任务 - 用这3个选项写一个菜单: 关闭计划 2.显示用户ID 3.显示当前工作目录

我只能使用3个库 - unistd.h,sys / syscall.h,sys / sysinfo.h。 所以没有printf / scanf 我需要使用一个给定的结构数组,它有一个函数指针, 调用用户想要使用的函数。

问题出在选项2& 3; 当我选择2,第一次它工作正常(我认为) 我第二次选择2,它可以工作,但是当进入第三次迭代时, 它不等待输入,由于某种原因它将'\ n'作为输入,然后它表示无效输入。 (我检查了printf输入的内容,重新计算后打印索引,因为-39,所以这意味着选择[0] = 10 ='\ n')

这是第一个问题,我无法找到解决方案。

第二个问题是当前的工作目录功能; 由于某种原因,SYS_getcwd返回-1,这意味着有一个错误,但我无法弄明白。

对这些事情的任何解释?

(也 - slen和__itoa是我给出的函数 - slen返回字符串的长度, __itoa返回一个char *,它是整数的字符串表示形式

helper.h:

typedef struct func_desc {
char *name;
void (*func)(void); 
} fun_desc;

main.c中:

#include <unistd.h>
#include "helper.h"
#include <sys/syscall.h>
#include <sys/sysinfo.h>

void exitProgram();
void printID();
void currDir();

int main() {
    fun_desc arrFuncs[3];
    arrFuncs[0].name = "exitProgram";
    arrFuncs[0].func = &exitProgram;
    arrFuncs[1].name = "printID";
    arrFuncs[1].func = &printID;
    arrFuncs[2].name = "currDir";
    arrFuncs[2].func = &currDir;
    char selection[2];
    int index;
    const char* menu = "Welcome to the menu. Please pick one of the following actions:\n1.Close the program\n2.Print the current user's id\n3.Print the current directory's id\n";

    while(1 == 1) {
        syscall(SYS_write, 0, menu, slen(menu));
        syscall(SYS_write, 0, "Your selection: ", slen("Your selection: "));
        syscall(SYS_read, 1, selection, slen(selection));       //might be a problem
        selection[1] = '\0';
        index = selection[0] - '0' - 1;

        if(index > 2)
                syscall(SYS_write, 0, "Invalid input\n", slen("Invalid input\n"));
        else 
            arrFuncs[index].func();
    }
    return(0);
}


void exitProgram() {
    syscall(SYS_write, 0, "The program will close\n", slen("The program will close\n"));
    syscall(SYS_exit);
}

void printID() {        //problem
    char* uid = __itoa(syscall(SYS_getuid));
    syscall(SYS_write, 0, uid, slen(uid));
    syscall(SYS_write, 0, "\n", slen("\n"));
}

void currDir() {        //????  
    char* buf = __itoa(syscall(SYS_getcwd));
    syscall(SYS_write, 0, buf, slen(buf));
    syscall(SYS_write, 0, "\n", slen("\n"));
}

1 个答案:

答案 0 :(得分:1)

您将错误数量的参数传递给其中一些系统调用。特别是:


syscall(SYS_exit);

_exit()接受一个参数:退出代码。


char* buf = __itoa(syscall(SYS_getcwd));

getcwd()有两个参数:指向要写入字符串的缓冲区的指针,以及该缓冲区的长度。在实践中,这可能看起来像:

char pathbuf[PATH_MAX];
syscall(SYS_getcwd, pathbuf, sizeof(pathbuf));

如果您没有定义PATH_MAX的标头,请自行定义。 4096是一个合适的值。

请注意getcwd()将字符串写入传递给它的缓冲区 - 它不会返回数字标识符。


顺便说一下,你可能希望通过实现一个包装来写一个字符串来节省一些时间,例如

void putstring(const char *str) {
    syscall(SYS_write, 0, str, slen(str));
}

因为你似乎做了很多。