【问题标题】:Segmentation fault when using tm struck in C在 C 中使用 tm 时出现分段错误
【发布时间】:2013-04-03 00:33:38
【问题描述】:

所以我在下面发布了我的代码(抱歉,我知道它很长),但是当我尝试使用 tm 结构执行任何操作时出现分段错误。我不知道为什么会出现此段错误,我很确定我以前可以正常工作,但是现在我无法正常工作。如果有人知道如何摆脱段错误,那就太好了。段错误出现在第一个嵌套的 if 语句中,位于代码块的中下部,位于 if-else 的长块之后。

非常感谢!

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <assert.h>


int main(){

int sockfd, clifd, status, monthModifiedi, newer;
struct sockaddr_in addr;
//char buf[1024] = "HEAD httpserver.c HTTP/1.1\nHost: www.reddit.com";
char buf[1024];
struct stat statBuf;
char *message, *filePath, *domain, *monthModified, *dayModified, *hourModified, *minuteModified, *secondModified, *yearModified;
FILE *pFile;
struct tm *tm;
time_t time;

//instantiate
strcpy(buf,"HEAD /httpserver.c HTTP/1.1\nHost: www.reddit.com\nIf-Modified-Since: Thu Mar 28 02:20:08 2013");

printf("%s\n\n", buf);

//parse buffer
message = strtok(buf, " ");
filePath = strtok(NULL, " ");
domain = strtok(NULL, "\n");
domain = strtok(NULL, " "); //domain will be overwritten with actual doman, this is filler
domain = strtok(NULL, " \n");
monthModified = strtok(NULL, " ");

printf("%s\n", filePath);
if(stat(filePath, &statBuf) == 0){
    tm = localtime(&statBuf.st_mtime);
    //time = &statBuf.st_mtime;
}

//newer will keep this value of 2 if there is no conditional GET request
newer = 2;

//If it is a conditional GET request
if(strcmp(monthModified, "If-Modified-Since:") == 0){

    monthModified = strtok(NULL, " ");
    monthModified = strtok(NULL, " ");
  dayModified = strtok(NULL, " ");
  hourModified = strtok(NULL, " :");
  minuteModified = strtok(NULL,":");
  secondModified = strtok(NULL,": ");
  yearModified = strtok(NULL, " ");

    //Turns string version of month to numeric value
    if(strcmp(monthModified,"Jan") ==0)
        monthModifiedi = 1;
    else if(strcmp(monthModified,"Feb")==0)
        monthModifiedi = 2;
    else if(strcmp(monthModified,"Mar") ==0)
        monthModifiedi = 3;
    else if(strcmp(monthModified,"Apr") ==0)
        monthModifiedi = 4;
    else if(strcmp(monthModified,"May") ==0)
        monthModifiedi = 5;
    else if(strcmp(monthModified,"Jun") ==0)
        monthModifiedi = 6;
    else if(strcmp(monthModified,"Jul") ==0)
        monthModifiedi = 7;
    else if(strcmp(monthModified,"Aug") ==0)
        monthModifiedi = 8;
    else if(strcmp(monthModified, "Sep") ==0)
        monthModifiedi = 9;
    else if(strcmp(monthModified,"Oct") ==0)
        monthModifiedi = 10;
    else if(strcmp(monthModified, "Nov") ==0)
        monthModifiedi = 11;
    else if(strcmp(monthModified,"Dec") ==0)
        monthModifiedi = 12;

    //Determines if file has been modified since date requested from client
    newer = 0;
    if(atoi(yearModified) > (*tm).tm_year)
        if(monthModifiedi > (*tm).tm_mon)
            if(atoi(dayModified) > (*tm).tm_mday)
                if(atoi(hourModified) > (*tm).tm_hour)
                    if(atoi(minuteModified) > (*tm).tm_min)
                        if(atoi(secondModified) > (*tm).tm_sec)
                            newer = 1;
}

printf("Value of newer: %i", newer);
printf("Message: %s Filename: %s Domain: %s monthModified: %i dayModified: %s hourModified: %s minuteModified: %s secondModified: %s yearModified: %s\n", message, filePath, domain, monthModifiedi, dayModified, hourModified, minuteModified, secondModified, yearModified);

if(message == "GET"){
    if ((pFile = fopen(filePath, "w")) == NULL){
        message = "HTTP/1.1 404 Not Found\n\r";
        send(clifd, message, strlen(message), 0);
    }
    // If not conditinal request, or if file has been modified
    else if(newer == 2 || newer == 1){
        message = "HTTP/1.1 200 OK\n\r", pFile;
        send(clifd, message, strlen(message), 0);
    }
    // If file has not been modified
    else{
        message = "HTTP/1.1 304 Not Modified\n\r";
        send(clifd, message, strlen(message),0);
    }
}
else if(message == "HEAD"){
    if ((pFile = fopen(filePath, "w")) == NULL){
        message = "HTTP/1.1 404 Not Found\n\r";
        send(clifd, message, strlen(message), 0);
    }
    else{
        message = "HTTP/1.1 200 OK\n\r";
        send(clifd, message, strlen(message), 0);
    }
}

return 0;
}

【问题讨论】:

    标签: c struct segmentation-fault time-t tm


    【解决方案1】:

    stat的返回值是多少?

    if(stat(filePath, &statBuf) == 0){
        tm = localtime(&statBuf.st_mtime);
        //time = &statBuf.st_mtime;
    }
    

    只有在stat 成功时才初始化tm,但如果不是,则无论如何都无需检查即可访问它。

    【讨论】:

      【解决方案2】:

      问题不在于tm 本身,而在于filePath。您很可能在根目录中没有名为/httpserver.c 的文件。这会导致赋值

      tm = localtime(&statBuf.st_mtime);
      

      被跳过,tm 指向任意内存。

      从字符串中,我猜这应该是一个 HTTP HEAD 请求。要测试正确的文件,您必须将文档根添加到请求的 URI 的名称前。

      【讨论】:

      • 如果找不到文件,您可以(显然)通过采取适当的措施来防止这种情况发生,也可以在声明时将 tm 初始化为 NULL。这样一来,您至少可以在失败的情况下获得可预测的结果。
      • 但我愿意。如果我删除前导斜杠,那么它将在此代码所在的同一目录中查找,对吗?我删除了斜杠,目录中有一个文件 httpserver.c 。还是什么都没有
      • @Skytbest 当您删除前导斜杠时,stat 会查看进程的当前目录,而不是源目录。您可以在if 分支中放置一条调试打印语句,以查看它是执行分配还是跳过它。
      猜你喜欢
      • 2021-06-13
      • 2016-09-15
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 2020-05-29
      • 1970-01-01
      相关资源
      最近更新 更多